Class: MmTool::MmMovieStream

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

Overview

A stream of an MmMovie. Instances contain simple accessors to the data made available by ffmpeg, and have knowledge on how to generate useful arguments for ffmpeg and mkvpropedit.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream_data:, source_file:, file_number:, streams_ref:, owner_ref:) ⇒ MmMovieStream


Initialize




36
37
38
39
40
41
42
43
# File 'lib/mm_tool/mm_movie_stream.rb', line 36

def initialize(stream_data:, source_file:, file_number:, streams_ref:, owner_ref:)
  @defaults    = MmUserDefaults.shared_user_defaults
  @data        = stream_data
  @source_file = source_file
  @file_number = file_number
  @streams     = streams_ref
  @owner_ref   = owner_ref
end

Instance Attribute Details

#file_numberObject


Attribute accessors




48
49
50
# File 'lib/mm_tool/mm_movie_stream.rb', line 48

def file_number
  @file_number
end

#source_fileObject

Returns the value of attribute source_file.



49
50
51
# File 'lib/mm_tool/mm_movie_stream.rb', line 49

def source_file
  @source_file
end

Class Method Details

.streams(with_files:, owner_ref:) ⇒ Object


Given an array of related files, this class method returns an array of MmMovieStreams reflecting the streams present in each of them.




18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/mm_tool/mm_movie_stream.rb', line 18

def self.streams(with_files:, owner_ref:)
  # Arrays are passed around by reference; when this array is created and
  # used as a reference in each stream, and *also* returned from this class
  # method, everyone will still be using the same reference. It's important
  # below to build up this array without replacing it with another instance.
  streams = []
  with_files.each_with_index do |path, i|
    ff_movie = FFMPEG::Movie.new(path)
    ff_movie.[:streams].each do |stream|
      streams << MmMovieStream.new(stream_data: stream, source_file: path, file_number: i, streams_ref: streams, owner_ref: owner_ref)
    end
  end
  streams
end

Instance Method Details

#action_labelObject


Property - returns a convenient label indicating the

recommended actions for the stream.



183
184
185
# File 'lib/mm_tool/mm_movie_stream.rb', line 183

def action_label
  "#{output_specifier} #{actions.select {|a| a != :interesting}.join(' ')}"
end

#channel_layoutObject


Property - returns the channel layout of the stream.




103
104
105
# File 'lib/mm_tool/mm_movie_stream.rb', line 103

def channel_layout
  @data[:channel_layout]
end

#channelsObject


Property - returns the number of channels of the stream.




96
97
98
# File 'lib/mm_tool/mm_movie_stream.rb', line 96

def channels
  @data[:channels]
end

#codec_nameObject


Property - returns the codec name of the stream.




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

def codec_name
  @data[:codec_name]
end

#codec_typeObject


Property - returns the codec type of the stream.




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

def codec_type
  @data[:codec_type]
end

#coded_heightObject


Property - returns the coded height of the stream.




89
90
91
# File 'lib/mm_tool/mm_movie_stream.rb', line 89

def coded_height
  @data[:coded_height]
end

#coded_widthObject


Property - returns the coded width of the stream.




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

def coded_width
  @data[:coded_width]
end

#copy?Boolean


Property - stream action includes :copy?


Returns:

  • (Boolean)


220
221
222
# File 'lib/mm_tool/mm_movie_stream.rb', line 220

def copy?
  actions.include?(:copy)
end

#copy_only?Boolean


Property - Is the stream copy only? No other modifications?


Returns:

  • (Boolean)


227
228
229
# File 'lib/mm_tool/mm_movie_stream.rb', line 227

def copy_only?
  (actions - [:copy, :interesting]).empty?
end

#default?Boolean


Property - indicates whether or not the stream is the

default stream per its dispositions.

Returns:

  • (Boolean)


191
192
193
# File 'lib/mm_tool/mm_movie_stream.rb', line 191

