arduino-audio-tools icon indicating copy to clipboard operation
arduino-audio-tools copied to clipboard

Feature request: Example for how create a HLS stream m3u8 player

Open DrewBatchelor opened this issue 2 years ago • 19 comments

Hi Phil, Thank you for all the work you have put into making this amazing library, and thank you for generously sharing it. It is amazing.

I have been using it to make my main kitchen radio, but last month BBC have changed how they stream their internet radio, so mp3 streams are no longer available, only m3u8 like this one: "http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/uk/sbr_high/ak/bbc_6music.m3u8"

I can see that you have created a HLS player in experiments, which looks like it will solve this problem, but I can't quite work out how to use it.

Would you please share an example that shows how to use this to create a simple streaming music player. Something like the URL player example for playing a m3u8 live stream.

Many thanks

Drew

DrewBatchelor avatar Jul 02 '23 11:07 DrewBatchelor

BBC decided to provide the audio as m4a. Unfortunatly I do not have any codec which would support this and information how to parse this is really hard to find.

Any help is appreciated...

pschatzmann avatar Jul 03 '23 08:07 pschatzmann

Hi Phil, Thank you for the reply, this level of coding is well beyond my understanding, In searching for a solution, I found 2 possible similar projects that might be of help.

Frank Boesing AudioLibrary on a Teensy looks promising: https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib "Audiolibrary plugin, plays up to 320 kbps MP3, MP4(AAC), M4A(AAC), AAC-Raw or FLAC in software without external hardware - with only 48MHz." Frank B described the "*.m4a .... file format is horror :-) ( "ISO14496-14" if anyone wants to study it)"

And Yokohama-Miyazawa on a M5 Stack has and M5HLSPlayer: https://github.com/Yokohama-Miyazawa/M5HLSPlayer Although I'm not clear if this one is also solving the m4a Problem.

Kind Regards Drew

DrewBatchelor avatar Jul 03 '23 12:07 DrewBatchelor

3 attempts at any help:

Espressif provides an aac decoder with their ADF: https://github.com/espressif/esp-adf-libs/blob/master/esp_codec/include/codec/aac_decoder.h

m4a is just an envelope for a codec, usually aac. Have not checked for what bbc actually uses.

faad is one open source project that can decode m4a and aac, so probably contains code to study the difference.

joba-1 avatar Jul 03 '23 13:07 joba-1

Yes, I also found franks approach most promising, but I am not sure how reliable it will be. A test file that I donwloaded did not seem to have the same atoms that he was relying on. He also has an easier problem to solve because he can rely on the file API when doing the parsing.

I would expect that the helix aac decoder that I am normally using in my examples works as well.

Currently I am in the hospital,, so do not expect to see any quick progress.

pschatzmann avatar Jul 04 '23 13:07 pschatzmann

Things are not working yet, but to keep things simple, I decided on the following design:

  • HLSStream: provides the stream of raw (encoded) data. Usually with Content-Type: video/MP2T, so this is mpeg-ts (=MTS) format.
  • MTSDecoder: can be used to extract the AAC data using the https://github.com/pschatzmann/arduino-tsdemux library. This can be just forwarded to a AAC decoder to provide pcm data.

A draft implementation of these classes have been committed.

#include "AudioTools.h"
#include "AudioCodecs/CodecMTS.h"
#include "AudioCodecs/CodecAACHelix.h"

I2SStream out; // final output of decoded stream
HLSStream hls_stream("SSID", "password");
MTSDecoder mts;
AACDecoderHelix aac;
EncodedAudioStream aac_stream(&out, &aac); 
EncodedAudioStream mts_stream(&aac_stream, &mts);
StreamCopy copier(mts_stream, hls_stream);

// Arduino Setup
void setup(void) {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Info);

  out.begin(TX_MODE);
  mts_stream.begin();
  aac_stream.begin();

  hls_stream.begin("http://a.files.bbci.co.uk/media/live/manifesto/audio/simulcast/hls/nonuk/sbr_vlow/ak/bbc_world_service.m3u8");
}

