[FFmpeg-user] Piped processes result in glitches/dropouts
Srikanth Kotagiri
srikanthk at gmail.com
Sat Sep 28 21:37:24 EEST 2024
On Sat, Sep 28, 2024 at 11:26 AM Anders Bjerkén <anders at bjerken.net> wrote:
> SOLVED! Here's an update from me, that might help someone with a similar
> problem in the future:
>
> My problem turned out to be mainly hardware related. The "ALSA buffer
> xrun." messages indeed came every time I experienced a glitch in the sound
> stream. I first assumed it all had to do with limitations in the network
> connection, and that the stream going out from my Raspberry PI messed up
> for ffmpeg when doing the splitting of streams. That is why I tried to set
> up a UDP based connection to my streaming server. No need for that - it
> turned out to be the other way around. It was the local storage that was
> the problem. I had put a slow SD card in the RPI...
>
> On the way to a solution I found some other tricks, that might be useful to
> fine-tune a system like this:
>
> - Breaking out the PCM data extraction from my ffmpeg command, not using
> the ALSA plugin, reduced CPU load for the command by appr. 20%. Hence,
> instead of using "ffmpeg -i alsa ...", I now use "arecord ... - | ffmpeg
> -f s16le -i - ...". Here there might be some fine-tuning to be done
> in the ffmpeg code base.
> - Previously I used the /root partition in ext4 format for my local
> storage of audio data and logging. Setting up a separate partition using
> xfs as file system instead for storage and logging, made the glitches
> almost disappear.
> - Decreasing the mp3 compression rate to 64k of course made an impact on
> the throughput, but this was unacceptable from a listening perspective.
> - AND... I had an old class 4 SD card. Now I have one of class V30,
> which gives almost 10 times faster I/O access. This was the main fix!
>
> This is my final, working command:
>
> arecord --device='hw:<hwno>' --channels=2 --format=s16_le --rate=44 - |
> ffmpeg -hide_banner -f s16le -ac 2 -ar 44100 -channel_layout stereo -i -
> -filter:a 'volume=1.5' -ab 192k -acodec mp3 -f mp3 - | ffmpeg -hide_banner
> -f mp3 -i - -c copy -f mp3 -content_type 'audio/mpeg'
> icecast://source:<password>@<ip>:8000/pslive -c copy -f mp3 - >> /<xfs
> mount point>/audio.ts
>
> (Yes, I do a tidy-up of the concatenated audio.ts before using it...)
>
> This setup works flawlessly for an old RPI 3. However, it is not sufficient
> for a RPI Zero 1W - here the glitches appear every now and then, but much
> more seldom than before.
>
> The only problem I have now is that the piping between arecord and ffmpeg
> shuts down after 3 hours, 22 minutes and 54.94 seconds of 44.1 kHz PCM
> stereo data, and ffmpeg dies. Sharp on the second, every time. This is
> equivalent to transferring exactly 6 GB through the pipe (on the byte!). I
> don't see how to come around this limit; that seems to be hard coded in
> some way. Anyone who knows more about how to solve this? (However, this is
> not an actual problem for me, since the recording sessions I do never last
> longer than 2 hours.)
>
> Best regards,
> Anders
>
>
> Den lör 14 sep. 2024 kl 18:23 skrev Anders Bjerkén <anders at bjerken.net>:
>
> > Thanks Moritz for the quick response!
> >
> > Here's my command in its full context:
> >
> > ffmpeg -hide_banner -f s16le -ac 2 -ar 44100 -channel_layout stereo -f
> > alsa -i hw:2 -filter:a "volume=1.5" -ab 192k -acodec mp3 -f mp3 - |
> ffmpeg
> > -hide_banner -f mp3 -i - -c copy -f mpegts udp://<ip>:1685 -c copy -f mp3
> > udp://0.0.0.0:1685
> >
> > Input #0, alsa, from 'hw:2':
> >
> > Duration: N/A, start: 1726316588.273876, bitrate: 1411 kb/s
> >
> > Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
> >
> > Stream mapping:
> >
> > Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
> >
> > Press [q] to stop, [?] for help
> >
> > Output #0, mp3, to 'pipe:':
> >
> > Metadata:
> >
> > TSSE : Lavf58.45.100
> >
> > Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, fltp, 192
> kb/s
> >
> > Metadata:
> >
> > encoder : Lavc58.91.100 libmp3lame
> >
> > Input #0, mp3, from 'pipe:':0.91 bitrate= 197.4kbits/s speed=0.912x
> >
> > Metadata:
> >
> > encoder : Lavf58.45.100
> >
> > Duration: N/A, start: 0.000000, bitrate: 192 kb/s
> >
> > Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
> >
> > Output #0, mpegts, to 'udp://<ip>:1685':
> >
> > Metadata:
> >
> > encoder : Lavf58.45.100
> >
> > Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
> >
> > Output #1, mp3, to 'udp://0.0.0.0:1685':
> >
> > Metadata:
> >
> > TSSE : Lavf58.45.100
> >
> > Stream #1:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
> >
> > Stream mapping:
> >
> > Stream #0:0 -> #0:0 (copy)
> >
> > Stream #0:0 -> #1:0 (copy)
> >
> > size= 1346kB time=00:00:57.39 bitrate= 192.1kbits/s speed=0.999x
> >
> >
> > No, it doesn't glitch if I stream directly from the first ffmpeg process
> > to any of the outputs.
> >
> >
> > Thanks for the tip regarding the complete, uncut console output, which I
> > didn't study in detail before. I suddenly realized that there are
> > corresponding entries with "ALSA buffer xrun." in the log for every
> glitch.
> > I reckon this may be fixed by setting "-thread_queue_size" for the input
> in
> > my second ffmpeg. I will try different values and come back here if I
> don't
> > get it right...
> >
> >
> > Thanks again
> >
> > Anders
> >
> >
> >
> > Den lör 14 sep. 2024 kl 13:50 skrev Moritz Barsnick via ffmpeg-user <
> > ffmpeg-user at ffmpeg.org>:
> >
> >> Hej Anders,
> >>
> >> On Sat, Sep 14, 2024 at 13:32:01 +0200, Anders Bjerkén wrote:
> >> > ffmpeg -f alsa -i hw:2 -filter:a "volume=1.5" -ab 192k -acodec mp3 -f
> >> mp3 -
> >> > | ffmpeg -f mp3 -i - -c copy -f mpegts udp://<external_ip>:1685 -c
> copy
> >> -f
> >> > mp3 udp://0.0.0.0:1685
> >>
> >> It's usually expected to also post the complete, uncut console
> >> output(s) here.
> >>
> >> > Conceptually, it works. However, every now and then I get synchronized
> >> 1-2
> >> > second long glitches in the outcoming data stream for both outputs.
> >>
> >> This sounds like a buffering issue.
> >>
> >> What happens if you stream directly from the first ffmpeg process to
> >> one of the outputs? Does it also glitch?
> >>
> >> You could consider using one ffmpeg process and the "tee" muxer. I'm
> >> not sure it will solve your problem, but could be an alternative and a
> >> more lightweight command line.
> >>
> >> > have used all suggested versions of this command mentioned
> >> > on https://trac.ffmpeg.org/wiki/Creating%20multiple%20outputs, but
> >> with the
> >> > same result in the end.
> >>
> >> Ah, I forgot that the "tee" muxer is mentioned there as well.
> >>
> >> Moritz
> >> _______________________________________________
> >> ffmpeg-user mailing list
> >> ffmpeg-user at ffmpeg.org
> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
> >>
> >> To unsubscribe, visit link above, or email
> >> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
> >>
> >
> _______________________________________________
> ffmpeg-user mailing list
> ffmpeg-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> To unsubscribe, visit link above, or email
> ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
>
Instead of using the pipe can you try using the ffmpeg tee filter or split
filter? You can split the source stream into two and send one output to
disk and other to the network stream in a single ffmpeg process.
More information about the ffmpeg-user
mailing list