def default?
  @data[:disposition][:default] == 1
end

#dispositionsObject


Property - returns the disposition flags of the stream as

a comma-separated list for compactness.



145
146
147
148
149
# File 'lib/mm_tool/mm_movie_stream.rb', line 145

def dispositions
  MmMovie.dispositions
      .collect {|symbol| @data[:disposition][symbol]}
      .join(',')
end

#drop?Boolean


Property - stream action includes :drop?


Returns:

  • (Boolean)


213
214
215
# File 'lib/mm_tool/mm_movie_stream.rb', line 213

def drop?
  actions.include?(:drop)
end

#indexObject


Property - returns the index of the stream.




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

def index
  @data[:index]
end

#input_specifierObject


Property - returns the input specifier of the stream.




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

def input_specifier
  "#{@file_number}:#{index}"
end

#instruction_actionObject


Property - returns an instruction for handling the stream,

according to the action(s) determined.



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/mm_tool/mm_movie_stream.rb', line 310

def instruction_action
  if copy?
    "-codec:#{output_specifier} copy \\"
  elsif transcode?
    if codec_type == 'audio'
      encode_to = @defaults[:codecs_audio_preferred][0]
    elsif codec_type == 'video'
      encode_to = @defaults[:codecs_video_preferred][0]
    else
      raise Exception.new "Error: somehow the program branched where it shouldn't have."
    end
    "-codec:#{output_specifier} #{encoder_string(for_codec: encode_to)} \\"
  else
    nil
  end
end

#instruction_dispositionObject


Property - returns an instruction for setting the stream’s

default disposition, if necessary.



354
355
356
357
358
359
360
361
362
# File 'lib/mm_tool/mm_movie_stream.rb', line 354

def instruction_disposition
  set_disposition = output_unique? && !default? && !drop? ? "default " : nil

  if set_disposition
    "-disposition:#{output_specifier} #{set_disposition}\\"
  else
    nil
  end
end

#instruction_inputObject


Property - returns the -i input instruction for this

stream.



289
290
291
292
293
294
295
296
# File 'lib/mm_tool/mm_movie_stream.rb', line 289

def instruction_input
  src = if @file_number == 0
          File.join(File.dirname(@source_file), File.basename(@source_file, '.*') + @defaults[:suffix] + File.extname(@source_file))
        else
          @source_file
        end
  "-i \"#{src}\" \\"
end

#instruction_mapObject


Property - returns the -map instruction for this stream,

according to the action(s) determined.



302
303
304
# File 'lib/mm_tool/mm_movie_stream.rb', line 302

def instruction_map
  drop? ? nil : "-map #{input_specifier} \\"
end

#instruction_metadataObject


Property - returns instructions for setting the metadata

of the stream, if necessary.



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/mm_tool/mm_movie_stream.rb', line 331

def 
  return [] if @actions.include?(:drop)

  # We only want to set fixed_lang if options allow us to fix the language,
  # and we want to set subtitle language from the filename, if applicable.
  fixed_lang = @defaults[:fix_undefined_language] ? @defaults[:undefined_language] : nil
  lang = subtitle_file_language ? subtitle_file_language : fixed_lang

  result = []
  result << "-metadata:s:#{output_specifier} language=#{lang} \\" if set_language?
  result << "-metadata:s:#{output_specifier} title=\"#{title}\" \\" if title  && ! @defaults[:ignore_titles]

  if @defaults[:containers_preferred][0].downcase == 'mkv'
    result << "-metadata:s:#{output_specifier} MM_TOOL_ENCODED_STREAM=\"true\" \\" if @actions.include?(:transcode)
  end

  result
end

#interesting?Boolean


Property - stream action includes :interesting?


Returns:

  • (Boolean)


248
249
250
# File 'lib/mm_tool/mm_movie_stream.rb', line 248

def interesting?
  actions.include?(:interesting)
end

#languageObject


Property - returns the language of the stream, or ‘und’

if the language is not defined.



