I implemented a StreamingResponse in FastAPI with audio bytes from async generator sources. But besides need to insert some messages for client side audio player (currently, React Native) just in the stream.
Read about ICY format and it looks like appropriate stuff for this. So what headers are required for stream endpoint and what format a message for AudioPlayer should be to trigger an event (like Event.MetadataCommonReceived
)?
@router.get(
"/stream/{session_id}",
response_class=StreamingResponse,
responses={200: {"content": {"audio/mpeg": {}}, "description": "An audio file in MP3 format"}},
)
async def stream_audio(session_id: str):
...
return StreamingResponse(
stream_from_queue(<some asyncio.Queue>, session_id),
headers={
"content-type": "audio/mpeg",
"icy-metaint": "16000",
"icy-name": "MyAudioStream",
"icy-genre": "Podcast",
"icy-url": "http://localhost:8000"
},
media_type="audio/mpeg",
)
async def stream_from_queue(queue: Queue, session_id: str):
... # get an audio chunk from queue
... # send some metadata
2
Answers
Base on the protocol description link (thank to Rauuun) I implemented this algorithm.
After reading https://gist.github.com/niko/2a1d7b2d109ebe7f7ca2f860c3505ef0 it seems that your method
stream_from_queue
needs to pad the initial message that you willyield
with the metadata information you desire to send.I understand the encoding is ascii