mkvtoolnix 0.7.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +203 -5
- data/lib/mkvtoolnix/modules/mkvmerge.rb +49 -1
- data/lib/mkvtoolnix/types/merge/attachment.rb +41 -0
- data/lib/mkvtoolnix/types/merge/chapter.rb +53 -0
- data/lib/mkvtoolnix/types/merge/input_file.rb +119 -0
- data/lib/mkvtoolnix/types/merge/input_track_options.rb +390 -0
- data/lib/mkvtoolnix/types/merge/output_control.rb +120 -0
- data/lib/mkvtoolnix/types/merge/segment_info.rb +28 -0
- data/lib/mkvtoolnix/types/merge/tags.rb +21 -0
- data/lib/mkvtoolnix.rb +14 -1
- data/mkvtoolnix.gemspec +4 -4
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fbb34a6ebad7edff1fd7a8b346772d03cb4586266708b1117023fc5212ee278
|
4
|
+
data.tar.gz: 3c943c0d0839585b61b7bcec644811cd7ba2ebcb02717bab4da6d242d187d635
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 499dbf2eee5835142fc5e68bed28ca54bcac1d9c59be5eaa692bfabf1284267c4e5a5c4798410d2b04d3035ee43a0270a798674496f4be290121317e2d62aa5d
|
7
|
+
data.tar.gz: 061047311adda84e1ad76e119aca20dd37048c25a77dc68ae3862c00d0634f897d5f56fa5aa88326b17c61b64951a184413c3bd93ad6f7e076ead73069b00c69
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Currently the following modules are implemented (fully):
|
|
6
6
|
* [mkvpropedit](https://mkvtoolnix.download/doc/mkvpropedit.html)
|
7
7
|
* [mkvextract](https://mkvtoolnix.download/doc/mkvextract.html)
|
8
8
|
|
9
|
-
|
9
|
+
Fully implemented, except `split`:
|
10
10
|
* [mkvmerge](https://mkvtoolnix.download/doc/mkvmerge.html)
|
11
11
|
|
12
12
|
## Installation
|
@@ -218,12 +218,210 @@ extract_attachments('myFile.mkv', [Attachment.new(0, 'attachment1.jpeg'), 'attac
|
|
218
218
|
```
|
219
219
|
will extract the attachments of the given file with ID 0 to `attachment1.jpeg` and ID 2 to `attachment.2.png`.
|
220
220
|
|
221
|
+
### mkvmerge
|
221
222
|
|
222
|
-
|
223
|
+
merges or modifies several input files by muxing it. This does not alter just metadata of a file, and instead writes a new
|
224
|
+
file depending on the provides input files and options.
|
223
225
|
|
224
|
-
|
226
|
+
#### available commands
|
227
|
+
|
228
|
+
* version
|
229
|
+
* info
|
230
|
+
* merge
|
231
|
+
|
232
|
+
`merge` covers all options except for split from [here](https://mkvtoolnix.download/doc/mkvmerge.html). It requires an input, and an
|
233
|
+
output file. If you just want to alter a file, e.g. removing a track, then only this file needs to be given as an input file.
|
234
|
+
All options from the manual page are available as some kind of builder. This way, an input file with the selected options can be build, and
|
235
|
+
will be applied when passed to `merge`.
|
236
|
+
The global options are seperated into different option builder. Those ones are:
|
237
|
+
* Chapter
|
238
|
+
* Tags
|
239
|
+
* Segment Info
|
240
|
+
* General Output
|
241
|
+
* Attachments
|
242
|
+
|
243
|
+
To build an option or an input file, mkvmerge provides already methods to do so:
|
244
|
+
* build_attachment(file)
|
245
|
+
* build_chapter
|
246
|
+
* build_segment_info
|
247
|
+
* build_tags(file)
|
248
|
+
* build_output_control
|
249
|
+
* build_input_file(file)
|
250
|
+
|
251
|
+
For specific track options for an input file, `InputFile` offers a `build_track_option(track_id)` method, which offers
|
252
|
+
options for this specific track and afterwards added to the input file via `add_track_options`
|
253
|
+
|
254
|
+
For specific details what options are available, just check the manual page. The available options are:
|
255
|
+
**Attachment:**
|
256
|
+
* with_mime_type
|
257
|
+
* with_name
|
258
|
+
* with_description
|
259
|
+
|
260
|
+
**Chapter:**
|
261
|
+
* with_chapter_language
|
262
|
+
* with_chapter_charset
|
263
|
+
* generate_chapter_every_secs
|
264
|
+
* generate_chapter_name_template
|
265
|
+
* generate_chapter_cue_name_format
|
266
|
+
* with_chapters_file
|
267
|
+
|
268
|
+
**Output Control:**
|
269
|
+
* with_title
|
270
|
+
* with_default_language
|
271
|
+
* with_track_order
|
272
|
+
* with_cluster_length_in_blocks
|
273
|
+
* with_meta_seek_element
|
274
|
+
* with_timestamp_scale
|
275
|
+
* with_durations_enabled
|
276
|
+
* without_cues
|
277
|
+
* without_date
|
278
|
+
* with_disabled_lacing
|
279
|
+
* without_track_statistics_tags
|
280
|
+
* without_language_ietf
|
281
|
+
|
282
|
+
**Segment Info:**
|
283
|
+
* for_file
|
284
|
+
* for_uids
|
285
|
+
|
286
|
+
**Tags:**
|
287
|
+
* can only be build by file
|
288
|
+
|
289
|
+
**Input File:**
|
290
|
+
* with_audio_tracks
|
291
|
+
* with_video_tracks
|
292
|
+
* with_subtitle_tracks
|
293
|
+
* with_track_tags
|
294
|
+
* with_attachments
|
295
|
+
* with_no_audio
|
296
|
+
* with_no_video
|
297
|
+
* with_no_subtitles
|
298
|
+
* with_no_chapters
|
299
|
+
* with_no_track_tags
|
300
|
+
* with_no_global_tags
|
301
|
+
* with_no_attachments
|
302
|
+
* add_track_options
|
303
|
+
* with_track_options
|
304
|
+
* chapter_sync
|
305
|
+
|
306
|
+
**Input Track Option**
|
307
|
+
* with_name
|
308
|
+
* with_language
|
309
|
+
* with_tags
|
310
|
+
* handle_as_aac_sbr
|
311
|
+
* with_track_sync
|
312
|
+
* with_cues
|
313
|
+
* default?
|
314
|
+
* forced?
|
315
|
+
* hearing_impaired?
|
316
|
+
* visual_impaired?
|
317
|
+
* text_description?
|
318
|
+
* original?
|
319
|
+
* commentary?
|
320
|
+
* reduce_audio_to_core
|
321
|
+
* with_timestamps
|
322
|
+
* remove_dialog_normalization_gain
|
323
|
+
* with_default_duration_in_secs
|
324
|
+
* fix_bitstream_timing_information
|
325
|
+
* with_compression_mode
|
326
|
+
* with_four_cc
|
327
|
+
* with_dimensions
|
328
|
+
* with_aspect_ratio
|
329
|
+
* with_cropping
|
330
|
+
* with_color_matrix_coefficients
|
331
|
+
* with_color_bits_per_channel
|
332
|
+
* with_chroma_sub_sample
|
333
|
+
* with_cb_sub_sample
|
334
|
+
* with_chroma_siting
|
335
|
+
* with_color_range
|
336
|
+
* with_color_transfer_characteristics
|
337
|
+
* with_color_primaries
|
338
|
+
* with_max_content_light
|
339
|
+
* with_max_frame_light
|
340
|
+
* with_chromaticity_coordinates
|
341
|
+
* with_white_color_coordinate
|
342
|
+
* with_max_luminance
|
343
|
+
* with_min_luminance
|
344
|
+
* with_projection_type
|
345
|
+
* with_projection_private
|
346
|
+
* with_projection_pose_yaw
|
347
|
+
* with_projection_pose_pitch
|
348
|
+
* with_projection_pose_roll
|
349
|
+
* with_field_order
|
350
|
+
* with_stereo_mode
|
351
|
+
* with_sub_charset
|
352
|
+
|
353
|
+
For example, to specify that a meta seek element,
|
354
|
+
no cues and no date are written, a the general output can be build accordingly:
|
355
|
+
```ruby
|
356
|
+
output_control = merge.build_output_control
|
357
|
+
output_control.with_meta_seek_element.without_cues.without_date
|
358
|
+
```
|
359
|
+
just pass this `output_control` to `merge`, and the options will be applied.
|
360
|
+
|
361
|
+
#### Example
|
362
|
+
|
363
|
+
##### merge video and audio from 2 different files
|
364
|
+
```ruby
|
365
|
+
video_input = merge.build_input_file('pathToVideo')
|
366
|
+
# we don't want the audio from this video file
|
367
|
+
video_input.with_no_audio
|
368
|
+
audio_input = merge.build_input_file('pathToAudio')
|
369
|
+
# we don't want the video from this audio file, if it has any
|
370
|
+
audio_input.with_no_video
|
371
|
+
|
372
|
+
# lets take the output control as defined earlier
|
373
|
+
merge.merge('outputFilePath', video_input, audio_input, output_control: output_control)
|
374
|
+
# => nil, or an error and the merged file is written to the given path
|
375
|
+
```
|
376
|
+
|
377
|
+
##### add 2 Attachments, chapters and tags to an mkv file
|
378
|
+
```ruby
|
379
|
+
attachment1 = merge.build_attachment('pathToAttachment1')
|
380
|
+
# no mime type provided, so it will be determined automatically by mkvmerge
|
381
|
+
attachment1.with_name('My first Attachment').with_description('and the description')
|
382
|
+
|
383
|
+
attachment2 = merge.build_attachment('pathToAttachment2')
|
384
|
+
attachment2.with_name('the 2nd one').with_mime_type('mime/type')
|
385
|
+
|
386
|
+
chapters = merge.build_chapter.with_chapters_file('pathToChapters.xml')
|
387
|
+
tags = merge.build_tags('pathToTags.xml')
|
388
|
+
|
389
|
+
input_file = merge.build_input_file('pathToInputFile')
|
390
|
+
|
391
|
+
merge.merge('outputFle', input_file, attachments: [attachment1, attachment2], chapter_options: chapters,
|
392
|
+
tag_options: tags)
|
393
|
+
# => nil, and outPutFile now contains the attachments, chapers and tag options
|
394
|
+
```
|
395
|
+
|
396
|
+
##### switch the track order of an mkv file
|
397
|
+
assuming we have 1 video, 2 audios, and 2 subtitles
|
398
|
+
```ruby
|
399
|
+
output_control = merge.build_output_control
|
400
|
+
# the order can be given as a String, hash, Array, or TrackOrder object
|
401
|
+
# mkv always builds video, audio and subtitle order, so we just need to switch the audio ids, video will be the first
|
402
|
+
# and subtitles the last tracks
|
403
|
+
output_control.with_track_order({ file_index: 0, track_index: 2 }, [0, 1])
|
404
|
+
|
405
|
+
input_file = merge.build_input_file('pathToInputFile')
|
406
|
+
|
407
|
+
merge.merge('outputFle', input_file, output_control: output_control)
|
408
|
+
# => nil, and the new file has the audio tracks switched
|
409
|
+
```
|
410
|
+
|
411
|
+
##### switch rename the first audio track and language
|
412
|
+
the first audio stream in this example has ID 1
|
413
|
+
```ruby
|
414
|
+
input_file = merge.build_input_file('pathToInputFile')
|
415
|
+
track_option = input_file.build_track_option(1)
|
416
|
+
track_option.with_name('the new track name')
|
417
|
+
# this will also set the language_ietf field
|
418
|
+
track_option.with_language('en')
|
419
|
+
|
420
|
+
input_file.add_track_options(track_option)
|
421
|
+
|
422
|
+
merge.merge('outputFle', input_file)
|
423
|
+
```
|
225
424
|
|
226
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
227
425
|
|
228
426
|
## Contributing
|
229
427
|
|
@@ -235,4 +433,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
235
433
|
|
236
434
|
## Code of Conduct
|
237
435
|
|
238
|
-
Everyone interacting in the Mkvtoolnix project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
436
|
+
Everyone interacting in the Mkvtoolnix project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/cfe86/RubyMkvToolNix/blob/master/CODE_OF_CONDUCT.md).
|
@@ -6,8 +6,12 @@ module MkvToolNix
|
|
6
6
|
class MkvMerge
|
7
7
|
include MkvModule
|
8
8
|
|
9
|
+
attr_accessor :default_language, :disable_language_ietf
|
10
|
+
|
9
11
|
def initialize(bin_path)
|
10
12
|
@bin_path = "#{bin_path}mkvmerge"
|
13
|
+
@default_language = 'und'
|
14
|
+
@disable_language_ietf = false
|
11
15
|
end
|
12
16
|
|
13
17
|
def version
|
@@ -18,9 +22,29 @@ module MkvToolNix
|
|
18
22
|
result.stdout.strip
|
19
23
|
end
|
20
24
|
|
25
|
+
def merge(output_file, *input_files, attachments: nil, chapter_options: nil, tag_options: nil,
|
26
|
+
output_control: nil, segment_info: nil)
|
27
|
+
raise Errors::MkvToolNixError, 'No Input File(s) given.' if input_files.nil?
|
28
|
+
|
29
|
+
cmd = ['mkvmerge']
|
30
|
+
|
31
|
+
attachments&.each { |attachment| attachment.add_to_cmd(cmd) }
|
32
|
+
chapter_options&.add_to_cmd(cmd)
|
33
|
+
segment_info&.add_to_cmd(cmd)
|
34
|
+
tag_options&.add_to_cmd(cmd)
|
35
|
+
output_control&.add_to_cmd(cmd)
|
36
|
+
|
37
|
+
cmd << '-o' << output_file
|
38
|
+
|
39
|
+
input_files.each { |input| input.add_to_cmd(cmd) }
|
40
|
+
|
41
|
+
a = cmd.join(' ')
|
42
|
+
|
43
|
+
call_cmd(cmd)
|
44
|
+
end
|
45
|
+
|
21
46
|
def info(file)
|
22
47
|
cmd = [@bin_path, '-J']
|
23
|
-
# cmd = [@bin_path, '--identififcation-format', 'json', '--identify']
|
24
48
|
cmd << file
|
25
49
|
|
26
50
|
result = call_cmd(cmd)
|
@@ -28,6 +52,30 @@ module MkvToolNix
|
|
28
52
|
json = JSON.parse(result.stdout)
|
29
53
|
Types::Info::MkvContainer.create(json)
|
30
54
|
end
|
55
|
+
|
56
|
+
def build_segment_info
|
57
|
+
Types::Merge::SegmentInfo.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_attachment(file)
|
61
|
+
Types::Merge::Attachment.new(file)
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_chapter
|
65
|
+
Types::Merge::Chapter.new
|
66
|
+
end
|
67
|
+
|
68
|
+
def build_tags(file)
|
69
|
+
Types::Merge::Tags.new(file)
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_output_control
|
73
|
+
Types::Merge::OutputControl.new
|
74
|
+
end
|
75
|
+
|
76
|
+
def build_input_file(file)
|
77
|
+
Types::Merge::InputFile.new(file)
|
78
|
+
end
|
31
79
|
end
|
32
80
|
end
|
33
81
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class Attachment
|
7
|
+
|
8
|
+
attr_reader :file, :mime_type, :name, :description
|
9
|
+
|
10
|
+
def with_mime_type(type)
|
11
|
+
@mime_type = type
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_name(name)
|
16
|
+
@name = name
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def with_description(description)
|
21
|
+
@description = description
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(file)
|
26
|
+
@file = file
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_to_cmd(cmd)
|
30
|
+
unless @file.nil?
|
31
|
+
cmd << '--attachment-description' << @description unless @description.nil?
|
32
|
+
cmd << '--attachment-mime-type' << @mime_type unless @mime_type.nil?
|
33
|
+
cmd << '--attachment-name' << @name unless @name.nil?
|
34
|
+
cmd << '--attach-file' << @file
|
35
|
+
end
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class Chapter
|
7
|
+
|
8
|
+
attr_reader :chapter_language, :chapter_charset, :generate_chapter_interval_secs,
|
9
|
+
:gen_chapter_cue_name_format, :gen_chapter_name_template, :chapters_file
|
10
|
+
|
11
|
+
def with_chapter_language(language_code)
|
12
|
+
@chapter_language = language_code
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_chapter_charset(charset)
|
17
|
+
@chapter_charset = charset
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_chapter_every_secs(num_secs)
|
22
|
+
@generate_chapter_interval_secs = num_secs
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_chapter_name_template(template)
|
27
|
+
@gen_chapter_name_template = template
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_chapter_cue_name_format(format)
|
32
|
+
@gen_chapter_cue_name_format = format
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def with_chapters_file(file)
|
37
|
+
@chapters_file = file
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_to_cmd(cmd)
|
42
|
+
cmd << '--chapters' << @chapters_file unless @chapters_file.nil?
|
43
|
+
cmd << '--chapter-language' << @chapter_language unless @chapter_language.nil?
|
44
|
+
cmd << '--chapter-charset' << @chapter_charset unless @chapter_charset.nil?
|
45
|
+
cmd << '--generate-chapters' << "interval:#{@generate_chapter_interval_secs}s" unless @generate_chapter_interval_secs.nil?
|
46
|
+
cmd << '--generate-chapters-name-template' << @gen_chapter_name_template unless @gen_chapter_name_template.nil?
|
47
|
+
cmd << '--cue-chapter-name-format' << @gen_chapter_cue_name_format unless @gen_chapter_cue_name_format.nil?
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class InputFile
|
7
|
+
|
8
|
+
attr_reader :audio_tracks, :video_tracks, :subtitle_tracks, :track_tags, :attachments, :no_audio,
|
9
|
+
:no_video, :no_subtitles, :no_chapters, :no_attachments, :no_track_tags, :no_global_tags,
|
10
|
+
:track_options
|
11
|
+
|
12
|
+
def with_audio_tracks(*track_ids)
|
13
|
+
@audio_tracks = track_ids
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_video_tracks(*track_ids)
|
18
|
+
@video_tracks = track_ids
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_subtitle_tracks(*track_ids)
|
23
|
+
@subtitle_tracks = track_ids
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def with_track_tags(*track_ids)
|
28
|
+
@track_tags = track_ids
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_attachments(*attachment_ids)
|
33
|
+
@attachments = attachment_ids
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def with_no_audio
|
38
|
+
@no_audio = true
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def with_no_video
|
43
|
+
@no_video = true
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_no_subtitles
|
48
|
+
@no_subtitles = true
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def with_no_chapters
|
53
|
+
@no_chapters = true
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def with_no_track_tags
|
58
|
+
@no_track_tags = true
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
def with_no_global_tags
|
63
|
+
@no_global_tags = true
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
def with_no_attachments
|
68
|
+
@no_attachments = true
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_track_options(option)
|
73
|
+
@track_options << option
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
def with_track_options(options)
|
78
|
+
@track_options = options
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def chapter_sync(d = 0, o_div_p = 1.0)
|
83
|
+
@chapter_sync = "-2:#{d},#{o_div_p}"
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def build_track_option(track_id)
|
88
|
+
InputTrackOption.new(track_id)
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_to_cmd(cmd)
|
92
|
+
cmd << '--audio-tracks' << @audio_tracks.join(',') unless @audio_tracks.nil?
|
93
|
+
cmd << '--video-tracks' << @video_tracks.join(',') unless @video_tracks.nil?
|
94
|
+
cmd << '--subtitle-tracks' << @subtitle_tracks.join(',') unless @subtitle_tracks.nil?
|
95
|
+
cmd << '--track-tags' << @track_tags.join(',') unless @track_tags.nil?
|
96
|
+
cmd << '--attachments' << @attachments.join(',') unless @attachments.nil?
|
97
|
+
cmd << '--no-audio' unless @no_audio.nil?
|
98
|
+
cmd << '--no-video' unless @no_video.nil?
|
99
|
+
cmd << '--no-subtitles' unless @no_subtitles.nil?
|
100
|
+
cmd << '--no-track-tags' unless @no_track_tags.nil?
|
101
|
+
cmd << '--no-chapters' unless @no_chapters.nil?
|
102
|
+
cmd << '--no-attachments' unless @no_attachments.nil?
|
103
|
+
cmd << '--no-global-tags' unless @no_global_tags.nil?
|
104
|
+
cmd << '--sync' << @chapter_sync unless @chapter_sync.nil?
|
105
|
+
|
106
|
+
@track_options.each { |option| option.add_to_cmd(cmd) }
|
107
|
+
|
108
|
+
cmd << @file
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def initialize(file)
|
113
|
+
@file = file
|
114
|
+
@track_options = []
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,390 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class InputTrackOption
|
7
|
+
|
8
|
+
attr_reader :track_id, :name, :language, :tag_file, :aac_sbr, :track_sync, :cues, :is_default,
|
9
|
+
:is_forced, :is_hearing_impaired, :is_visual_impaired, :is_text_description, :is_original,
|
10
|
+
:is_commentary, :reduce_to_core, :no_dialog_norm_gain, :timestamp_file, :default_duration_in_secs,
|
11
|
+
:fix_bitstream_timing_info, :compression, :four_cc, :dimensions, :aspect_ratio,
|
12
|
+
:color_matrix_coefficients, :color_bits_per_channel, :chroma_sub_sample, :cb_sub_sample,
|
13
|
+
:color_transfer_characteristics, :color_primaries, :max_content_light, :max_frame_light,
|
14
|
+
:chromaticity_coordinates, :white_color_coordinate, :max_luminance, :min_luminance,
|
15
|
+
:projection_type, :projection_private, :projection_pose_yaw, :projection_pose_pitch,
|
16
|
+
:projection_pose_roll, :field_order, :stereo_mode, :sub_charset
|
17
|
+
|
18
|
+
def with_name(name)
|
19
|
+
@name = "#{@track_id}:#{name}"
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_language(language)
|
24
|
+
@language = "#{@track_id}:#{language}"
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def with_tags(file)
|
29
|
+
@tag_file = "#{@track_id}:#{file}"
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle_as_aac_sbr(enabled: true)
|
34
|
+
@aac_sbr = "#{@track_id}:#{enabled ? 1 : 0}"
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_track_sync(d = 0, o_div_p = 1.0)
|
39
|
+
@track_sync = "#{@track_id}:#{d},#{o_div_p}"
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_cues(mode = CueMode::I_FRAMES)
|
44
|
+
@cues = "#{@track_id}:#{mode}"
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def default?(enabled: true)
|
49
|
+
@is_default = "#{@track_id}:#{enabled}"
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def forced?(enabled: true)
|
54
|
+
@is_forced = "#{@track_id}:#{enabled}"
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def hearing_impaired?(enabled: true)
|
59
|
+
@is_hearing_impaired = "#{@track_id}:#{enabled}"
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def visual_impaired?(enabled: true)
|
64
|
+
@is_visual_impaired = "#{@track_id}:#{enabled}"
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def text_description?(enabled: true)
|
69
|
+
@is_text_description = "#{@track_id}:#{enabled}"
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def original?(enabled: true)
|
74
|
+
@is_original = "#{@track_id}:#{enabled}"
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def commentary?(enabled: true)
|
79
|
+
@is_commentary = "#{@track_id}:#{enabled}"
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
def reduce_audio_to_core
|
84
|
+
@reduce_to_core = true
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def with_timestamps(file)
|
89
|
+
@timestamp_file = "#{@track_id}:#{file}"
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def remove_dialog_normalization_gain
|
94
|
+
@no_dialog_norm_gain = true
|
95
|
+
self
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def with_default_duration_in_secs(secs)
|
100
|
+
@default_duration_in_secs = "#{@track_id}:#{secs}s"
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
def fix_bitstream_timing_information(fix: true)
|
105
|
+
@fix_bitstream_timing_info = "#{@track_id}:#{fix ? 1 : 0}"
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def with_compression_mode(mode = Compression::NONE)
|
110
|
+
@compression = "#{@track_id}:#{mode}"
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
def with_four_cc(four_cc)
|
115
|
+
@four_cc = "#{@track_id}:#{four_cc}"
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
def with_dimensions(width, height)
|
120
|
+
@dimensions = "#{@track_id}:#{width}x#{height}"
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
def with_aspect_ratio(ratio)
|
125
|
+
@aspect_ratio = "#{@track_id}:#{ratio}"
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
def with_cropping(left, top, right, bottom)
|
130
|
+
@cropping = "#{@track_id}:#{left},#{top},#{right},#{bottom}"
|
131
|
+
self
|
132
|
+
end
|
133
|
+
|
134
|
+
def with_color_matrix_coefficients(coefficient)
|
135
|
+
@color_matrix_coefficients = "#{@track_id}:#{coefficient}"
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
def with_color_bits_per_channel(bits)
|
140
|
+
@color_bits_per_channel = "#{@track_id}:#{bits}"
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
def with_chroma_sub_sample(horizontal, vertical)
|
145
|
+
@chroma_sub_sample = "#{@track_id}:#{horizontal},#{vertical}"
|
146
|
+
self
|
147
|
+
end
|
148
|
+
|
149
|
+
def with_cb_sub_sample(horizontal, vertical)
|
150
|
+
@cb_sub_sample = "#{@track_id}:#{horizontal},#{vertical}"
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
def with_chroma_siting(horizontal, vertical)
|
155
|
+
@chroma_siting = "#{@track_id}:#{horizontal},#{vertical}"
|
156
|
+
self
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_color_range(range)
|
160
|
+
@color_range = "#{@track_id}:#{range}"
|
161
|
+
self
|
162
|
+
end
|
163
|
+
|
164
|
+
def with_color_transfer_characteristics(characteristics)
|
165
|
+
@color_transfer_characteristics = "#{@track_id}:#{characteristics}"
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
def with_color_primaries(primaries)
|
170
|
+
@color_primaries = "#{@track_id}:#{primaries}"
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
def with_max_content_light(light)
|
175
|
+
@max_content_light = "#{@track_id}:#{light}"
|
176
|
+
self
|
177
|
+
end
|
178
|
+
|
179
|
+
def with_max_frame_light(light)
|
180
|
+
@max_frame_light = "#{@track_id}:#{light}"
|
181
|
+
self
|
182
|
+
end
|
183
|
+
|
184
|
+
def with_chromaticity_coordinates(red_x, red_y, green_x, green_y, blue_x, blue_y)
|
185
|
+
@chromaticity_coordinates = "#{@track_id}:#{red_x},#{red_y},#{green_x},#{green_y},#{blue_x},#{blue_y}"
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
def with_white_color_coordinate(x, y)
|
190
|
+
@white_color_coordinate = "#{@track_id}:#{x},#{y}"
|
191
|
+
self
|
192
|
+
end
|
193
|
+
|
194
|
+
def with_max_luminance(luminance)
|
195
|
+
@max_luminance = "#{@track_id}:#{luminance}"
|
196
|
+
self
|
197
|
+
end
|
198
|
+
|
199
|
+
def with_min_luminance(luminance)
|
200
|
+
@min_luminance = "#{@track_id}:#{luminance}"
|
201
|
+
self
|
202
|
+
end
|
203
|
+
|
204
|
+
def with_projection_type(type)
|
205
|
+
@projection_type = "#{@track_id}:#{type}"
|
206
|
+
self
|
207
|
+
end
|
208
|
+
|
209
|
+
def with_projection_private(hex_data)
|
210
|
+
@projection_private = "#{@track_id}:#{hex_data}"
|
211
|
+
self
|
212
|
+
end
|
213
|
+
|
214
|
+
def with_projection_pose_yaw(yaw)
|
215
|
+
@projection_pose_yaw = "#{@track_id}:#{yaw}"
|
216
|
+
self
|
217
|
+
end
|
218
|
+
|
219
|
+
def with_projection_pose_pitch(pitch)
|
220
|
+
@projection_pose_pitch = "#{@track_id}:#{pitch}"
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
def with_projection_pose_roll(roll)
|
225
|
+
@projection_pose_roll = "#{@track_id}:#{roll}"
|
226
|
+
self
|
227
|
+
end
|
228
|
+
|
229
|
+
def with_field_order(order)
|
230
|
+
@field_order = "#{@track_id}:#{order}"
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
def with_stereo_mode(mode)
|
235
|
+
@stereo_mode = "#{@track_id}:#{mode}"
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
def with_sub_charset(charset)
|
240
|
+
@sub_charset = "#{@track_id}:#{charset}"
|
241
|
+
self
|
242
|
+
end
|
243
|
+
|
244
|
+
def initialize(track_id)
|
245
|
+
raise Errors::MkvToolNixError, 'track_id can\'t be nil' if track_id.nil?
|
246
|
+
|
247
|
+
@track_id = track_id
|
248
|
+
end
|
249
|
+
|
250
|
+
def add_to_cmd(cmd)
|
251
|
+
cmd << '--sync' << @track_sync unless @track_sync.nil?
|
252
|
+
cmd << '--cues' << @cues unless @cues.nil?
|
253
|
+
cmd << '--default-track' << @is_default unless @is_default.nil?
|
254
|
+
cmd << '--forced-track' << @is_forced unless @is_forced.nil?
|
255
|
+
cmd << '--hearing-impaired-flag' << @is_hearing_impaired unless @is_hearing_impaired.nil?
|
256
|
+
cmd << '--visual-impaired-flag' << @is_visual_impaired unless @is_visual_impaired.nil?
|
257
|
+
cmd << '--text-descriptions-flag' << @is_text_description unless @is_text_description.nil?
|
258
|
+
cmd << '--original-flag' << @is_original unless @is_original.nil?
|
259
|
+
cmd << '--commentary-flag' << @is_commentary unless @is_commentary.nil?
|
260
|
+
cmd << '--track-name' << @name unless @name.nil?
|
261
|
+
cmd << '--language' << @language unless @language.nil?
|
262
|
+
cmd << '--tags' << @tag_file unless @tag_file.nil?
|
263
|
+
cmd << '--aac-is-sbr' << @aac_sbr unless @aac_sbr.nil?
|
264
|
+
cmd << '--reduce-to-core' unless @reduce_to_core.nil?
|
265
|
+
cmd << '--remove-dialog-normalization-gain' unless @no_dialog_norm_gain.nil?
|
266
|
+
cmd << '--timestamps' << @timestamp_file unless @timestamp_file.nil?
|
267
|
+
cmd << '--default-duration' << @default_duration_in_secs unless @default_duration_in_secs.nil?
|
268
|
+
cmd << '--fix-bitstream-timing-information' << @fix_bitstream_timing_info unless @fix_bitstream_timing_info.nil?
|
269
|
+
cmd << '--compression' << @compression unless @compression.nil?
|
270
|
+
cmd << '--fourcc' << @four_cc unless @four_cc.nil?
|
271
|
+
cmd << '--display-dimensions' << @dimensions unless @dimensions.nil?
|
272
|
+
cmd << '--aspect-ratio' << @aspect_ratio unless @aspect_ratio.nil?
|
273
|
+
cmd << '--cropping' << @cropping unless @cropping.nil?
|
274
|
+
cmd << '--colour-matrix-coefficients' << @color_matrix_coefficients unless @color_matrix_coefficients.nil?
|
275
|
+
cmd << '--colour-bits-per-channel' << @color_bits_per_channel unless @color_bits_per_channel.nil?
|
276
|
+
cmd << '--chroma-subsample' << @chroma_sub_sample unless @chroma_sub_sample.nil?
|
277
|
+
cmd << '--cb-subsample' << @cb_sub_sample unless @cb_sub_sample.nil?
|
278
|
+
cmd << '--chroma-siting' << @chroma_siting unless @chroma_siting.nil?
|
279
|
+
cmd << '--colour-range' << @color_range unless @color_range.nil?
|
280
|
+
cmd << '--colour-transfer-characteristics' << @color_transfer_characteristics unless @color_transfer_characteristics.nil?
|
281
|
+
cmd << '--colour-primaries' << @color_primaries unless @color_primaries.nil?
|
282
|
+
cmd << '--max-content-light' << @max_content_light unless @max_content_light.nil?
|
283
|
+
cmd << '--max-frame-light' << @max_frame_light unless @max_frame_light.nil?
|
284
|
+
cmd << '--chromaticity-coordinates' << @chromaticity_coordinates unless @chromaticity_coordinates.nil?
|
285
|
+
cmd << '--white-colour-coordinates' << @white_color_coordinate unless @white_color_coordinate.nil?
|
286
|
+
cmd << '--max-luminance' << @max_luminance unless @max_luminance.nil?
|
287
|
+
cmd << '--min-luminance' << @min_luminance unless @min_luminance.nil?
|
288
|
+
cmd << '--projection-type' << @projection_type unless @projection_type.nil?
|
289
|
+
cmd << '--projection-private' << @projection_private unless @projection_private.nil?
|
290
|
+
cmd << '--projection-pose-yaw' << @projection_pose_yaw unless @projection_pose_yaw.nil?
|
291
|
+
cmd << '--projection-pose-pitch' << @projection_pose_pitch unless @projection_pose_pitch.nil?
|
292
|
+
cmd << '--projection-pose-roll' << @projection_pose_roll unless @projection_pose_roll.nil?
|
293
|
+
cmd << '--field-order' << @field_order unless @field_order.nil?
|
294
|
+
cmd << '--stereo-mode' << @stereo_mode unless @stereo_mode.nil?
|
295
|
+
cmd << '--sub-charset' << @sub_charset unless @sub_charset.nil?
|
296
|
+
nil
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
module CueMode
|
301
|
+
NONE = 'none'
|
302
|
+
I_FRAMES = 'iframes'
|
303
|
+
ALL = 'all'
|
304
|
+
end
|
305
|
+
|
306
|
+
module Compression
|
307
|
+
NONE = 'none'
|
308
|
+
ZLIB = 'zlib'
|
309
|
+
MPEG4_P2 = 'mpeg4_p2'
|
310
|
+
end
|
311
|
+
|
312
|
+
module ColorMatrixCoefficients
|
313
|
+
GBR = 0
|
314
|
+
BT709 = 1
|
315
|
+
UNSPECIFIED = 2
|
316
|
+
FCC = 4
|
317
|
+
BT470BG = 5
|
318
|
+
SMPTE_170M = 6
|
319
|
+
SMPTE_240M = 7
|
320
|
+
YCOCG = 8
|
321
|
+
BT2020_NON_CONSTANT_LUMINANCE = 9
|
322
|
+
BT2020_CONSTANT_LUMINANCE = 10
|
323
|
+
end
|
324
|
+
|
325
|
+
module ColorRange
|
326
|
+
UNSPECIFIED = 0
|
327
|
+
BROADCAST_RANGE = 1
|
328
|
+
FULL_RANGE = 2
|
329
|
+
DEFINED_BY_MATRIX_TRANSFER_COEFFICIENTS = 3
|
330
|
+
end
|
331
|
+
|
332
|
+
module ColorTransferCharacteristics
|
333
|
+
ITU_R_BT_709 = 1
|
334
|
+
UNSPECIFIED = 2
|
335
|
+
GAMMA_2_2_CURVE = 4
|
336
|
+
GAMMA_8_CURVE = 5
|
337
|
+
SMPTE_170M = 6
|
338
|
+
SMPTE_240M = 7
|
339
|
+
LINEAR = 8
|
340
|
+
LOG = 9
|
341
|
+
LOG_SQRT = 10
|
342
|
+
IEC_61966_2_4 = 11
|
343
|
+
ITU_R_BT_1361_EXTENDED_COLOR_GAMUT = 12
|
344
|
+
IEC_61966_2_1 = 13
|
345
|
+
ITU_R_BT_2020_10_BIT = 14
|
346
|
+
ITU_R_BT_2020_12_BIT = 15
|
347
|
+
SMPTE_ST_2084 = 16
|
348
|
+
SMPTE_ST_428_1 = 17
|
349
|
+
ARIB_STD_B67_HLG = 18
|
350
|
+
end
|
351
|
+
|
352
|
+
module ColorPrimaries
|
353
|
+
ITU_R_BT_709 = 1
|
354
|
+
ITU_R_BT_470M = 4
|
355
|
+
ITU_R_BT_470BG = 5
|
356
|
+
SMPTE_170M = 6
|
357
|
+
SMPTE_240M = 7
|
358
|
+
FILM = 8
|
359
|
+
ITU_R_BT_2020 = 9
|
360
|
+
SMPTE_ST_428_1 = 10
|
361
|
+
JEDEC_P22_PHOSPHORS = 22
|
362
|
+
end
|
363
|
+
|
364
|
+
module ProjectionType
|
365
|
+
RECTANGULAR = 0
|
366
|
+
EQUIRECTANGULAR = 1
|
367
|
+
CUBEMAP = 2
|
368
|
+
MESH = 3
|
369
|
+
end
|
370
|
+
|
371
|
+
module StereoMode
|
372
|
+
MONO = 'mono'
|
373
|
+
SIDE_BY_SIDE_LEFT_FIRST = 'side_by_side_left_first'
|
374
|
+
TOP_BOTTOM_RIGHT_FIRST = 'top_bottom_right_first'
|
375
|
+
TOP_BOTTOM_LEFT_FIRST = 'top_bottom_left_first'
|
376
|
+
CHECKERBOARD_RIGHT_FIRST = 'checkerboard_right_first'
|
377
|
+
CHECKERBOARD_LEFT_FIRST = 'checkerboard_left_first'
|
378
|
+
ROW_INTERLEAVED_RIGHT_FIRST = 'row_interleaved_right_first'
|
379
|
+
ROW_INTERLEAVED_LEFT_FIRST = 'row_interleaved_left_first'
|
380
|
+
COLUMN_INTERLEAVED_RIGHT_FIRST = 'column_interleaved_right_first'
|
381
|
+
COLUMN_INTERLEAVED_LEFT_FIRST = 'column_interleaved_left_first'
|
382
|
+
ANAGLYPH_CYAN_RED = 'anaglyph_cyan_red'
|
383
|
+
SIDE_BY_SIDE_RIGHT_FIRST = 'side_by_side_right_first'
|
384
|
+
ANAGLYPH_GREEN_MAGENTA = 'anaglyph_green_magenta'
|
385
|
+
BOTH_EYES_LACED_LEFT_FIRST = 'both_eyes_laced_left_first'
|
386
|
+
BOTH_EYES_LACED_RIGHT_FIRST = 'both_eyes_laced_right_first'
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class OutputControl
|
7
|
+
|
8
|
+
attr_reader :title, :default_language, :track_order, :cluster_length_blocks, :generate_meta_seek,
|
9
|
+
:timestamp_scale, :enable_duration, :no_cues, :no_date, :disable_lacing, :disable_language_ietf,
|
10
|
+
:disable_track_statistics_tags
|
11
|
+
|
12
|
+
def with_title(title)
|
13
|
+
@title = title
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_default_language(language)
|
18
|
+
@default_language = language
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def with_track_order(order)
|
23
|
+
if order.is_a?(String)
|
24
|
+
@track_order = order
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
@track_order = order.map do |it|
|
29
|
+
# @track_order.map(&:to_s).join(',')
|
30
|
+
case it
|
31
|
+
when TrackOrder
|
32
|
+
next it.to_s
|
33
|
+
when Array
|
34
|
+
next ["#{it[0]}:#{it[1]}"]
|
35
|
+
when Hash
|
36
|
+
next ["#{it[:file_index]}:#{it[:track_id]}"]
|
37
|
+
end
|
38
|
+
end.join(',')
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_cluster_length_in_blocks(blocks)
|
44
|
+
@cluster_length_blocks = blocks
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def with_meta_seek_element
|
49
|
+
@generate_meta_seek = true
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_timestamp_scale(factor)
|
54
|
+
@timestamp_scale = factor
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def with_durations_enabled
|
59
|
+
@enable_duration = true
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def without_cues
|
64
|
+
@no_cues = true
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def without_date
|
69
|
+
@no_date = true
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def with_disabled_lacing
|
74
|
+
@disable_lacing = true
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def without_track_statistics_tags
|
79
|
+
@disable_track_statistics_tags = true
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
def without_language_ietf
|
84
|
+
@disable_language_ietf = true
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_to_cmd(cmd)
|
89
|
+
cmd << '--title' << @title unless @title.nil?
|
90
|
+
cmd << '--default-language' << @default_language unless @default_language.nil?
|
91
|
+
cmd << '--track-order' << @track_order unless @track_order.nil?
|
92
|
+
cmd << '--cluster-length' << @cluster_length_blocks unless @cluster_length_blocks.nil?
|
93
|
+
cmd << '--clusters-in-meta-seek' if @generate_meta_seek
|
94
|
+
cmd << '--timestamp-scale' << @timestamp_scale unless @timestamp_scale.nil?
|
95
|
+
cmd << '--enable-durations' if @enable_duration
|
96
|
+
cmd << '--no-cues' if @no_cues
|
97
|
+
cmd << '--no-date' if @no_date
|
98
|
+
cmd << '--disable-lacing' if @disable_lacing
|
99
|
+
cmd << '--disable-track-statistics-tags' if @disable_track_statistics_tags
|
100
|
+
cmd << '--disable-language-ietf' if @disable_language_ietf
|
101
|
+
nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class TrackOrder
|
106
|
+
|
107
|
+
attr_reader :file_index, :track_id
|
108
|
+
|
109
|
+
def to_s
|
110
|
+
"#{@file_index}:#{@track_id}"
|
111
|
+
end
|
112
|
+
|
113
|
+
def initialize(file_index, track_id)
|
114
|
+
@file_index = file_index
|
115
|
+
@track_id = track_id
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class SegmentInfo
|
7
|
+
|
8
|
+
attr_reader :file, :uids
|
9
|
+
|
10
|
+
def for_file(file)
|
11
|
+
@file = file
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def for_uids(uids)
|
16
|
+
@uids = uids
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_to_cmd(cmd)
|
21
|
+
cmd << '--segmentinfo' << @file unless @file.nil?
|
22
|
+
cmd << '--segment-uid' << @uids.join(',') unless @uids.nil?
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MkvToolNix
|
4
|
+
module Types
|
5
|
+
module Merge
|
6
|
+
class Tags
|
7
|
+
|
8
|
+
attr_reader :file
|
9
|
+
|
10
|
+
def initialize(file)
|
11
|
+
@file = file
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_to_cmd(cmd)
|
15
|
+
cmd << '--global-tags' << @file unless @file.nil?
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/mkvtoolnix.rb
CHANGED
@@ -27,9 +27,17 @@ require 'mkvtoolnix/types/info/subtitle'
|
|
27
27
|
require 'mkvtoolnix/types/info/video'
|
28
28
|
require 'mkvtoolnix/types/info/attachment'
|
29
29
|
|
30
|
-
require 'mkvtoolnix/
|
30
|
+
require 'mkvtoolnix/types/merge/attachment'
|
31
|
+
require 'mkvtoolnix/types/merge/chapter'
|
32
|
+
require 'mkvtoolnix/types/merge/input_track_options'
|
33
|
+
require 'mkvtoolnix/types/merge/input_file'
|
34
|
+
require 'mkvtoolnix/types/merge/output_control'
|
35
|
+
require 'mkvtoolnix/types/merge/segment_info'
|
36
|
+
require 'mkvtoolnix/types/merge/tags'
|
37
|
+
|
31
38
|
require 'mkvtoolnix/modules/mkvpropedit'
|
32
39
|
require 'mkvtoolnix/modules/mkvextract'
|
40
|
+
require 'mkvtoolnix/modules/mkvmerge'
|
33
41
|
|
34
42
|
module MkvToolNix
|
35
43
|
|
@@ -64,7 +72,12 @@ module MkvToolNix
|
|
64
72
|
|
65
73
|
def disable_language_ietf(disabled: true)
|
66
74
|
@mkvpropedit.disable_language_ietf = disabled
|
75
|
+
@mkvmerge.disable_language_ietf = disabled
|
67
76
|
self
|
68
77
|
end
|
78
|
+
|
79
|
+
def default_language(language = 'und')
|
80
|
+
@mkvmerge.default_language = language
|
81
|
+
end
|
69
82
|
end
|
70
83
|
end
|
data/mkvtoolnix.gemspec
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'mkvtoolnix'
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '1.0.0'
|
6
6
|
spec.authors = ['Christian Feier']
|
7
7
|
spec.email = ['Christian.Feier@gmail.com']
|
8
8
|
|
9
|
-
spec.summary = 'A wrapper for MkvToolNix https://mkvtoolnix.download/ to create, alter and inspect MKV files.
|
10
|
-
|
9
|
+
spec.summary = 'A wrapper for MkvToolNix https://mkvtoolnix.download/ to create, alter and inspect MKV files.'\
|
10
|
+
'For more information, please check the github page: https://github.com/cfe86/RubyMkvToolNix'
|
11
11
|
spec.description = 'A wrapper for MkvToolNix https://mkvtoolnix.download/ to create, alter and inspect MKV files.'\
|
12
|
-
'Currently mkvpropedit and mkvextract are fully implemented. mkvmerge is
|
12
|
+
'Currently mkvpropedit and mkvextract are fully implemented. mkvmerge is completed except the split options.'
|
13
13
|
spec.homepage = 'https://github.com/cfe86/RubyMkvToolNix'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
spec.required_ruby_version = '>= 2.5.0'
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mkvtoolnix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Feier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A wrapper for MkvToolNix https://mkvtoolnix.download/ to create, alter
|
14
14
|
and inspect MKV files.Currently mkvpropedit and mkvextract are fully implemented.
|
15
|
-
mkvmerge is
|
15
|
+
mkvmerge is completed except the split options.
|
16
16
|
email:
|
17
17
|
- Christian.Feier@gmail.com
|
18
18
|
executables: []
|
@@ -43,6 +43,13 @@ files:
|
|
43
43
|
- lib/mkvtoolnix/types/info/mkv_container.rb
|
44
44
|
- lib/mkvtoolnix/types/info/subtitle.rb
|
45
45
|
- lib/mkvtoolnix/types/info/video.rb
|
46
|
+
- lib/mkvtoolnix/types/merge/attachment.rb
|
47
|
+
- lib/mkvtoolnix/types/merge/chapter.rb
|
48
|
+
- lib/mkvtoolnix/types/merge/input_file.rb
|
49
|
+
- lib/mkvtoolnix/types/merge/input_track_options.rb
|
50
|
+
- lib/mkvtoolnix/types/merge/output_control.rb
|
51
|
+
- lib/mkvtoolnix/types/merge/segment_info.rb
|
52
|
+
- lib/mkvtoolnix/types/merge/tags.rb
|
46
53
|
- lib/mkvtoolnix/types/propedit/audio_property.rb
|
47
54
|
- lib/mkvtoolnix/types/propedit/common_property.rb
|
48
55
|
- lib/mkvtoolnix/types/propedit/info_property.rb
|
@@ -76,5 +83,5 @@ rubygems_version: 3.2.15
|
|
76
83
|
signing_key:
|
77
84
|
specification_version: 4
|
78
85
|
summary: 'A wrapper for MkvToolNix https://mkvtoolnix.download/ to create, alter and
|
79
|
-
inspect MKV files.
|
86
|
+
inspect MKV files.For more information, please check the github page: https://github.com/cfe86/RubyMkvToolNix'
|
80
87
|
test_files: []
|