diff options
Diffstat (limited to 'lib/dtas/source')
-rw-r--r-- | lib/dtas/source/av.rb | 49 | ||||
-rw-r--r-- | lib/dtas/source/sox.rb | 4 |
2 files changed, 38 insertions, 15 deletions
diff --git a/lib/dtas/source/av.rb b/lib/dtas/source/av.rb index 804a66b..1de0a72 100644 --- a/lib/dtas/source/av.rb +++ b/lib/dtas/source/av.rb @@ -11,9 +11,12 @@ class DTAS::Source::Av # :nodoc: include DTAS::Source::File + AStream = Struct.new(:duration, :channels, :rate) + AV_DEFAULTS = COMMAND_DEFAULTS.merge( "command" => - 'avconv -v error $SSPOS -i "$INFILE" -f sox - | sox -p $SOXFMT - $RGFX', + 'avconv -v error $SSPOS -i "$INFILE" $AMAP -f sox - |' \ + 'sox -p $SOXFMT - $RGFX', "comments" => nil, ) @@ -42,24 +45,23 @@ class DTAS::Source::Av # :nodoc: @comments = {} err = "" s = qx(%W(avprobe -show_streams -show_format #@infile), err: err) + @astreams = [] s.scan(%r{^\[STREAM\]\n(.*?)\n\[/STREAM\]\n}m) do |_| stream = $1 # XXX what to do about multiple streams? if stream =~ /^codec_type=audio$/ - duration = channels = rate = nil - stream =~ /^duration=([\d\.]+)\s*$/m and duration = $1.to_f - stream =~ /^channels=(\d)\s*$/m and channels = $1.to_i - stream =~ /^sample_rate=([\d\.]+)\s*$/m and rate = $1.to_i - if channels > 0 && rate > 0 - @duration = duration - @format.channels = channels - @format.rate = rate - end + as = AStream.new + index = nil + stream =~ /^index=(\d+)\s*$/m and index = $1.to_i + stream =~ /^duration=([\d\.]+)\s*$/m and as.duration = $1.to_f + stream =~ /^channels=(\d)\s*$/m and as.channels = $1.to_i + stream =~ /^sample_rate=([\d\.]+)\s*$/m and as.rate = $1.to_i + @astreams[index] = as if as.channels > 0 && as.rate > 0 end end s.scan(%r{^\[FORMAT\]\n(.*?)\n\[/FORMAT\]\n}m) do |_| f = $1 - f =~ /^duration=([\d\.]+)\s*$/m and @duration ||= $1.to_f + f =~ /^duration=([\d\.]+)\s*$/m and @duration = $1.to_f # TODO: multi-line/multi-value/repeated tags f.gsub!(/^TAG:([^=]+)=(.*)$/i) { |_| @comments[$1.upcase] = $2 } end @@ -71,10 +73,31 @@ class DTAS::Source::Av # :nodoc: sprintf("-ss %0.9g", samples / @format.rate) end - def spawn(format, rg_state, opts) + def spawn(player_format, rg_state, opts) raise "BUG: #{self.inspect}#spawn called twice" if @to_io - e = @format.to_env + amap = nil + found_as = nil + + # try to find an audio stream which matches our channel count + # we need to set @format for sspos() down below + @astreams.each_with_index do |as, index| + if as && as.channels == player_format.channels + @format.channels = as.channels + @format.rate = as.rate + found_as = as + amap = "-map 0:#{index}" + end + end + unless found_as + first_as = @astreams.compact[0] + if first_as + @format.channels = found_as.channels + @format.rate = found_as.rate + end + end + e = player_format.to_env e["INFILE"] = @infile + e["AMAP"] = amap # make sure these are visible to the "current" command... @env["SSPOS"] = @offset ? sspos(@offset) : nil diff --git a/lib/dtas/source/sox.rb b/lib/dtas/source/sox.rb index 954c1a5..235cbbc 100644 --- a/lib/dtas/source/sox.rb +++ b/lib/dtas/source/sox.rb @@ -86,9 +86,9 @@ class DTAS::Source::Sox # :nodoc: tmp end - def spawn(format, rg_state, opts) + def spawn(player_format, rg_state, opts) raise "BUG: #{self.inspect}#spawn called twice" if @to_io - e = format.to_env + e = player_format.to_env e["INFILE"] = @infile # make sure these are visible to the "current" command... |