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)
  @format_metadata = 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.




158
159
160
161
162
# File 'lib/mm_tool/mm_movie.rb', line 158

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




196
197
198
# File 'lib/mm_tool/mm_movie.rb', line 196

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.




169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/mm_tool/mm_movie.rb', line 169

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

  if @defaults[:containers_preferred][0].downcase == 'mkv'
    command << "   -metadata MM_TOOL_ENCODED=\"true\" \\" if @streams.count {|stream| stream.transcode?} > 0
    command << "   -metadata MM_TOOL_WRITTEN=\"true\" \\" if modify_streams?
  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 = @format_metadata[: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 = @format_metadata[:duration]
  seconds ? Time.at(seconds.to_i).utc.strftime("%H:%M:%S") : nil
end

#format_mm_tool_encodedObject


Get the file-level ‘MM_TOOL_ENCODED’ metadata.




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

def format_mm_tool_encoded
  @format_metadata&.dig(:tags, :MM_TOOL_ENCODED)&.downcase == 'true'
end

#format_mm_tool_writtenObject


Get the file-level ‘MM_TOOL_WRITTEN’ metadata.




82
83
84
# File 'lib/mm_tool/mm_movie.rb', line 82

def format_mm_tool_written
  @format_metadata&.dig(:tags, :MM_TOOL_WRITTEN)&.downcase == 'true'
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 = @format_metadata[:size]
  size ? ByteSize.new(size) : 'unknown'
end

#format_tableObject


Get the rendered text of the format_table.




125
126
127
128
129
130
131
132
133
134
135
# File 'lib/mm_tool/mm_movie.rb', line 125

def format_table
  unless @format_table
    @format_table = format_table_datasource.render(:basic) do |renderer|
      renderer.column_widths = [10,10,10,12,10,123]
      renderer.multiline     = true
      renderer.padding       = [0,1]
      renderer.width         = 192
    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
  @format_metadata&.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)


90
91
92
# File 'lib/mm_tool/mm_movie.rb', line 90

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)


106
107
108
# File 'lib/mm_tool/mm_movie.rb', line 106

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)


98
99
100
101
# File 'lib/mm_tool/mm_movie.rb', line 98

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

#modify_streams?Boolean


Indicates whether any of the streams are to be modified in any form.


Returns:

  • (Boolean)


114
115
116
117
118
119
120
# File 'lib/mm_tool/mm_movie.rb', line 114

def modify_streams?
  number_of_copy_only = @streams.count {|stream| stream.copy_only?}
  number_of_streams = @streams.count
  number_of_streams > number_of_copy_only
  # result = @streams.count {|stream| stream.copy_only?} < @streams.count
  # result
end

#raw_bitrateObject


Get the file-level ‘bitrate’ metadata.




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

def raw_bitrate
  @format_metadata[:bit_rate].to_i
end

#stream_tableObject


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




141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/mm_tool/mm_movie.rb', line 141

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, :left]
      renderer.column_widths = [5,10,10,5,10,5,23,50,8,35]
      renderer.multiline     = true
      renderer.padding       = [0,1]
      renderer.width         = 192
    end # do
  end
  @stream_table
end