Closed vitoyucepi closed 2 years ago
Issue re-opened, see my rational here: https://github.com/savonet/liquidsoap/commit/acfaea458aa0f61ab4c67de72fbbd87349a5eb37#commitcomment-64698991
First, R128_TRACK_GAIN
seems to relate to a different standard than replaygain: https://en.wikipedia.org/wiki/EBU_R_128, it's not sure if we should or should not support it as part of the replaygain stack.
Second, I haven't run the test yet but there really is nothing that we do to change the volume on these tracks. We ask the ffmpeg decoder to decode it and send it to the vorbis encoder as is. I'm pretty sure the R128_TRACK_GAIN
does not even get passed to the encoder.
If I run those files through the replaygain peak detections, a different value is returned:
❯ ffmpeg -i /tmp/testfile_with_RG.opus -vn -filter replaygain -f null /dev/null
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 13.0.0 (clang-1300.0.29.3)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/4.4.1_5 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[ogg @ 0x133808200] 1 bytes of comment header remain
Input #0, ogg, from '/tmp/testfile_with_RG.opus':
Duration: 00:00:11.04, start: 0.000000, bitrate: 184 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
Metadata:
R128_TRACK_GAIN : -5120
Stream mapping:
Stream #0:0 -> #0:0 (opus (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
Metadata:
encoder : Lavf58.76.100
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Metadata:
R128_TRACK_GAIN : -5120
encoder : Lavc58.134.100 pcm_s16le
size=N/A time=00:00:11.00 bitrate=N/A speed= 242x
video:0kB audio:2069kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_replaygain_0 @ 0x132e04dc0] track_gain = -3.81 dB
[Parsed_replaygain_0 @ 0x132e04dc0] track_peak = 0.619401
❯ ffmpeg -i /tmp/testfile_without_RG.opus -vn -filter replaygain -f null /dev/null
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 13.0.0 (clang-1300.0.29.3)
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/4.4.1_5 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[ogg @ 0x142008200] 1 bytes of comment header remain
Input #0, ogg, from '/tmp/testfile_without_RG.opus':
Duration: 00:00:11.04, start: 0.000000, bitrate: 184 kb/s
Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
Stream mapping:
Stream #0:0 -> #0:0 (opus (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
Metadata:
encoder : Lavf58.76.100
Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Metadata:
encoder : Lavc58.134.100 pcm_s16le
size=N/A time=00:00:11.00 bitrate=N/A speed= 260x
video:0kB audio:2069kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_replaygain_0 @ 0x141105710] track_gain = -8.81 dB
[Parsed_replaygain_0 @ 0x141105710] track_peak = 1.101468
This is also confirmed by a visual inspection of the decoded wav files:
Sorry about this, I have known for long that we did not properly apply replaygain for opus and read this bug report too quickly...
Update:
After some testing with ffmpeg
and other players.
For example if I set apply gain in playback settings, then player will change volume according to replay gain.
Without audio processing all music has equal volume. Anyway it's not clear if it's metadata related or not.
@toots files in audacity are different because you need remove all gain info from opus file BEFORE encoding:
https://datatracker.ietf.org/doc/html/rfc7845 :
Players and media frameworks SHOULD apply it by default. If a player chooses to apply any volume adjustment or gain modification, such as the R128_TRACK_GAIN (see Section 5.2), the adjustment MUST be applied in addition to this output gain in order to achieve playback at the normalized volume.
A muxer SHOULD set this field to zero, and instead apply any gain prior to encoding, when this is possible and does not conflict with the user's wishes. A nonzero output gain indicates the gain was adjusted after encoding, or that a user wished to adjust the gain for playback while preserving the ability to recover the original signal amplitude.
https://github.com/Moonbase59/loudgain#how-i-handle-opus-opus-audio-files :
Encoders and muxes (should) set 'output_gain' to zero, so a non-zero 'output_gain' in the opus header is supposed to be a change after encoding/muxing.
Also, according to this info: https://wiki.xiph.org/OggOpus#Comment_Header when ReplayGain reading from file is disabled, music players must ignore both ReplayGain (R128_TRACK_GAIN) and Opus Header Gain. Don't know much about linux music players, but popular windows players like foobar2000 and AIMP works fine with this opus files, and if option "replaygain" is disabled, files sound the same, but if play files with RG through liquidsoap, they are quiet
Describe the bug If
opus
file contains replay gain metadata tag, then it will use it even ifenable_replaygain_metadata()
not used. I checked some other file formats and there's no such bug for them.Logs
``` liquidsoap_1 | 2022/01/26 02:03:18 >>> LOG START liquidsoap_1 | 2022/01/26 02:03:16 [main:3] Liquidsoap 2.0.2 liquidsoap_1 | 2022/01/26 02:03:16 [main:3] Using: bytes=[distributed with OCaml 4.02 or above] pcre=7.4.6 sedlex=2.3 menhirLib=20210419 curl=0.9.1 dtools=0.4.4 duppy=0.9.2 cry=0.6.5 mm=0.7.3 xmlplaylist=0.1.5 lastfm=0.3.3 ogg=0.7.0 ogg.decoder=0.7.0 vorbis=0.8.0 vorbis.decoder=0.8.0 opus=0.2.1 opus.decoder=0.2.1 speex=0.4.0 speex.decoder=0.4.0 mad=0.5.1 flac=0.3.0 flac.ogg=0.3.0 flac.decoder=0.3.0 dynlink=[distributed with Ocaml] lame=0.3.5 shine=0.2.2 frei0r=0.1.2 fdkaac=0.3.2 theora=0.4.0 theora.decoder=0.4.0 ffmpeg=1.1.1 bjack=0.1.6 alsa=0.3.0 ao=0.2.3 samplerate=0.1.6 taglib=0.3.7 ssl=0.5.9 magic=0.7.3 camomile=1.0.2 inotify=2.3 yojson=1.7.0 faad=0.5.0 soundtouch=0.1.9 portaudio=0.2.3 pulseaudio=0.1.4 ladspa=0.2.0 dssi=0.1.3 tsdl=v0.9.8 tsdl_ttf=0 tsdl-image=0.3.2 camlimages=4.2.6 cohttp-lwt-unix=2.5.5 prometheus-app=1.1 srt.constants=0.2.1 srt.types=0.2.1 srt.stubs=0.2.1 srt.stubs.locked=0.2.1 srt=0.2.1 lo=0.2.0 gd=1.0a5 liquidsoap_1 | 2022/01/26 02:03:16 [clock:3] Using builtin (low-precision) implementation for latency control liquidsoap_1 | 2022/01/26 02:03:17 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz main. liquidsoap_1 | 2022/01/26 02:03:17 [frame:3] Video frame size set to: 1280x720 liquidsoap_1 | 2022/01/26 02:03:17 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples. liquidsoap_1 | 2022/01/26 02:03:17 [frame:3] Targeting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks. liquidsoap_1 | 2022/01/26 02:03:17 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks. liquidsoap_1 | 2022/01/26 02:03:18 [sandbox:3] Sandboxing disabled liquidsoap_1 | 2022/01/26 02:03:18 [video.converter:3] Using preferred video converter: ffmpeg. liquidsoap_1 | 2022/01/26 02:03:18 [audio.converter:3] Using samplerate converter: ffmpeg. liquidsoap_1 | 2022/01/26 02:03:18 [single_0:3] /var/liquidsoap/with_RG.opus is static, resolving once for all... liquidsoap_1 | 2022/01/26 02:03:18 [single_1:3] /var/liquidsoap/without_RG.opus is static, resolving once for all... liquidsoap_1 | 2022/01/26 02:03:18 [single_0:3] Prepared "/var/liquidsoap/with_RG.opus" (RID 0). liquidsoap_1 | 2022/01/26 02:03:18 [clock.main:3] Streaming loop starts in auto-sync mode liquidsoap_1 | 2022/01/26 02:03:18 [clock.main:3] Delegating synchronisation to CPU clock liquidsoap_1 | 2022/01/26 02:03:18 [switch_1:3] Switch to switch_0. liquidsoap_1 | 2022/01/26 02:03:18 [switch_0:3] Switch to single_0. liquidsoap_1 | [opus @ 0x7fa33000bb40] Could not update timestamps for skipped samples. liquidsoap_1 | [opus @ 0x7fa33000bb40] Could not update timestamps for discarded samples. liquidsoap_1 | 2022/01/26 02:03:28 [decoder:2] Decoding "/var/liquidsoap/with_RG.opus" ended: Ffmpeg_decoder.End_of_file. liquidsoap_1 | 2022/01/26 02:03:29 [single_0:3] Prepared "/var/liquidsoap/with_RG.opus" (RID 0). liquidsoap_1 | 2022/01/26 02:03:29 [single_1:3] Prepared "/var/liquidsoap/without_RG.opus" (RID 1). liquidsoap_1 | 2022/01/26 02:03:29 [switch_0:3] Switch to single_1 with forgetful transition. liquidsoap_1 | [opus @ 0x7fa330013880] Could not update timestamps for skipped samples. liquidsoap_1 | [opus @ 0x7fa330013880] Could not update timestamps for discarded samples. liquidsoap_1 | 2022/01/26 02:03:39 [decoder:2] Decoding "/var/liquidsoap/without_RG.opus" ended: Ffmpeg_decoder.End_of_file. liquidsoap_1 | 2022/01/26 02:03:40 [switch_0:3] Switch to single_0. liquidsoap_1 | [opus @ 0x7fa330054bc0] Could not update timestamps for skipped samples. ```To Reproduce
Get sample files
testfile_original.flac
is the reference filetestfile_with_RG.opus
file with replay gain metadata tagffprobe testfile_with_RG.opus
testfile_without_RG.opus
file without tagffprobe testfile_without_RG.opus
ffplay
vlc
Create config
liquidsoap
/tmp/test.ogg
/tmp/test.ogg
Expected behavior Replay gain should be ignored by default in
opus
files.Version details
Install method Deb package from liquidsoap ci artifacts at github
Common issues N/A