Here’s how streaming works. In general. This is not news and is not really helpful. I’ll post it anyway.
There are three main tasks when you’re streaming. Could be audio, could be video, it doesn’t really matter. First, you’ll pull the content from the network. Buffering. Then you’ll decode the content. Then you’ll render it. (Yes, the output of audio is rendering it to the output buffer)
Many applications express these three job systems by using multiple threads. It’s a wise choice and makes a lot of sense. The problems appear when the specifics of the implementation come in to play. What happens when a network connection fails half way through? You’ve spun up three threads, one provides the other with raw data, one decodes the data, and one outputs the data as audio. How do you handle a stall?
Now, how do you handle a decoding error? It’s totally possible your source has promised a MIME type that it doesn’t conform to. Promised MP3 but given an M4A? With audio, it’s often close enough.
Once you start? That’s the easy bit. Stopping is hard. Three threads working away delivering data asynchronously? You need to coordinate them all stopping immediately. Without just shutting down the app. That may sound like a piece of cake but it’s really a pie in the face.
The concept is dead simple. One thread downloads the data and then passes it off to the decoding thread. The decoding thread turns MP3 or whatever format into the native PCM format that can be output by the device. The device takes that input and queues it onto a native audio output channel.
Sounds easy, right?