From 63fb7405952428a3093ea32865ef0336e1a46bda Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 12 Oct 2023 09:22:51 +0000 Subject: favor ffmpeg over deprecated avconv When this project started avconv was favored in Debian, but that hasn't been the case in many years. Increase the priority of ffmpeg to match the current situation in Debian. --- Documentation/dtas-player.pod | 10 ++-- Documentation/dtas-sourceedit.pod | 8 +-- lib/dtas/source/av.rb | 6 +-- lib/dtas/source/av_ff_common.rb | 8 +-- lib/dtas/source/ff.rb | 7 +-- test/test_source_ff.rb | 102 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 test/test_source_ff.rb diff --git a/Documentation/dtas-player.pod b/Documentation/dtas-player.pod index 932441a..4cfdd12 100644 --- a/Documentation/dtas-player.pod +++ b/Documentation/dtas-player.pod @@ -70,10 +70,10 @@ To play audio on my favorite USB DAC directly to ALSA, I use: =head2 Seeking/playing audio from large video containers (e.g. VOB) fails This is a problem with large VOBs. We recommend breaking up the -VOB into smaller files or using L or L to extract -the desired audio stream. +VOB into smaller files or using L to extract +the desired audio stream at C<$STREAM_NR>. - avconv -analyzeduration 2G -probesize 2G \ + ffmpeg -analyzeduration 2G -probesize 2G \ -i input.vob -vn -sn -c:a copy -map 0:$STREAM_NR output.ext =head1 ADVANCED EXAMPLES @@ -115,7 +115,7 @@ No subscription is necessary to post to the mailing list. =head1 COPYRIGHT -Copyright 2013-2020 all contributors L +Copyright all contributors L License: GPL-3.0+ L @@ -123,4 +123,4 @@ License: GPL-3.0+ L L, L, L, L, L, L, L, -L, L, L, L +L, L, L diff --git a/Documentation/dtas-sourceedit.pod b/Documentation/dtas-sourceedit.pod index 67ecabf..593bcf5 100644 --- a/Documentation/dtas-sourceedit.pod +++ b/Documentation/dtas-sourceedit.pod @@ -51,11 +51,7 @@ of a previous "dtas-ctl source cat sox" invocation: $ dtas-sourceedit sox < saved.yml -To change the way dtas-player calls avconv (part of libav): - - $ dtas-sourceedit av - -To change the way dtas-player calls ffmpeg (lightly-tested): +To change the way dtas-player calls ffmpeg: $ dtas-sourceedit ff @@ -77,7 +73,7 @@ No subscription is necessary to post to the mailing list. =head1 COPYRIGHT -Copyright 2013-2020 all contributors L +Copyright all contributors L License: GPL-3.0+ L diff --git a/lib/dtas/source/av.rb b/lib/dtas/source/av.rb index 39cad6c..e05c695 100644 --- a/lib/dtas/source/av.rb +++ b/lib/dtas/source/av.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require_relative '../../dtas' @@ -13,9 +13,7 @@ class DTAS::Source::Av # :nodoc: 'avconv -v error $SSPOS $PROBE -i "$INFILE" $AMAP -f sox - |' \ 'sox -p $SOXFMT - $TRIMFX $RGFX', - # this is above ffmpeg because this av is the Debian default and - # it's easier for me to test av than ff - "tryorder" => 1, + "tryorder" => 2, ) def initialize diff --git a/lib/dtas/source/av_ff_common.rb b/lib/dtas/source/av_ff_common.rb index 20c9d19..d096aba 100644 --- a/lib/dtas/source/av_ff_common.rb +++ b/lib/dtas/source/av_ff_common.rb @@ -7,10 +7,10 @@ require_relative '../replaygain' require_relative '../xs' require_relative 'file' -# Common code for libav (avconv/avprobe) and ffmpeg (and ffprobe) -# TODO: newer versions of both *probes support JSON, which will be easier to -# parse. However, the packaged libav version in Debian 7.0 does not -# support JSON, so we have an ugly parser... +# Common code for ffmpeg/ffprobe and the abandoned libav (avconv/avprobe). +# TODO: newer versions of both *probes support JSON, which will be easier +# to parse. libav is abandoned, nowadays, and Debian only packages +# ffmpeg+ffprobe nowadays. module DTAS::Source::AvFfCommon # :nodoc: include DTAS::Source::File include DTAS::XS diff --git a/lib/dtas/source/ff.rb b/lib/dtas/source/ff.rb index 687cd18..3d84d99 100644 --- a/lib/dtas/source/ff.rb +++ b/lib/dtas/source/ff.rb @@ -1,12 +1,10 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require_relative '../../dtas' require_relative 'av_ff_common' # ffmpeg support -# note: only tested with the compatibility wrapper in the Debian 7.0 package -# (so still using avconv/avprobe) class DTAS::Source::Ff # :nodoc: include DTAS::Source::AvFfCommon @@ -15,8 +13,7 @@ class DTAS::Source::Ff # :nodoc: 'ffmpeg -v error $SSPOS $PROBE -i "$INFILE" $AMAP -f sox - |' \ 'sox -p $SOXFMT - $TRIMFX $RGFX', - # I haven't tested this much since av is in Debian stable and ff is not - "tryorder" => 2, + "tryorder" => 1, ) def initialize diff --git a/test/test_source_ff.rb b/test/test_source_ff.rb new file mode 100644 index 0000000..e53e72e --- /dev/null +++ b/test/test_source_ff.rb @@ -0,0 +1,102 @@ +# Copyright (C) all contributors +# License: GPL-3.0+ +# frozen_string_literal: true +require './test/helper' +require 'dtas/source/ff' +require 'tempfile' + +class TestSourceFf < Testcase + def teardown + @tempfiles.each(&:close!) + end + + def setup + @tempfiles = [] + end + + def x(cmd) + system(*cmd) + assert $?.success?, cmd.inspect + end + + def new_file(suffix) + tmp = Tempfile.new(%W(tmp .#{suffix})) + @tempfiles << tmp + cmd = %W(sox -r 44100 -b 16 -c 2 -n #{tmp.path} trim 0 1) + return tmp if system(*cmd) + nil + end + + def test_flac + return if `which metaflac`.strip.size == 0 + tmp = new_file('flac') or return + + x(%W(metaflac --set-tag=FOO=BAR #{tmp.path})) + x(%W(metaflac --add-replay-gain #{tmp.path})) + source = DTAS::Source::Ff.new.try(tmp.path) + assert_equal source.comments["FOO"], "BAR", source.inspect + rg = source.replaygain('track_gain') + assert_kind_of DTAS::ReplayGain, rg + assert_in_delta 0.0, rg.track_peak.to_f, 0.00000001 + assert_in_delta 0.0, rg.album_peak.to_f, 0.00000001 + assert_operator rg.album_gain.to_f, :>, 1 + assert_operator rg.track_gain.to_f, :>, 1 + end + + def test_mp3gain + return if `which mp3gain`.strip.size == 0 + a = new_file('mp3') or return + b = new_file('mp3') or return + + # redirect stdout to /dev/null temporarily, mp3gain is noisy + File.open("/dev/null", "w") do |null| + old_out = $stdout.dup + $stdout.reopen(null) + begin + x(%W(mp3gain -q #{a.path} #{b.path})) + ensure + $stdout.reopen(old_out) + old_out.close + end + end + + source = DTAS::Source::Ff.new.try(a.path) + rg = source.replaygain('track_gain') + assert_kind_of DTAS::ReplayGain, rg + assert_in_delta 0.0, rg.track_peak.to_f, 0.00000001 + assert_in_delta 0.0, rg.album_peak.to_f, 0.00000001 + assert_operator rg.album_gain.to_f, :>, 1 + assert_operator rg.track_gain.to_f, :>, 1 + end + + def test_offset + tmp = new_file('flac') or return + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 5s)) + assert_equal 5, source.offset_samples + + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 1:00:00.5)) + expect = 1 * 60 * 60 * 44100 + (44100/2) + assert_equal expect, source.offset_samples + + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 1:10.5)) + expect = 1 * 60 * 44100 + (10 * 44100) + (44100/2) + assert_equal expect, source.offset_samples + + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 10.03)) + expect = (10 * 44100) + (44100 * 3/100.0) + assert_equal expect, source.offset_samples + end + + def test_offset_us + tmp = new_file('flac') or return + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 441s)) + assert_equal 10000.0, source.offset_us + + source = DTAS::Source::Ff.new.try(*%W(#{tmp.path} 22050s)) + assert_equal 500000.0, source.offset_us + + source = DTAS::Source::Ff.new.try(tmp.path, '1') + assert_equal 1000000.0, source.offset_us + end +end if `which ffprobe 2>/dev/null` =~ /ffprobe/ && + `which ffmpeg 2>/dev/null` =~ /ffmpeg/ -- cgit v1.2.3-24-ge0c7