Class: MmTool::MmMovie

Inherits:
Object
  • Object
show all
Defined in:
lib/mm_tool/mm_movie.rb

Overview

A movie as a self contained class. Instances of this class consist of one or more MmMovieStream instances, and contains intelligence about itself so that it can provide commands to ffmpeg and/or mkvpropedit as required. Upon creation it must be provided with a filename.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(with_file:) ⇒ MmMovie


Initialize




28
29
30
31
32
# File 'lib/mm_tool/mm_movie.rb', line 28

def initialize(with_file:)
  @defaults        = MmUserDefaults.shared_user_defaults
  @streams         = MmMovieStream::streams(with_files: all_paths(with_file: with_file), owner_ref: self)
   = FFMPEG::Movie.new(with_file).[:format]
end

Class Method Details

.dispositionsObject


This class method returns the known dispositions supported by ffmpeg. This array also reflects the output orders in the dispositions table field. Not combining them would result in a too-long table row.




21
22
23
# File 'lib/mm_tool/mm_movie.rb', line 21

def self.dispositions
  i(default dub original comment lyrics karaoke forced hearing_impaired visual_impaired clean_effects attached_pic timed_thumbnails)
end

Instance Method Details

#command_renameObject


The complete command to rename the main input file to include a tag indicating that it’s the original.




132
133
134
135
136
# File 'lib/mm_tool/mm_movie.rb', line 132

def command_rename
  src = @streams[0].source_file
  dst = File.join(File.dirname(src), File.basename(src, '.*') + @defaults[:suffix] + File.extname(src))
  "mv \"#{src}\" \"#{dst}\""
end

#command_review_postObject


The complete command to view the output file after running the transcode command




165
166
167
# File 'lib/mm_tool/mm_movie.rb', line 165

def command_review_post
  "\"#{$0}\" -is --no-use-external-subs \"#{output_path}\""
end

#command_transcodeObject


The complete, proposed ffmpeg command to transcode the input file to an output file. It uses the ‘new_input_path’ as the input file.




143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/mm_tool/mm_movie.rb', line 143

def command_transcode
  command = ["ffmpeg \\"]
  command << "   -hide_banner \\"
  command << "   -loglevel error \\"
  command << "   -stats \\"
  @streams.each {|stream| command |= ["   #{stream.instruction_input}"] if stream.instruction_input }
  @streams.each {|stream| command << "   #{stream.instruction_map}" if stream.instruction_map }
  @streams.each {|stream| command << "   #{stream.instruction_action}" if stream.instruction_action }
  @streams.each {|stream| command << "   #{stream.instruction_disposition}" if stream.instruction_disposition }
  @streams.each do |stream|
    stream..each { |instruction| command << "   #{instruction}" }
  end

  command << "   -metadata title=\"#{format_title}\" \\" if format_title
  command << "   \"#{output_path}\""
  command.join("\n")
end

#format_bitrateObject


Get the file-level ‘bitrate’ metadata.




53
54
55
56
# File 'lib/mm_tool/mm_movie.rb', line 53

def format_bitrate
  size = [:bit_rate]
  ByteSize.new(size).to_kb.to_i.to_s + "K"
end

#format_durationObject


Get the file-level ‘duration’ metadata.




37
38
39
40
# File 'lib/mm_tool/mm_movie.rb', line 37

def format_duration
  seconds = [:duration]
  seconds ? Time.at(seconds.to_i).utc.strftime("%H:%M:%S") : nil
end

#format_sizeObject


Get the file-level ‘size’ metadata.




45
46
47
48
# File 'lib/mm_tool/mm_movie.rb', line 45

def format_size
  size = [:size]
  size ? ByteSize.new(size) : 'unknown'
end

#format_tableObject


Get the rendered text of the format_table.




99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mm_tool/mm_movie.rb', line 99

def format_table
  unless @format_table
    @format_table = format_table_datasource.render(:basic) do |renderer|
      renderer.column_widths = [10,10,10,160]
      renderer.multiline     = true
      renderer.padding       = [0,1]
      renderer.width         = 1000
    end
  end
  @format_table
end

#format_titleObject


Get the file-level ‘title’ metadata.




68
69
70
# File 'lib/mm_tool/mm_movie.rb', line 68

def format_title
  &.dig(:tags, :title)
end

#has_low_quality_streams?Boolean


Indicates whether any of the streams are of a lower quality than desired by the user.


Returns:

  • (Boolean)


76
77
78
# File 'lib/mm_tool/mm_movie.rb', line 76

def has_low_quality_streams?
  @streams.count {|stream| stream.low_quality?} > 0
end

#interesting?Boolean


Indicates whether any of the streams are interesting.


Returns:

  • (Boolean)


92
93
94
# File 'lib/mm_tool/mm_movie.rb', line 92

def interesting?
  @streams.count {|stream| stream.interesting?} > 0 || format_title
end

#meets_minimum_quality?Boolean


Indicates whether or not a file has at least one high- quality video stream and high-quality audio stream.


Returns:

  • (Boolean)


84
85
86
87
# File 'lib/mm_tool/mm_movie.rb', line 84

def meets_minimum_quality?
  @streams.count {|stream| stream.codec_type == 'audio' && !stream.low_quality? } > 0 &&
      @streams.count {|stream| stream.codec_type == 'video' && !stream.low_quality? } > 0
end

#raw_bitrateObject


Get the file-level ‘bitrate’ metadata.




61
62
63
# File 'lib/mm_tool/mm_movie.rb', line 61

def raw_bitrate
  [:bit_rate].to_i
end

#stream_tableObject


For the given table, get the rendered text of the table for output.




115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/mm_tool/mm_movie.rb', line 115

def stream_table
  unless @stream_table
    @stream_table = stream_table_datasource.render(:unicode) do |renderer|
      renderer.alignments    = [:center, :left, :left, :right, :right, :left, :left, :left, :left]
      renderer.column_widths = [5,10,10,5,10,5,23,50,35]
      renderer.multiline     = true
      renderer.padding       = [0,1]
      renderer.width         = 1000
    end # do
  end
  @stream_table
end