1

My use case is essentially DIY internet radio. I've abstracted the real-world constraints into a toy problem for simplicity, but these constraints are real for me.

I'm shipping a 24/7 live HLS stream with only MP3 files. In a perfect world, the catch is that to support high fault tolerance, and these MP3 files are all individually generated from the source WAV files.

I've gotten a test version working with ffmpeg running inside of another process that feeds PCM data to its stdin:

ffmpeg \
    -v info \
    -i pipe:0 \
    -f hls \
    -ac 2 \
    -c:a mp3 \
    -b:a 128k \
    -initial_offset 12345 \
    -maxrate 128k \
    -minrate 128k \
    -start_number 12345 \
    -hls_flags delete_segments \
    -hls_list_size 20 \
    -hls_playlist_type event \
    -hls_segment_filename /tmp/radio-%d.mp3 \
    -hls_time 10

Ideally, I can consume that stream using ffplay without errors.

However, when I perfectly replicate the output of that ffmpeg -f hls process above using manual ffmpeg runs, we hear audio discontinuities, tiny pieces of silent mortar between the bricks of audio. The reason for this is known. See this answer to this question on video StackExchange: Audio discontinuities when generating HLS segments in different processes:

Here's the ffmpeg I've got so far encoding from WAV files that we write to a temp folder on disk in advance of this step:

ffmpeg \
    -i pathToWAV \
    -id3v2_version 0 \
    -ac 2 \
    -c:a mp3 \
    -b:a 128k \
    -minrate 128k \
    -maxrate 128k \
    /tmp/radio-12345.wav

Is there some way to tell ffmpeg to use the last 1024 frames from the previously-encoded MP3 (e.g. radio-12344.mp3) in the transform overlapping the first 1024 frames of the next MP3 media segment in the HLS? Or maybe to do a second pass on each file using a muxer where I lop off those priming samples?

1
  • The best solution I've come up with so far is essentially the first version above where I run ffmpeg continuously outputting a whole HLS playlist based on stdin. What I figured out is that if I always discard the first segment generated when said process starts up (the first MP3 in the series is the only one that begins with priming frames) and I use a media segment numbering system that is totally deterministic from any given epoch seconds, then I can more-or-less idempotently generate my segments, per my fault tolerance constraints. Dec 27, 2021 at 4:06

1 Answer 1

1

The Thing Is, you are not perfectly replicating the output of -f hls by doing what you are doing. You are creating discrete mp3's and expecting them to behave the same way as hls mp3's. HLS is designed to produce mp3's that are a continuous stream of concatenatable files. Discrete mp3's cannot be concatenated in he way you are attempting.

Also, check this:

https://github.com/huhani/mp3-to-hls

2
  • That's right. However, it is certainly theoretically possible to do what I describe, if one could rehydrate its codec using the last 1024 frames from the previous media segment. The question is whether ffmpeg has this flexibility. In the meantime, I have posted an interesting trick I figured out in a comment on the original post. Dec 27, 2021 at 4:09
  • Yes, but I think that's what -f hls is doing.
    – Mark
    Dec 28, 2021 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.