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.



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

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
end

Instance Attribute Details

#vrdiscObject

Returns the value of attribute vrdisc.



42
43
44
# File 'lib/dvdvrconv/dvdvr.rb', line 42

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


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/dvdvrconv/dvdvr.rb', line 174

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


221
222
223
224
225
226
227
228
229
230
231
# File 'lib/dvdvrconv/dvdvr.rb', line 221

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.



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/dvdvrconv/dvdvr.rb', line 353

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}"
    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


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
287
288
289
290
291
292
293
294
# File 'lib/dvdvrconv/dvdvr.rb', line 261

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



405
406
407
408
409
# File 'lib/dvdvrconv/dvdvr.rb', line 405

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.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/dvdvrconv/dvdvr.rb', line 78

def ffmeg_normal_cmd(file_name)
  cmd = 'ffmpeg '
  cmd += "-i #{file_name}.vob "
  cmd += '-filter:v "crop=704:474:0:0" '
  cmd += '-vcodec libx264 '
  cmd += '-b:v 500k '
  cmd += '-aspect 16:9 '
  cmd += '-acodec copy '
  cmd += '-bsf:v "filter_units=remove_types=6" '
  cmd + "#{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.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dvdvrconv/dvdvr.rb', line 94

def ffmpeg_qsv_cmd(file_name)
  cmd = 'ffmpeg '
  cmd += '-hwaccel qsv '
  cmd += '-hwaccel_output_format qsv '
  cmd += "-i #{file_name}.vob "
  cmd += '-filter:v "crop=704:474:0:0" '
  cmd += '-c:v h264_qsv '
  cmd += "-global_quality #{@vrdisc.global_quality} "
  cmd += '-look_ahead 1 '
  cmd += '-aspect 16:9 '
  cmd += '-acodec copy '
  cmd += '-bsf:v "filter_units=remove_types=6" '
  cmd + "#{file_name}.mp4"
end

#make_concat_listObject

Make a list of file names to concatenate.

required values:

@vrdisc.duplicate_name, @vrdisc.output_title


324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/dvdvrconv/dvdvr.rb', line 324

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 { |line| contents += "file '#{line}.vob'\n" }
    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


132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dvdvrconv/dvdvr.rb', line 132

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], .…


304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/dvdvrconv/dvdvr.rb', line 304

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.



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

def str_concat_cmd(file_name, base_name)
  %(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.



110
111
112
113
114
115
116
117
118
# File 'lib/dvdvrconv/dvdvr.rb', line 110

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.



66
67
68
# File 'lib/dvdvrconv/dvdvr.rb', line 66

def str_dvdvr_cmd
  %(#{@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


152
153
154
155
156
157
158
159
160
161
162
# File 'lib/dvdvrconv/dvdvr.rb', line 152

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


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/dvdvrconv/dvdvr.rb', line 386

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}"
      system(cmd)
    end
  end
end

#vrdisc_statusObject



373
374
375
376
377
378
379
# File 'lib/dvdvrconv/dvdvr.rb', line 373

def vrdisc_status
  puts "\n< < < < < @vrdisc status > > > > >"
  %w[num title output_title duplicate_name vob_titles concat_mode hardware_encode global_quality].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.



205
206
207
208
209
210
211
# File 'lib/dvdvrconv/dvdvr.rb', line 205

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