Class: VTools::Converter

Inherits:
Object
  • Object
show all
Includes:
SharedMethods
Defined in:
lib/vtools/converter.rb

Overview

Video converter itself

Instance Method Summary collapse

Methods included from SharedMethods

included

Methods included from SharedMethods::Common

#config, #fix_encoding, #generate_path, #hash_to_obj, #json_to_obj, #keys_to_sym, #log, #logger=, #network_call, #parse_json, #path_generator

Constructor Details

#initialize(video) ⇒ Converter

Returns a new instance of Converter.



9
10
11
# File 'lib/vtools/converter.rb', line 9

def initialize video
  @video = video
end

Instance Method Details

#encodedObject

encoded media



91
92
93
# File 'lib/vtools/converter.rb', line 91

def encoded
  @encoded ||= Video.new(@output_file).get_info
end

#encoding_invalid?Boolean

define if encoded succeed

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/vtools/converter.rb', line 68

def encoding_invalid?
  unless File.exists?(@output_file)
    return "No output file created"
  end

  unless encoded.valid?
    return "Encoded file is invalid"
  end

  if CONFIG[:validate_duration]
    # reavalidate duration
    precision = @options[:duration] ? 1.5 : 1.1
    desired_duration = @options[:duration] && @options[:duration] < @video.duration ? @options[:duration] : @video.duration

    if (encoded.duration >= (desired_duration * precision) or encoded.duration <= (desired_duration / precision))
      return "Encoded file duration is invalid (original/specified: #{desired_duration}sec, got: #{encoded.duration}sec)"
    end
  end

  false
end

#runObject

ffmpeg converter cicle

ffmpeg < 0.8: frame= 413 fps= 48 q=31.0 size= 2139kB time=16.52 bitrate=1060.6kbits/s ffmpeg >= 0.8: frame= 485 fps= 46 q=31.0 size= 45306kB time=00:02:42.28 bitrate=2287.0kbits/

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/vtools/converter.rb', line 18

def run

  @options = @video.convert_options
  @output_file = "#{generate_path @video.name}/#{@video.name}#{@options[:postfix]}.#{@options[:extension]}"

  command = "#{CONFIG[:ffmpeg_binary]} -y -i '#{@video.path}' #{@options} '#{@output_file}'"
  output = ""
  convert_error = true

  # before convert callbacks
  Hook.exec :before_convert, @video, command

  # process video
  Open3.popen3(command) do |stdin, stdout, stderr|
    stderr.each "r" do |line|
      VTools.fix_encoding line
      output << line

      # we know, that all is not so bad, if "time=" at least once met
      if line.include? "time="

        convert_error = false # that is why, we say "generally it's OK"

        if line =~ /time=(\d+):(\d+):(\d+.\d+)/ # ffmpeg 0.8 and above style
          time = ($1.to_i * 3600) + ($2.to_i * 60) + $3.to_f
        elsif line =~ /time=(\d+.\d+)/ # ffmpeg 0.7 and below style
          time = $1.to_f
        else # in case of unexpected output
          time = 0.0
        end
        progress = time / @video.duration
        Hook.exec :in_convert, @video, progress # callbacks
      end
    end
  end

  raise ProcessError, output.split("\n").last if convert_error # exit on error

  # callbacks
  unless error = encoding_invalid?
    Hook.exec :convert_success, @video, @output_file
  else
    Hook.exec :convert_error, @video, error, output
    raise ProcessError, error # raise exception in error
  end

  encoded
end