Hi John,

Le lun. 21 mars 2022 à 12:29, John Warburton <j...@johnwarburton.net> a
écrit :
>
> On Mon, 21 Mar 2022 at 09:36, Romain Beauxis <romain.beau...@gmail.com>
wrote:
> I'm making the assumption that metadata mostly matters for audio streams
where they may hold track title/artist/album etc.
> >>>>
> > Curiously, the metadata sometimes flicks into life, but most of the
time my player reports "Unknown".
>
> > Do you have a script I could use to try & reproduce this?
>
> Thanks for asking Romain,
>
> By adding my own metadata handler, the problem went away. The metadata
handler was called before any crossfade.
>
> But on testing the script at the end of this email, which uses crossfade
before an FFmpeg filter for audio processing, the metadata stays the same
as the first track in the stream, no matter how many more tracks are
crossfaded afterwards.
>
> Incidentally, when putting an FFmpeg filter into the stream, do I still
need to change from stream to raw, thus, and back again afterwards with
ffmpeg.raw.decode.audio(s)?
>
> s = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), s)
> ...
>
> with best wishes,
> John
>
> #!/usr/local/bin/liquidsoap
>
> set("log.level", 5)
> settings.server.telnet.set(true)
> settings.server.telnet.bind_addr.set("0.0.0.0")
> settings.server.telnet.port.set(1235)
> settings.server.timeout.set(-1.0)
> settings.request.metadata_decoders.set(["FFMPEG"])
> settings.decoder.decoders.set(["FFMPEG"])
> settings.decoder.file_extensions.wav.set([])
> settings.decoder.file_extensions.taglib.set([])
> settings.decoder.file_extensions.id3v2.set([])
> settings.decoder.file_extensions.ffmpeg.set(["mka"])
> settings.frame.audio.samplerate.set(48000)
>
> def audio_process(s) =
>   def mkfilter(graph) =
>     s = ffmpeg.filter.audio.input(graph, pass_metadata=true, s)
>     s = ffmpeg.filter.dynaudnorm(graph, s, gausssize=23, correctdc=true,
altboundary=true, maxgain=80., b=true, targetrms=1.)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=192000)
>     s = ffmpeg.filter.alimiter(graph, s, limit=0.95, attack=3.,
release=50., asc=true, asc_level=1.)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=48000)
>     ffmpeg.filter.audio.output(graph, pass_metadata=true, s)
>   end
>   ffmpeg.filter.create(mkfilter)
> end
>
> def audio_process_wrap(s) =
>   a = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), s)
>   a = audio_process(a)
>   ffmpeg.raw.decode.audio(a)
> end
>
> def audio_process_multi(s) =
>   def mkfilter_multi(graph) =
>     s = ffmpeg.filter.audio.input(graph, pass_metadata=true, s)
>     s = ffmpeg.filter.dynaudnorm(graph, s, gausssize=7, correctdc=true,
altboundary=true, maxgain=80., b=true, targetrms=1.)
>     s = ffmpeg.filter.volume(graph, s, volume="-18dB", precision=2,
replaygain=0)
>     s = ffmpeg.filter.aexciter(graph, s, freq=6000.)
>     s = ffmpeg.filter.mcompand(graph, s, args="0.005,0.1 6
-47/-37,-34/-34,-17/-33 90 | 0.003,0.05 6 -47/-40,-34/-34,-17/-33 180 |
0.003,0.05 6 -47/-40,-34/-34,-17/-33 360 | 0.000625,0.03 6
-47/-40,-34/-34,-17/-33 1600 | 0.000625,0.03 6 -47/-40,-34/-34,-17/-33 2800
| 0.0001,0.025 6 -47/-35,-34/-34,-17/-33 5000 | 0,0.025 6
-47/-35,-34/-34,-17/-33 8192 | 0,0.025 6 -47/-40,-34/-34,-17/-33 23999")
>     s = ffmpeg.filter.volume(graph, s, volume="+20dB", precision=2,
replaygain=0)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=192000)
>     s = ffmpeg.filter.alimiter(graph, s, limit=0.8, attack=3.,
release=50., asc=false, asc_level=0., level=true)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=48000)
>     ffmpeg.filter.audio.output(graph, pass_metadata=true, s)
>   end
>   ffmpeg.filter.create(mkfilter_multi)
> end
>
> def audio_process_multi_wrap(s) =
>   a = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), buffer(s))
>   a = audio_process_multi(a)
>   ffmpeg.raw.decode.audio(a)
> end
>
> security = single("/home/john/src/radio/fault.mka")
>
> # Here's the playlist, annotated as per our Python pre-production program
dictates
> myplaylist = playlist(reload_mode="watch",
mime_type="application/x-mpegURL",
"/home/john/src/radio/bc2-30DEC2020-complete.m3u8")
>
> # Cut off any silent starts
> myplaylist = cue_cut(myplaylist)
>
> # Amplify each track according to our own EBU R.128 volume data
> myplaylist = amplify(override="liq_amplify", 1.0, myplaylist)
>
> # Add the news
> myplaylist = fallback(track_sensitive=true, transition_length=30.0,
[request.queue(id="override"), myplaylist])
>
> # Do the crossfades
> myplaylist = crossfade(duration=30.0, smart=false, fade_out=0.0,
fade_in=0.0, minimum=-1.0, default=(fun(a,b)->add(normalize=false,([b,
a]))), conservative=true,  myplaylist)
>
> radio = fallback(track_sensitive=false, [audio_process_wrap(myplaylist),
security])
> radio_comp = fallback(track_sensitive=false,
[audio_process_multi_wrap(myplaylist), security])
>
> output.icecast(icy_metadata="true", description="Music Too (hifi)",
genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
mount="audio-hifi.aac", public=true, url="
http://warblefly.sytes.net:8001/audio-hifi.aac";, timeout=240.0,
format="audio/aac", password="[REDACTED]", %fdkaac(channels=2,
samplerate=48000, bandwidth="auto", vbr=5, afterburner=true,
aot="mpeg2_aac_lc"), radio)
>
> output.icecast(icy_metadata="true", description="Music Too (compressed)",
genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
mount="audio-comp.aac", public=true, url="
http://warblefly.sytes.net:8001/audio-comp.aac";, timeout=240.0,
format="audio/aac", password="[REDACTED]", %fdkaac(channels=2,
samplerate=48000, bandwidth="auto", vbr=5, afterburner=true,
aot="mpeg2_aac_lc"), radio_comp)
>
> output.icecast(icy_metadata="true", description="Music Too (comp, low
bw)", genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
mount="audio.aac", public=true, url="
http://warblefly.sytes.net:8001/audio.aac";, timeout=240.0,
format="audio/aac", password="REDACTED", %fdkaac(channels=2,
samplerate=32000, bandwidth="auto", vbr=1, afterburner=true,
aot="mpeg4_he_aac_v2"), radio_comp)