111
112
113
114
115
116
117
118
119
120
# File 'lib/mm_tool/mm_movie_stream.rb', line 111

def language
  if @data.key?(:tags)
    lang = @data[:tags][:language]
    lang = @data[:tags][:LANGUAGE] unless lang
    lang = 'und' unless lang
  else
    lang = 'und'
  end
  lang
end

#low_quality?Boolean


Property - indicates whether or not the stream is

considered "low quality" based on the application
configuration.

Returns:

  • (Boolean)


200
201
202
203
204
205
206
207
208
# File 'lib/mm_tool/mm_movie_stream.rb', line 200

def low_quality?
  if codec_type == 'audio'
    channels.to_i < @defaults[:min_channels].to_i
  elsif codec_type == 'video'
    coded_width.to_i < @defaults[:min_width].to_i
  else
    false
  end
end

#mm_tool_encoded_streamObject


Property - returns the metadata indicating whether or not

mm_tool has previously encoded this stream.



126
127
128
# File 'lib/mm_tool/mm_movie_stream.rb', line 126

def mm_tool_encoded_stream
  @data&.dig(:tags, :MM_TOOL_ENCODED_STREAM)&.downcase == 'true'
end

#one_of_a_kind?Boolean


Property - indicates whether or not this stream is the

only one of its type.

Returns:

  • (Boolean)


264
265
266
# File 'lib/mm_tool/mm_movie_stream.rb', line 264

def one_of_a_kind?
  @streams.count {|s| s.codec_type  == codec_type && s != self } == 0
end

#output_indexObject


Property - returns the index of the stream in the output

file.



272
273
274
# File 'lib/mm_tool/mm_movie_stream.rb', line 272

def output_index
  @streams.select {|s| !s.drop? }.index(self)
end

#output_specifierObject


Property - returns a specific output specifier for the

stream, such as v:0 or a:2.



280
281
282
283
# File 'lib/mm_tool/mm_movie_stream.rb', line 280

def output_specifier
  idx = @streams.select {|s| s.codec_type == codec_type && !s.drop?}.index(self)
  idx ? "#{codec_type[0]}:#{idx}" : ''
end

#output_unique?Boolean


Property - indicates whether or not the stream will be

unique for its type at output.

Returns:

  • (Boolean)


256
257
258
# File 'lib/mm_tool/mm_movie_stream.rb', line 256

def output_unique?
  @streams.count {|s| s.codec_type  == codec_type && !s.drop? } == 1
end

#quality_01Object


Property - returns an appropriate “quality” indicator

based on the type of the stream.



155
156
157
158
159
160
161
162
163
# File 'lib/mm_tool/mm_movie_stream.rb', line 155

def quality_01
  if codec_type == 'audio'
    channels
  elsif codec_type == 'video'
    coded_width
  else
    nil
  end
end

#quality_02Object


Property - returns a different appropriate “quality”

indicator based on the type of the stream.



169
170
171
172
173
174
175
176
177
# File 'lib/mm_tool/mm_movie_stream.rb', line 169

def quality_02
  if codec_type == 'audio'
    channel_layout
  elsif codec_type == 'video'
    coded_height
  else
    nil
  end
end

#set_language?Boolean


Property - stream action includes :set_language?


Returns:

  • (Boolean)


241
242
243
# File 'lib/mm_tool/mm_movie_stream.rb', line 241

def set_language?
  actions.include?(:set_language)
end

#titleObject


Property - returns the title of the stream, or nil.




133
134
135
136
137
138
139
# File 'lib/mm_tool/mm_movie_stream.rb', line 133

def title
  if @data.key?(:tags)
    @data[:tags][:title]
  else
    nil
  end
end

#transcode?Boolean


Property - stream action includes :transcode?


Returns:

  • (Boolean)


234
235
236
# File 'lib/mm_tool/mm_movie_stream.rb', line 234

def transcode?
  actions.include?(:transcode)
end