1

I have been trying to pipe 2 levels deep.

I can pipe successfully:

  1. ffmpeg | grep
  2. ffmpeg | sed

I can not pipe

  1. ffmpeg | grep | sed
  2. ffmpeg | sed | grep

I don't understand, does ffmpeg limit to only one pipe in the chain?

This code has NO OUTPUT with 2 pipes and no errors:

ffmpeg -i "https://17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5 -f null - 2>&1 | grep silence_duration | sed "s/.*silence_duration: \(.*\).*/\1/"

Expected Output:

2.06442
0.719252
0.594036
0.562698
0.500295

This code has the correct output with 1 pipe:

ffmpeg -i "https://17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5 -f null - 2>&1 | grep silence_duration

Output:

[silencedetect @ 0000018027f9bd00] silence_end: 2.06442 | silence_duration: 2.06442
[silencedetect @ 0000018027f9bd00] silence_end: 3.45971 | silence_duration: 0.719252
[silencedetect @ 0000018027f9bd00] silence_end: 7.04399 | silence_duration: 0.594036
[silencedetect @ 0000018027f9bd00] silence_end: 7.81501 | silence_duration: 0.562698
[silencedetect @ 0000018027f9bd00] silence_end: 9.05535 | silence_duration: 0.500295

This code has the correct output with 1 pipe:

ffmpeg -i "https://17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5 -f null - 2>&1 | sed "s/.*silence_duration: \(.*\).*/\1/"

Output:

[silencedetect @ 000001a48277b980] silence_start: 0
2.06442
[silencedetect @ 000001a48277b980] silence_start: 2.74045
0.719252
[silencedetect @ 000001a48277b980] silence_start: 6.44995
0.594036
[silencedetect @ 000001a48277b980] silence_start: 7.25231
0.562698
[silencedetect @ 000001a48277b980] silence_start: 8.55506
0.500295

1 Answer 1

3

Why is grep | sed not doing anything?

It is, but you didn't wait for it. If you press q then ffmpeg will close the stream the silence_duration values will be displayed.

If you want it to print the values immediately one method is to use awk instead.

How to isolate the silence_duration values?

If the ultimate goal is to isolate the silence_duration values use awk:

ffmpeg -i "https://17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5 -f null - 2>&1 |  awk -F ': ' '/silence_duration/ {print $3}'

Result:

2.06442
0.719252
0.594036
0.562698
0.663968
1.24109

However, I prefer to use the (a)metadata filter with filters that support metadata keys. It is more complicated, but the output is cleaner and easier to parse. You can easily either pipe the info (file=-) or output directly to a file (file=silence.log):

ffmpeg -loglevel error -i "https://17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5,ametadata=mode=print:key=lavfi.silence_duration:file=- -f null - | awk -F = '/silence_duration/ {print $2}'
3
  • Thank you so much! This has been a great help for me, I took your code and modified it to append to a silence.log file with a slight variation: ffmpeg -loglevel error -i "17563.live.streamtheworld.com/WETAFM.mp3?nocache=Ag6q8pw2" -af silencedetect=n=-10dB:d=0.5,ametadata=mode=print:key=lavfi.silence_duration:file=- -t 30 -f null - | awk -F = '/silence_duration/ {print $2 >> "silence.log"}' Sep 28, 2021 at 17:22
  • @JimDandyBOA Consider removing the -t 30 if you want to process more than 30 seconds. I forgot to remove that from the answer originally.
    – llogan
    Sep 28, 2021 at 17:24
  • Coincidentally, before you added the -t 30 I had added the exact same thing the night before to force writing to an output file because awk is buffering the output to file but does not buffer to the terminal screen. My intentions were to call FFmpeg in a while loop as a hack. This method worked but opened up a can of worms with repeated opening and closing. Well, I learned a lot and hope that this post is useful to others. Thanks again Sep 28, 2021 at 17:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .