Class: Dvdvrconv::Dvdvr

Inherits:
Object
  • Object
show all
Defined in:
lib/dvdvrconv/dvdvr.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDvdvr

Returns a new instance of Dvdvr.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/dvdvrconv/dvdvr.rb', line 47

def initialize
  @vrdisc = Vrdisc.new(nil)

  if RUBY_PLATFORM =~ /mswin(?!ce)|mingw|cygwin/
    @vrdisc.opts_ifo = Dvdvrconv::WIN_DRV_IFO
    @vrdisc.opts_vro = Dvdvrconv::WIN_DRV_VRO
    @vrdisc.cmd = Dvdvrconv::WIN_DRV_CMD
  else
    @vrdisc.opts_ifo = Dvdvrconv::DRV_IFO
    @vrdisc.opts_vro = Dvdvrconv::DRV_VRO
    @vrdisc.cmd = Dvdvrconv::DRV_CMD
  end

  @vrdisc.default_opts_ifo = @vrdisc.opts_ifo
  @vrdisc.default_opts_vro = @vrdisc.opts_vro
  @vrdisc.default_cmd = @vrdisc.cmd
  @vrdisc.concat_mode = Dvdvrconv::DEFAULT_CONCAT_MODE
  @vrdisc.hardware_encode = Dvdvrconv::DEFAULT_HARDWARE_ENCODE
  @vrdisc.global_quality = Dvdvrconv::DEFAULT_GLOBAL_QUALITY
  @vrdisc.h264_crf = Dvdvrconv::DEFAULT_H264_CRF
end

Instance Attribute Details

#vrdiscObject

Returns the value of attribute vrdisc.



45
46
47
# File 'lib/dvdvrconv/dvdvr.rb', line 45

def vrdisc
  @vrdisc
end

Instance Method Details

#adjust_titleObject

Add sequence number to the duplicate title name. Replace white space in the title with underscore.

required value:

@vrdisc.title

Output values:

=> @vrdisc.duplicate_name
=> @vrdisc.output_title


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/dvdvrconv/dvdvr.rb', line 166

def adjust_title
  output_title = []
  duplicate_names = []
  dup_counter = 0

  # Extract duplicate names from title.
  dup = @vrdisc.title.select { |x| @vrdisc.title.count(x) > 1 }

  @vrdisc.title.each_index do |idx|
    # Replace white space in the title with underscore.
    new_name = @vrdisc.title[idx][0].gsub(/\s/, "_")

    # Add sequential numbers to duplicate name.
    if dup.include?(@vrdisc.title[idx])
      dup_counter += 1
      output_title << format('%s_%02d', new_name, dup_counter)
      duplicate_names << new_name
    else
      output_title << format('%s', new_name)
    end
    dup_counter = 0 if dup_counter == @vrdisc.title.count(@vrdisc.title[idx])
  end

  @vrdisc.duplicate_name = duplicate_names.select do |x|
    duplicate_names.count(x) > 1
  end.uniq

  @vrdisc.output_title = output_title
end

#change_to_title_nameObject

Change the file name to the title name

required value:

@vrdisc.title

Output values:

=> @vrdisc.vob_titles


213
214
215
216
217
218
219
220
221
222
223
# File 'lib/dvdvrconv/dvdvr.rb', line 213

def change_to_title_name
  vob_titles = []

  @vrdisc.title.size.times do |x|
    src = format('%s#%03d', Dvdvrconv::BASE_NAME, x + 1) + '.vob'
    dst = @vrdisc.output_title[x] + '.vob'
    vob_titles << [src, dst]
  end

  @vrdisc.vob_titles = vob_titles
end

#concat_titles(concat_list) ⇒ Object

Concatenate Split Titles. This method uses FFmpeg's media file concatenation feature.

required Argument:

concat_list

concat_list is Array. Includes file_name, contents, base_name.

concat_list = [[file_name, contents, base_name], [file_name, contents, base_name]. .... ]

Parameters:

  • file_name (String)

    concat list name.

  • contents (String)

    concatenate file names.

  • base_name (String)

    output vob name.



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/dvdvrconv/dvdvr.rb', line 348

def concat_titles(concat_list)
  puts '----- Concatenate Split Titles -----'
  concat_list.each do |list|
    file_name, contents, base_name = list
    File.write(file_name, contents)
    puts "concat list= #{file_name}"

    cmd = str_concat_cmd(file_name, base_name)
    puts '----- concat vob files -----'
    puts "run cmd:\n  #{cmd.join(' ')}"
    system(*cmd)

    begin
      File.delete(file_name)
    rescue
      p $!
    end
  end
end

#customize_title(base_dst_name, number_list = []) ⇒ Object

customize the title of vob files.

If specify individual file names. Write "base_dst_name" as an Array.

base_dst_name = ["name_one", "name_two"]
number_list = []
=> ["name_one", "name_two"]

If add a sequence number to the file name. Write "base_dst_name" as String.

base_dst_name = "output_name_"
number_list = []
=> ["output_name_01", "output_name_02", ...]

If specify sequence numbers individually. Write "base_dst_name" as String and Write "number_list" as an Array.

base_dst_name = "output_name_"
number_list = [12, 13, 14, 15]
=> ["output_name_12", "output_name_13", "output_name_14", "output_name_15"]

required Argument, value:

base_dst_name, number_list,
@vrdisc.title

Output values:

=> @vrdisc.vob_titles


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/dvdvrconv/dvdvr.rb', line 253

def customize_title(base_dst_name, number_list = [])
  vob_titles = []

  if @vrdisc.concat_mode == true
    titels = @vrdisc.title.uniq.flatten
  else
    titels = @vrdisc.output_title
  end

  titels.each_with_index do |title, idx|
    src = title.gsub(/\s/, '_') + '.vob'

    case base_dst_name
    when Array
      dst_name = base_dst_name[idx]
    when String
      if number_list.size.zero?
        dst_name = base_dst_name + format('_%02d', idx + 1)
      else
        case number_list[idx]
        when Numeric
          dst_name = base_dst_name + format('_%02d', number_list[idx])
        when String
          dst_name = base_dst_name + format('_%s', number_list[idx])
        end
      end
    end

    dst = dst_name + '.vob'
    vob_titles << [src, dst]
  end

  @vrdisc.vob_titles = vob_titles
end

#debug_view_vrdiscObject



400
401
402
403
404
# File 'lib/dvdvrconv/dvdvr.rb', line 400

def debug_view_vrdisc
  @vrdisc.members.each do |member|
    puts "#{member} => #{@vrdisc[member]}"
  end
end

#ffmeg_normal_cmd(file_name) ⇒ Object

File convert command, vob to mp4 for FFmpeg.

  • Change the aspect ratio to 16:9.
  • Delete a closed caption.
  • Use deinterlace (bwdif)
  • Use Constant Rate Factor mode insted of CBR mode
  • Use analyze and probe option


85
86
87
# File 'lib/dvdvrconv/dvdvr.rb', line 85

def ffmeg_normal_cmd(file_name)
  Shellwords.shellsplit(%(ffmpeg -analyzeduration 2000M -probesize 2G -i "#{file_name}.vob" -vf "bwdif=0:-1:0,crop=704:474:0:0,scale=704:480,setdar=16/9" -c:v libx264 -crf "#{@vrdisc.h264_crf}" -preset medium -bsf:v "filter_units=remove_types=6" -map 0:v:0 -map 0:a:0 -c:a copy "#{file_name}.mp4"))
end

#ffmpeg_qsv_cmd(file_name) ⇒ Object

File convert command, vob to mp4 for FFmpeg.

  • FFmpeg with QSV(Intel Quick Sync Video)
  • Change the aspect ratio to 16:9.
  • Delete a closed caption.
  • Support for FFmpeg 8
  • Software decode, cropp and deinterlace + h264 qsv(LA_ICQ) encode
  • Use ICQ Look_ahead mode
  • Use analyze and probe option


97
98
99
# File 'lib/dvdvrconv/dvdvr.rb', line 97

def ffmpeg_qsv_cmd(file_name)
  Shellwords.shellsplit(%(ffmpeg -analyzeduration 2000M -probesize 2G -i "#{file_name}.vob" -vf "bwdif=0:-1:0,crop=704:474:0:0,scale=704:480,setdar=16/9" -c:v h264_qsv -global_quality "#{@vrdisc.global_quality}" -look_ahead 1 -look_ahead_depth 30 -aspect 16:9 -bsf:v "filter_units=remove_types=6" -map 0:v:0 -map 0:a:0 -c:a copy "#{file_name}.mp4"))
end

#make_concat_listObject

Make a list of file names to concatenate.

required values:

@vrdisc.duplicate_name, @vrdisc.output_title


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/dvdvrconv/dvdvr.rb', line 316

def make_concat_list
  concat_list = []

  @vrdisc.duplicate_name.each do |base_name|
    contents = ''
    file_name = "concat_#{base_name}.txt"

    names = @vrdisc.output_title.select { |x| x.match(/#{base_name}_\d\d/) }
    names.each do |line|
      escaped_line = "#{line}.vob".gsub("'") {"'\\''"}
      contents += "file '#{escaped_line}'\n"
    end
    concat_list << [file_name, contents, base_name]
  end

  concat_list
end

#read_infoObject

Read video information from dvd-ram discs in dvd-vr format.

required values:

@vrdisc.cmd, @vrdisc.opts_ifo

Get values of the video information:

=> @vrdisc.header
=> @vrdisc.num
=> @vrdisc.title
=> @vrdisc.date
=> @vrdisc.size


124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/dvdvrconv/dvdvr.rb', line 124

def read_info
  out, err, status = Open3.capture3(@vrdisc.cmd, @vrdisc.opts_ifo)
  puts "File read error => #{err}" unless status.success?
  @vrdisc.header = out.scan(/^(.*?)Number/m)

  # Sets the captured information to @vrdisc.
  %w[num title date size].each do |item|
    str = format("%-5s", item) + ":"
    @vrdisc[item] = out.scan(/#{str}\s(.*?)$/)
  end

  out
end

#rename_vobObject

Rename vob file to a customized title name.

required value:

@vrdisc.vob_titles

Parameters:

  • file_titles (String)

    is Array. Includes pair of source and destination filename.

    • [[src, dst], [src, dst], [src, dst], ....]


296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/dvdvrconv/dvdvr.rb', line 296

def rename_vob
  puts '----- output vob file -----'

  @vrdisc.vob_titles.each do |file_title|
    src, dst = file_title

    if File.exist?("#{dst}")
      puts "Skip => file #{dst} is exist."
    else
      File.rename(src, dst)
      puts "  file name: #{dst}"
    end
  end
end

#str_concat_cmd(file_name, base_name) ⇒ Object

Make a concatenation command string for FFmpeg.



75
76
77
# File 'lib/dvdvrconv/dvdvr.rb', line 75

def str_concat_cmd(file_name, base_name)
  Shellwords.shellsplit(%(ffmpeg -f concat -safe 0 -i "#{file_name}" -c copy "#{base_name}.vob"))
end

#str_convert_cmd(file_name) ⇒ Object

File convert command, vob to mp4 for FFmpeg.



102
103
104
105
106
107
108
109
110
# File 'lib/dvdvrconv/dvdvr.rb', line 102

def str_convert_cmd(file_name)
  if @vrdisc.hardware_encode == 'qsv'
    ffmpeg_qsv_cmd(file_name)
  elsif @vrdisc.hardware_encode == 'normal'
    ffmeg_normal_cmd(file_name)
  else
    ffmeg_normal_cmd(file_name)
  end
end

#str_dvdvr_cmdObject

Read VRO file from dvd-ram disc in dvd-vr format, and output vob files.



70
71
72
# File 'lib/dvdvrconv/dvdvr.rb', line 70

def str_dvdvr_cmd
  Shellwords.shellsplit(%("#{@vrdisc.cmd}" --name="#{Dvdvrconv::BASE_NAME}" "#{@vrdisc.opts_ifo}" "#{@vrdisc.opts_vro}"))
end

#view_infoObject

View video information from dvd-ram discs in dvd-vr format.

required values:

@vrdisc.header, @vrdisc.num, @vrdisc.title,
@vrdisc.date, @vrdisc.size


144
145
146
147
148
149
150
151
152
153
154
# File 'lib/dvdvrconv/dvdvr.rb', line 144

def view_info
  puts '----- view dvd-vr info -----'
  puts @vrdisc.header
  [@vrdisc.num, @vrdisc.title, @vrdisc.date, @vrdisc.size].transpose.each do |x|
    %w[num title date size].each_with_index do |item, idx|
      line = format('%-5s', item) + ": #{x.flatten[idx]}\n"
      puts line
    end
    puts '-'
  end
end

#vob2mp4Object

convert vob to mp4.

required Values:

@vrdisc.vob_titles


381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/dvdvrconv/dvdvr.rb', line 381

def vob2mp4
  files = []

  @vrdisc.vob_titles.each do |vob_title|
    files << vob_title[1].gsub(/.vob/, '')
  end

  files.each do |file_name|
    if File.exist?("#{file_name}.mp4")
      puts "Skip => file #{file_name}.mp4 is exist."
    else
      cmd = str_convert_cmd(file_name)
      puts "----- convert #{file_name}.vob to mp4 file -----"
      puts "run cmd:\n  #{cmd.join(' ')}"
      system(*cmd)
    end
  end
end

#vrdisc_statusObject



368
369
370
371
372
373
374
# File 'lib/dvdvrconv/dvdvr.rb', line 368

def vrdisc_status
  puts "\n< < < < < @vrdisc status > > > > >"
  %w[num title output_title duplicate_name vob_titles concat_mode hardware_encode global_quality h264_crf].each do |item|
    puts "#{item}=> #{@vrdisc[item]}"
  end
  puts "< < < < < @vrdisc status > > > > >\n"
end

#vro2vobObject

Read VRO file from dvd-ram disc in dvd-vr format, and output vob files.



197
198
199
200
201
202
203
# File 'lib/dvdvrconv/dvdvr.rb', line 197

def vro2vob
  cmd = str_dvdvr_cmd
  puts '----- convert file VRO to VOB -----'
  puts "> cmd:\n  #{cmd.join(' ')}"
  system(*cmd)
  puts ''
end