// Arduino loop  
void loop() {
  copier.copy();
}

pschatzmann avatar Sep 10 '23 20:09 pschatzmann

faad is one open source project that can decode m4a and aac, so probably contains code to study the difference

I just made a test by sending the data directly to FAAD: it can't handle it! I am getting a Decoding error: Channel coupling not yet implemented. So there seems to be no direct path w/o mpeg-ts.

ps. The memory requirements for FAAD are horrendous!

pschatzmann avatar Sep 12 '23 11:09 pschatzmann

Today I spent some time to investigate why the MTSDecoder above is not working: I am stunned - the same code with the same data on the desktop is working, but on the ESP32 it's not.

This will be difficult to find...

pschatzmann avatar Sep 12 '23 16:09 pschatzmann

https://github.com/frejoel/tsdemux/issues/10

pschatzmann avatar Sep 13 '23 11:09 pschatzmann

@pschatzmann Thank you. Thank you.

DrewBatchelor avatar Sep 13 '23 15:09 DrewBatchelor

The MTSDecoder is working now, but the HLSStream seems to need some rework, to get faster. I want to avoid to use some FreeRTOS, so that this will work in other environments as well.

pschatzmann avatar Sep 13 '23 15:09 pschatzmann

Hi Phil, I'm not sure which example file this is, is it this one and is it working enough to be useful? https://github.com/pschatzmann/arduino-audio-tools/blob/ae72af696865c42bd3e929953bb36016189529b5/examples/examples-stream/streams-url_mts-hex/streams-url_mts-hex.ino#L12 Thank you

DrewBatchelor avatar Dec 12 '23 15:12 DrewBatchelor

No hls does not work properly yet

pschatzmann avatar Dec 12 '23 15:12 pschatzmann

Phil, my favorite radio use this kind of stream and after many research this is the only solution i've found. I look forward waiting for a working release. I'm very sorry my programming capacity are miles away to give any help. Now i'm compiling the example https://github.com/pschatzmann/arduino-audio-tools/blob/ae72af696865c42bd3e929953bb36016189529b5/examples/examples-stream/streams-url_mts-hex/streams-url_mts-hex.ino#L12 and starting to study it and your library. Very gratefull for your work

Marco1971Repo avatar Feb 13 '24 12:02 Marco1971Repo

HLS is not working (reliably) yet. I was coming to the conclusion that it will be too slow when using a simple sequential approach.

pschatzmann avatar Feb 13 '24 14:02 pschatzmann

I see the example running and receiving TS file without any sound. I rellay hope you can dedicate some time to make it work and I repeat i'm very sorry the matter is mile further to my capability to help. May all two esp32 cores in parallel can do the work but i understand is a big work to do

Marco1971Repo avatar Feb 13 '24 14:02 Marco1971Repo

The example sends the output to the display! So there can not be any sound... It might be no problem on an ESP32, but then the solution is not portable any more and will not run on other procesors!

pschatzmann avatar Feb 13 '24 14:02 pschatzmann

The example sends the output to the display! So there can not be any sound... Yes i'm trying to stream it i2s just to try it and study. But anyway you say the result it will be not good enough

I see your point regarding portability.

Marco1971Repo avatar Feb 13 '24 14:02 Marco1971Repo

Did you try this code: https://github.com/Yokohama-Miyazawa/M5HLSPlayer It seems to have all you need for HLS streaming with esp32?

lidense avatar Mar 13 '24 21:03 lidense

I am also very interested in HLS streams (mainly because BBC discontinued their Icecast MP3 streams). A quick note: Aside from issues of portability, the M5HLSPlayer repo also seems quite broken and hasn't had any commits in a year. HLS is a tough one!

z-l-p avatar Apr 28 '24 14:04 z-l-p