From 70b81da26a525486c288176e5764c875c752d0b8 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 25 Jan 2016 01:03:18 +0000 Subject: mlib: support all formats of player Almost, we will need to get a list of all suffixes supported by ffprobe or avprobe. This could prove tricky.. --- lib/dtas/mlib.rb | 36 +++++++++++++++++++++--------------- lib/dtas/source/av_ff_common.rb | 1 + lib/dtas/source/sox.rb | 4 ++++ lib/dtas/source/splitfx.rb | 4 ++++ 4 files changed, 30 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/dtas/mlib.rb b/lib/dtas/mlib.rb index 1f61369..3bfed8f 100644 --- a/lib/dtas/mlib.rb +++ b/lib/dtas/mlib.rb @@ -5,6 +5,10 @@ # require_relative '../dtas' require_relative 'process' +require_relative 'source/sox' +require_relative 'source/av' +require_relative 'source/ff' +require_relative 'source/splitfx' require 'socket' # For the DTAS Music Library, based on what MPD uses. @@ -53,12 +57,18 @@ class DTAS::Mlib # :nodoc: @tag_map = nil @suffixes = nil @work = nil + @sources = [ # order matters + (sox = DTAS::Source::Sox.new), + DTAS::Source::Av.new, + DTAS::Source::Ff.new, + DTAS::Source::SplitFX.new(sox), + ] end def init_suffixes `sox --help 2>/dev/null` =~ /\nAUDIO FILE FORMATS:\s*([^\n]+)/s re = $1.split(/\s+/).map { |x| Regexp.quote(x) }.join('|') - @suffixes = Regexp.new("\\.(?:#{re})\\z", Regexp::IGNORECASE) + @suffixes = Regexp.new("\\.(?:#{re}|yml)\\z", Regexp::IGNORECASE) end def worker(todo) @@ -89,22 +99,17 @@ class DTAS::Mlib # :nodoc: Dir.chdir(wd) @pwd = wd end - tmp = {} path = job.path - tlen = qx(%W(soxi -D #{path}), no_raise: true) - return ignore(job) unless String === tlen - tlen = tlen.to_f + found = nil + @sources.each do |src| + found = src.try(path) and break + end + return ignore(job) unless found + tlen = found.duration return ignore(job) if tlen < 0 tlen = tlen.round - buf = qx(%W(soxi -a #{path}), no_raise: true) - return ignore(job) unless String === buf - - # no, we don't support comments with newlines in them - buf = buf.split("\n") - while line = buf.shift - tag, value = line.split('=', 2) - tag && value or next - tag.downcase! + tmp = {} + found.comments.each do |tag, value| tag_id = @tag_map[tag] or next value.strip! @@ -183,6 +188,8 @@ class DTAS::Mlib # :nodoc: %w(track disc).each do |x| tag_id = tag_map[x] and tag_map["#{x}number"] = tag_id end + @tag_rmap = tag_map.invert.freeze + tag_map.merge!(Hash[*(tag_map.map { |k,v| [k.upcase.freeze, v] }.flatten!)]) @tag_map = tag_map.freeze end @@ -354,7 +361,6 @@ class DTAS::Mlib # :nodoc: # success load_tags - @tag_rmap = @tag_map.invert if found[:tlen] == DM_DIR emit_recurse(found, cache, cb) else diff --git a/lib/dtas/source/av_ff_common.rb b/lib/dtas/source/av_ff_common.rb index 0fb3ace..58d9f54 100644 --- a/lib/dtas/source/av_ff_common.rb +++ b/lib/dtas/source/av_ff_common.rb @@ -19,6 +19,7 @@ module DTAS::Source::AvFfCommon # :nodoc: attr_reader :precision # always 32 attr_reader :format + attr_reader :duration def try(infile, offset = nil, trim = nil) rv = source_file_dup(infile, offset, trim) diff --git a/lib/dtas/source/sox.rb b/lib/dtas/source/sox.rb index 9d128a6..db1ace2 100644 --- a/lib/dtas/source/sox.rb +++ b/lib/dtas/source/sox.rb @@ -53,6 +53,10 @@ class DTAS::Source::Sox # :nodoc: @format ||= DTAS::Format.from_file(@env, @infile) end + def duration + samples / format.rate.to_f + end + # This is the number of samples according to the samples in the source # file itself, not the decoded output def samples diff --git a/lib/dtas/source/splitfx.rb b/lib/dtas/source/splitfx.rb index d824959..f746bee 100644 --- a/lib/dtas/source/splitfx.rb +++ b/lib/dtas/source/splitfx.rb @@ -107,6 +107,10 @@ class DTAS::Source::SplitFX < DTAS::Source::Sox # :nodoc: @sox.samples end + def duration + @sox.duration + end + def source_defaults SPLITFX_DEFAULTS end -- cgit v1.2.3-24-ge0c7