The calls
POST /v1/uploads, thenPUT /v1/uploads/{id}/contentPOST /v1/jobs/music-separationDuplex Conversation SeparationPOST /v1/jobs/separationMulti Mic SeparationPOST /v1/jobs/multi-mic-separationGET /v1/jobs/{id}GET /v1/jobs/{id}/stems/{name}
The program
set -euo pipefail
# Export DUETA_API_KEY once in your shell (Authenticate). This reads it.
: "${DUETA_API_KEY:?export DUETA_API_KEY first}"
BASE="https://dueta.ai"
AUTH="Authorization: Bearer $DUETA_API_KEY"
# 1. Declare the recording, then send its bytes.
SIZE=$(wc -c < song.wav)
UPLOAD=$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/ json" \
-d "{\"filename\": \"song.wav\", \"size_bytes\": $SIZE}" \
"$BASE/ v1/ uploads")
UPLOAD_ID=$(echo "$UPLOAD" | jq -er .id) || { echo "$UPLOAD"; exit 1; }
curl -fsS -X PUT -H "$AUTH" -H "Content-Type: application/ octet-stream" \
--data-binary @song.wav "$BASE/ v1/ uploads/ $UPLOAD_ID/ content" |
jq -e '.state == "ready"' # stops here unless the bytes landed
# 2. Create the job.
JOB=$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/ json" \
-d "{\"inputs\": [\"$UPLOAD_ID\"]}" "$BASE/ v1/ jobs/ music-separation")
JOB_ID=$(echo "$JOB" | jq -er .id) || { echo "$JOB"; exit 1; } # an error body (credit, limits) has no id
# 3. Poll until it is done.
while :; do
JOB=$(curl -sS -H "$AUTH" "$BASE/ v1/ jobs/ $JOB_ID")
case "$(echo "$JOB" | jq -r .status)" in
succeeded) break ;;
queued|running) sleep 5 ;;
failed|canceled) echo "$JOB" | jq -r .error; exit 1 ;;
*) echo "$JOB"; exit 1 ;; # not a job at all: an error body
esac
done
# 4. One stem per part of the song.
for NAME in $(echo "$JOB" | jq -r '.result.stems[].name'); do
curl -fsSL -H "$AUTH" -o "$NAME.wav" "$BASE/ v1/ jobs/ $JOB_ID/ stems/ $NAME"
done