Thanks for this example, this has forced me to take another look at ffmpeg
filters. I discovered several issues with them with the configuration that
you are looking at.

I was able to fix most of what I could see and add a test. As far as I can
tell your filters should now work with the `v2.0.4-preview` branch (soon to
be `2.0.4` release).

There were some issues with the multi one but they were raised by ffmpeg
about some internal issue with the filter parameters so this looks like
something to be fixed in the script.

I was able to notice more issues with the filters but they will need a
deeper rewrite to be addressed. Those are mostly cases when one wants to
re-mux audio and video data generated by a filter. This is probably a
pretty advanced use at the moment.


Le lun. 21 mars 2022 à 12:29, John Warburton <j...@johnwarburton.net> a
écrit :

> On Mon, 21 Mar 2022 at 09:36, Romain Beauxis <romain.beau...@gmail.com>
> wrote:
> I'm making the assumption that metadata mostly matters for audio streams
> where they may hold track title/artist/album etc.
> >>>>
> > Curiously, the metadata sometimes flicks into life, but most of the time
> my player reports "Unknown".
>
> > Do you have a script I could use to try & reproduce this?
>
> Thanks for asking Romain,
>
> By adding my own metadata handler, the problem went away. The metadata
> handler was called before any crossfade.
>
> But on testing the script at the end of this email, which uses crossfade
> before an FFmpeg filter for audio processing, the metadata stays the same
> as the first track in the stream, no matter how many more tracks are
> crossfaded afterwards.
>
> Incidentally, when putting an FFmpeg filter into the stream, do I still
> need to change from stream to raw, thus, and back again afterwards with
> ffmpeg.raw.decode.audio(s)?
>
> s = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), s)
> ...
>
> with best wishes,
> John
>
> #!/usr/local/bin/liquidsoap
>
> set("log.level", 5)
> settings.server.telnet.set(true)
> settings.server.telnet.bind_addr.set("0.0.0.0")
> settings.server.telnet.port.set(1235)
> settings.server.timeout.set(-1.0)
> settings.request.metadata_decoders.set(["FFMPEG"])
> settings.decoder.decoders.set(["FFMPEG"])
> settings.decoder.file_extensions.wav.set([])
> settings.decoder.file_extensions.taglib.set([])
> settings.decoder.file_extensions.id3v2.set([])
> settings.decoder.file_extensions.ffmpeg.set(["mka"])
> settings.frame.audio.samplerate.set(48000)
>
> def audio_process(s) =
>   def mkfilter(graph) =
>     s = ffmpeg.filter.audio.input(graph, pass_metadata=true, s)
>     s = ffmpeg.filter.dynaudnorm(graph, s, gausssize=23, correctdc=true,
> altboundary=true, maxgain=80., b=true, targetrms=1.)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=192000)
>     s = ffmpeg.filter.alimiter(graph, s, limit=0.95, attack=3.,
> release=50., asc=true, asc_level=1.)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=48000)
>     ffmpeg.filter.audio.output(graph, pass_metadata=true, s)
>   end
>   ffmpeg.filter.create(mkfilter)
> end
>
> def audio_process_wrap(s) =
>   a = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), s)
>   a = audio_process(a)
>   ffmpeg.raw.decode.audio(a)
> end
>
> def audio_process_multi(s) =
>   def mkfilter_multi(graph) =
>     s = ffmpeg.filter.audio.input(graph, pass_metadata=true, s)
>     s = ffmpeg.filter.dynaudnorm(graph, s, gausssize=7, correctdc=true,
> altboundary=true, maxgain=80., b=true, targetrms=1.)
>     s = ffmpeg.filter.volume(graph, s, volume="-18dB", precision=2,
> replaygain=0)
>     s = ffmpeg.filter.aexciter(graph, s, freq=6000.)
>     s = ffmpeg.filter.mcompand(graph, s, args="0.005,0.1 6
> -47/-37,-34/-34,-17/-33 90 | 0.003,0.05 6 -47/-40,-34/-34,-17/-33 180 |
> 0.003,0.05 6 -47/-40,-34/-34,-17/-33 360 | 0.000625,0.03 6
> -47/-40,-34/-34,-17/-33 1600 | 0.000625,0.03 6 -47/-40,-34/-34,-17/-33 2800
> | 0.0001,0.025 6 -47/-35,-34/-34,-17/-33 5000 | 0,0.025 6
> -47/-35,-34/-34,-17/-33 8192 | 0,0.025 6 -47/-40,-34/-34,-17/-33 23999")
>     s = ffmpeg.filter.volume(graph, s, volume="+20dB", precision=2,
> replaygain=0)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=192000)
>     s = ffmpeg.filter.alimiter(graph, s, limit=0.8, attack=3.,
> release=50., asc=false, asc_level=0., level=true)
>     s = ffmpeg.filter.aresample(graph, s, sample_rate=48000)
>     ffmpeg.filter.audio.output(graph, pass_metadata=true, s)
>   end
>   ffmpeg.filter.create(mkfilter_multi)
> end
>
> def audio_process_multi_wrap(s) =
>   a = ffmpeg.raw.encode.audio(%ffmpeg(%audio.raw), buffer(s))
>   a = audio_process_multi(a)
>   ffmpeg.raw.decode.audio(a)
> end
>
> security = single("/home/john/src/radio/fault.mka")
>
> # Here's the playlist, annotated as per our Python pre-production program
> dictates
> myplaylist = playlist(reload_mode="watch",
> mime_type="application/x-mpegURL",
> "/home/john/src/radio/bc2-30DEC2020-complete.m3u8")
>
> # Cut off any silent starts
> myplaylist = cue_cut(myplaylist)
>
> # Amplify each track according to our own EBU R.128 volume data
> myplaylist = amplify(override="liq_amplify", 1.0, myplaylist)
>
> # Add the news
> myplaylist = fallback(track_sensitive=true, transition_length=30.0,
> [request.queue(id="override"), myplaylist])
>
> # Do the crossfades
> myplaylist = crossfade(duration=30.0, smart=false, fade_out=0.0,
> fade_in=0.0, minimum=-1.0, default=(fun(a,b)->add(normalize=false,([b,
> a]))), conservative=true,  myplaylist)
>
> radio = fallback(track_sensitive=false, [audio_process_wrap(myplaylist),
> security])
> radio_comp = fallback(track_sensitive=false,
> [audio_process_multi_wrap(myplaylist), security])
>
> output.icecast(icy_metadata="true", description="Music Too (hifi)",
> genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
> mount="audio-hifi.aac", public=true, url="
> http://warblefly.sytes.net:8001/audio-hifi.aac";, timeout=240.0,
> format="audio/aac", password="[REDACTED]", %fdkaac(channels=2,
> samplerate=48000, bandwidth="auto", vbr=5, afterburner=true,
> aot="mpeg2_aac_lc"), radio)
>
> output.icecast(icy_metadata="true", description="Music Too (compressed)",
> genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
> mount="audio-comp.aac", public=true, url="
> http://warblefly.sytes.net:8001/audio-comp.aac";, timeout=240.0,
> format="audio/aac", password="[REDACTED]", %fdkaac(channels=2,
> samplerate=48000, bandwidth="auto", vbr=5, afterburner=true,
> aot="mpeg2_aac_lc"), radio_comp)
>
> output.icecast(icy_metadata="true", description="Music Too (comp, low
> bw)", genre="Freeform", name="Music Too", host="127.0.0.1", port=8001,
> mount="audio.aac", public=true, url="
> http://warblefly.sytes.net:8001/audio.aac";, timeout=240.0,
> format="audio/aac", password="REDACTED", %fdkaac(channels=2,
> samplerate=32000, bandwidth="auto", vbr=1, afterburner=true,
> aot="mpeg4_he_aac_v2"), radio_comp)
>
> _______________________________________________
> Savonet-users mailing list
> Savonet-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/savonet-users
>
_______________________________________________
Savonet-users mailing list
Savonet-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/savonet-users

Reply via email to