Install
openclaw skills install audio-upload-aioz-streamQuick upload audio to AIOZ Stream API. Create audio objects with default or custom encoding configurations, upload the file, complete the upload, then return the audio link to the user.
openclaw skills install audio-upload-aioz-streamUpload audio to AIOZ Stream API quickly with API key authentication. The full upload flow requires 3 API calls: Create → Upload Part → Complete.
This skill uses API key authentication. The user must provide:
stream-public-key: their AIOZ Stream public keystream-secret-key: their AIOZ Stream secret keyAsk the user for these keys if not provided. They will be sent as HTTP headers on ALL API calls.
When the user wants to upload audio, ask them to choose:
Creates an audio object with minimal config — just a title. Then uploads the file.
Example user prompt:
"Upload audio file /path/to/audio.mp3 with title My Podcast"
Creates an audio object with full encoding configuration including quality presets, bitrate, sample rate, tags, metadata, etc. Then uploads the file.
Example user prompt:
"Upload audio with custom config: title My Podcast, highest quality HLS, 320kbps, 48000Hz, tags podcast,tech"
Default:
curl -s -X POST 'https://api-w3stream.attoaioz.cyou/api/videos/create' \
-H 'stream-public-key: PUBLIC_KEY' \
-H 'stream-secret-key: SECRET_KEY' \
-H 'Content-Type: application/json' \
-d '{
"title": "AUDIO_TITLE",
"type": "audio"
}'
Custom (with encoding config):
curl -s -X POST 'https://api-w3stream.attoaioz.cyou/api/videos/create' \
-H 'stream-public-key: PUBLIC_KEY' \
-H 'stream-secret-key: SECRET_KEY' \
-H 'Content-Type: application/json' \
-d '{
"title": "AUDIO_TITLE",
"type": "audio",
"description": "DESCRIPTION",
"is_public": true,
"tags": ["tag1", "tag2"],
"metadata": [
{"key": "KEY", "value": "VALUE"}
],
"qualities": [
{
"resolution": "highest",
"type": "hls",
"container_type": "mpegts",
"audio_config": {
"codec": "aac",
"bitrate": 320000,
"channels": "2",
"sample_rate": 48000,
"language": "en",
"index": 0
}
},
{
"resolution": "standard",
"type": "hls",
"container_type": "mpegts",
"audio_config": {
"codec": "aac",
"bitrate": 128000,
"channels": "2",
"sample_rate": 44100,
"language": "en",
"index": 0
}
}
]
}'
Response: Extract data.id — this is the AUDIO_ID used in the next steps.
Upload the actual audio file binary to the created audio object.
First, get the file size and compute the MD5 hash:
# Get file size (cross-platform compatible)
FILE_SIZE=$(stat -f%z /path/to/audio.mp3 2>/dev/null || stat -c%s /path/to/audio.mp3)
END_POS=$((FILE_SIZE - 1))
# Compute MD5 hash
HASH=$(md5sum /path/to/audio.mp3 | awk '{print $1}')
Then upload via multipart form-data with the Content-Range header:
curl -s -X POST "https://api-w3stream.attoaioz.cyou/api/videos/AUDIO_ID/part" \
-H 'stream-public-key: PUBLIC_KEY' \
-H 'stream-secret-key: SECRET_KEY' \
-H "Content-Range: bytes 0-$END_POS/$FILE_SIZE" \
-F "file=@/path/to/audio.mp3" \
-F "index=0" \
-F "hash=$HASH"
Important: The Content-Range header is required for the upload to succeed. Format: bytes {start}-{end}/{total_size} where:
start=0, end=file_size-1, total_size=file_sizeForm-data fields:
file: the audio file binary (use @/path/to/file)index: 0 (for single-part upload, increment for multi-part)hash: MD5 hash of the file partAfter the file part is uploaded, call the complete endpoint to finalize:
curl -s -X GET "https://api-w3stream.attoaioz.cyou/api/videos/AUDIO_ID/complete" \
-H 'accept: application/json' \
-H 'stream-public-key: PUBLIC_KEY' \
-H 'stream-secret-key: SECRET_KEY'
This triggers transcoding. The upload is now considered successful.
After completing the upload, fetch the audio detail to get the streaming URL:
curl -s 'https://api-w3stream.attoaioz.cyou/api/videos/AUDIO_ID' \
-H 'stream-public-key: PUBLIC_KEY' \
-H 'stream-secret-key: SECRET_KEY'
Parse the response to find the HLS URL from the assets or hls field and return it to the user.
Important: Audio outputs do NOT have an mp4_url field. Only HLS/DASH streaming links are available.
resolution field):standard — Standard qualitygood — Good qualityhighest — Highest qualitylossless — Lossless qualitytype field):hls — HTTP Live Streaming (container: mpegts or mp4)dash — Dynamic Adaptive Streaming (container: fmp4)codec: aac (only supported codec)bitrate: integer in bits/sec (e.g., 128000, 256000, 320000)channels: "2" (stereo)sample_rate: 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000language: BCP 47 code (e.g., en, vi)index: 0data.idAUDIO_ID