mkv2m4v 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/README.md +35 -6
- data/Rakefile +9 -0
- data/doc/notes.md +26 -0
- data/lib/mkv2m4v/file.rb +80 -0
- data/lib/mkv2m4v/track.rb +86 -0
- data/lib/mkv2m4v/track_ranker.rb +64 -0
- data/lib/mkv2m4v/transcoder.rb +141 -0
- data/lib/mkv2m4v/version.rb +1 -1
- data/lib/mkv2m4v.rb +10 -44
- data/mkv2m4v.gemspec +7 -2
- data/test/test_helper.rb +2 -0
- metadata +80 -4
- data/lib/mkv2m4v/mediainfo.rb +0 -13
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
**This gem is a work in progress.** Do not expect any supported functionality
|
2
|
-
until v0.1.0.
|
3
|
-
|
4
1
|
# mkv2m4v
|
5
2
|
|
6
3
|
Converts audio and video tracks from a MKV (Matroska Media) container into a
|
@@ -15,12 +12,44 @@ It attempts to pass through as many codecs as possible.
|
|
15
12
|
|
16
13
|
## Installation
|
17
14
|
|
18
|
-
|
19
|
-
|
15
|
+
mkv2m4v is dependent upon `mediainfo`, `mkvextract`, `ffmpeg`, and `MP4Box`.
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ brew install mediainfo
|
19
|
+
$ brew install gpac
|
20
|
+
$ brew install mkvtoolnix
|
21
|
+
$ gem install mkv2m4v
|
22
|
+
```
|
23
|
+
|
24
|
+
_Note: `gpac` includes `MP4Box` and is dependent on `ffmpeg`, so `ffmpeg`
|
25
|
+
should install automatically. If not, you should manually install `ffmpeg`:_
|
26
|
+
|
27
|
+
```bash
|
28
|
+
# ffmpeg should already be installed, but just in case:
|
29
|
+
$ brew install ffmpeg --with-tools
|
30
|
+
```
|
20
31
|
|
21
32
|
## Usage
|
22
33
|
|
23
|
-
|
34
|
+
```bash
|
35
|
+
$ mkv2m4v some-video.mkv
|
36
|
+
```
|
37
|
+
|
38
|
+
## Background
|
39
|
+
|
40
|
+
I got fed up with the reliability of the conversion tools out there for
|
41
|
+
converting MKV video containers to Apple TV compatible videos. Many of the
|
42
|
+
existing tools appear to have potential on the surface, but they fail under
|
43
|
+
certain scenarios.
|
44
|
+
|
45
|
+
[Handbrake](http://handbrake.fr/) is still the most realiable existing tool
|
46
|
+
out there, but it re-encodes h.264 video tracks, which is not ideal and very
|
47
|
+
slow.
|
48
|
+
|
49
|
+
The goal is to get a better, more automated tool to accomplish the task of
|
50
|
+
generating Apple TV compatible videos. Nothing more. It should generate an M4V
|
51
|
+
media file with the best possible quality given the original source and the
|
52
|
+
defaults should require no additional human interaction.
|
24
53
|
|
25
54
|
## Contributing
|
26
55
|
|
data/Rakefile
CHANGED
data/doc/notes.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Extracting tracks from an mkv (assuming correct track numbers):
|
2
|
+
|
3
|
+
$ mediainfo example.mkv # Inspect track IDs
|
4
|
+
$ mkvextract tracks example.mkv 1:example.h264 2:example.dts
|
5
|
+
|
6
|
+
Converting dts to ac3:
|
7
|
+
|
8
|
+
$ ffmpeg -i example.dts -acodec ac3 -ac 6 -ab 640k example-6ch.ac3
|
9
|
+
|
10
|
+
Converting dts to aac:
|
11
|
+
|
12
|
+
$ ffmpeg -i example.dts -acodec libfaac -ac 2 -ab 160k example-2ch.aac
|
13
|
+
|
14
|
+
Converting ac3 to aac:
|
15
|
+
|
16
|
+
$ ffmpeg -i example.ac3 -acodec libfaac -ac 2 -ab 160k example-2ch.aac
|
17
|
+
|
18
|
+
Remux the tracks into an M4V container. For Apple TV surround sound support,
|
19
|
+
the audio tracks must be in the same group with all but the first AAC track
|
20
|
+
disabled. [[source](http://forum.doom9.org/archive/index.php/t-160302.html)]
|
21
|
+
|
22
|
+
$ MP4Box \
|
23
|
+
-add example.h264:lang=en:name="AVC Video" \
|
24
|
+
-add example-2ch.aac:lang=en:group=1:delay=84:name="Stereo" \
|
25
|
+
-add example-6ch.ac3:lang=en:group=1:delay=84:disable:name="AC3" \
|
26
|
+
-new example_testing.m4v
|
data/lib/mkv2m4v/file.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "mkv2m4v/track"
|
2
|
+
require "mkv2m4v/track_ranker"
|
3
|
+
require "mkv2m4v/transcoder"
|
4
|
+
require "mediainfo"
|
5
|
+
require "forwardable"
|
6
|
+
require "iso639"
|
7
|
+
require "colorize"
|
8
|
+
|
9
|
+
module Mkv2m4v
|
10
|
+
class File
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
attr_reader :info, :video_tracks, :audio_tracks, :text_tracks
|
14
|
+
attr_reader :ideal_video_track, :ideal_audio_track
|
15
|
+
def_delegator :info, :filename, :name
|
16
|
+
def_delegator :info, :full_filename, :filename
|
17
|
+
|
18
|
+
def initialize(filename, options = {})
|
19
|
+
@info = Mediainfo.new(filename)
|
20
|
+
@options = options
|
21
|
+
@languages = @options[:languages]
|
22
|
+
init_tracks
|
23
|
+
end
|
24
|
+
|
25
|
+
def format
|
26
|
+
info.general.format
|
27
|
+
end
|
28
|
+
|
29
|
+
def print
|
30
|
+
puts "#{format}: #{name}".black.on_yellow
|
31
|
+
video_tracks.filter.each(&:print) if @options[:verbose]
|
32
|
+
audio_tracks.filter.each(&:print) if @options[:verbose]
|
33
|
+
text_tracks.filter.each(&:print) if @options[:verbose]
|
34
|
+
print_ideal_tracks
|
35
|
+
puts
|
36
|
+
end
|
37
|
+
|
38
|
+
def transcode
|
39
|
+
puts "#{format}: #{name}".black.on_yellow
|
40
|
+
Transcoder.new(self, @options).run
|
41
|
+
puts
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.each(filenames, options = {})
|
45
|
+
filenames.each do |filename|
|
46
|
+
if ::File.exists?(filename)
|
47
|
+
yield new(filename, options)
|
48
|
+
else
|
49
|
+
$stderr.puts "#{filename} does not exist."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def print_ideal_tracks
|
57
|
+
puts "==> Ideal video track"
|
58
|
+
@ideal_video_track.print
|
59
|
+
puts "==> Ideal audio track"
|
60
|
+
@ideal_audio_track.print
|
61
|
+
end
|
62
|
+
|
63
|
+
def init_tracks
|
64
|
+
@video_tracks = tracks_by_type(:video)
|
65
|
+
@audio_tracks = tracks_by_type(:audio)
|
66
|
+
@text_tracks = tracks_by_type(:text)
|
67
|
+
|
68
|
+
@ideal_video_track = video_tracks.filter.rank.first
|
69
|
+
@ideal_audio_track = audio_tracks.filter.rank.first
|
70
|
+
end
|
71
|
+
|
72
|
+
def tracks_by_type(type)
|
73
|
+
info_tracks = info.send(type)
|
74
|
+
tracks = info_tracks.count.times.map do |i|
|
75
|
+
Mkv2m4v.const_get("#{type.capitalize}Track").new(info_tracks[i])
|
76
|
+
end
|
77
|
+
Mkv2m4v.const_get("#{type.capitalize}Ranker").new(tracks, @options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Mkv2m4v
|
4
|
+
class Track
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_reader :info
|
8
|
+
def_delegator :info, :stream_id, :id
|
9
|
+
def_delegators :info, :format
|
10
|
+
|
11
|
+
def initialize(track_info)
|
12
|
+
@info = track_info
|
13
|
+
end
|
14
|
+
|
15
|
+
def language
|
16
|
+
Iso639[info["language"]]
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
info["title"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def format_description
|
24
|
+
"#{format} (#{info.format_info}, #{info.codec_id})"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class VideoTrack < Track
|
29
|
+
def_delegators :info, :frame_size, :interlaced?, :fps, :width, :height
|
30
|
+
|
31
|
+
def resolution
|
32
|
+
"#{frame_size}#{interlaced? ? "i" : "p"}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def print
|
36
|
+
puts "Track #{id}: (video)"
|
37
|
+
puts " Format: #{format_description}"
|
38
|
+
puts " Resolution: #{resolution}"
|
39
|
+
puts " FPS: #{fps}"
|
40
|
+
puts " Language: #{language}"
|
41
|
+
puts " Title: #{title}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class AudioTrack < Track
|
46
|
+
def_delegators :info, :bit_rate
|
47
|
+
|
48
|
+
def channel_count
|
49
|
+
info.channels.to_s.chars.first.to_i
|
50
|
+
end
|
51
|
+
|
52
|
+
def bit_rate_kbps
|
53
|
+
info.bit_rate.gsub(/\D/, "").to_i if info.bit_rate
|
54
|
+
end
|
55
|
+
|
56
|
+
def channel_description
|
57
|
+
"#{channel_count} (#{info.channel_positions})"
|
58
|
+
end
|
59
|
+
|
60
|
+
def bit_rate_description
|
61
|
+
"#{bit_rate_kbps}k (#{info.bit_rate_mode})"
|
62
|
+
end
|
63
|
+
|
64
|
+
def print
|
65
|
+
puts "Track #{id}: (audio)"
|
66
|
+
puts " Format: #{format_description}"
|
67
|
+
puts " Channels: #{channel_description}"
|
68
|
+
puts " Bit rate: #{bit_rate_description}"
|
69
|
+
puts " Language: #{language}"
|
70
|
+
puts " Title: #{title}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class TextTrack < Track
|
75
|
+
def format_description
|
76
|
+
"#{format} (#{info.codec_id})"
|
77
|
+
end
|
78
|
+
|
79
|
+
def print
|
80
|
+
puts "Track #{id}: (text)"
|
81
|
+
puts " Format: #{format_description}"
|
82
|
+
puts " Language: #{language}"
|
83
|
+
puts " Title: #{title}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Mkv2m4v
|
4
|
+
class TrackRanker
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :@tracks, :each, :first
|
8
|
+
|
9
|
+
def initialize(tracks, options = {})
|
10
|
+
@tracks = tracks
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def filter
|
15
|
+
filtered_tracks = @tracks.select { |t| language_okay?(t) }
|
16
|
+
self.class.new(filtered_tracks, @options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def rank
|
20
|
+
ranked_tracks = @tracks.sort_by { |t| score(t) }.reverse
|
21
|
+
self.class.new(ranked_tracks, @options)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def language_match?(track)
|
27
|
+
@options.languages.include?(track.language)
|
28
|
+
end
|
29
|
+
|
30
|
+
def language_okay?(track)
|
31
|
+
track.language.nil? ||
|
32
|
+
@options.languages.empty? ||
|
33
|
+
language_match?(track)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class VideoRanker < TrackRanker
|
38
|
+
def score(track)
|
39
|
+
score = 0
|
40
|
+
score += 8 if track.format == "AVC"
|
41
|
+
score += (track.height || 0)/ 1080.0 * 4.0
|
42
|
+
score += 2 if language_match?(track)
|
43
|
+
score
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class AudioRanker < TrackRanker
|
48
|
+
def score(track)
|
49
|
+
score = 0
|
50
|
+
score += 4 if ["DTS", "AC-3"].include?(track.format)
|
51
|
+
score += 2 if track.format == "AAC"
|
52
|
+
score += (track.channel_count || 0) / 8.0 * 2.0
|
53
|
+
score += (track.bit_rate_kbps || 0) / 1500.0 * 2.0
|
54
|
+
score += 4 if language_match?(track)
|
55
|
+
score
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class TextRanker < TrackRanker
|
60
|
+
# scoring not implemented yet
|
61
|
+
# def score(track)
|
62
|
+
# end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "colorize"
|
3
|
+
|
4
|
+
module Mkv2m4v
|
5
|
+
class Transcoder
|
6
|
+
def initialize(file, options = {})
|
7
|
+
@file = file
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
setup
|
13
|
+
extract
|
14
|
+
transcode_avc
|
15
|
+
transcode_aac
|
16
|
+
transcode_ac3
|
17
|
+
remux
|
18
|
+
cleanup
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def setup
|
24
|
+
FileUtils.mkdir_p tmp_dir
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract
|
28
|
+
puts "==> Extracting #{video_id}:video.#{video_ext} #{audio_id}:audio.#{audio_ext} ".magenta
|
29
|
+
system "mkvextract tracks #{@file.filename.inspect} #{video_id}:#{video_file} #{audio_id}:#{audio_file}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def transcode_avc
|
33
|
+
if video_format == "AVC"
|
34
|
+
puts "==> Assuming pass through for h.264 video track".yellow.on_black
|
35
|
+
else
|
36
|
+
puts "==> ERROR: Wrong Video format".white.on_red
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def transcode_aac
|
41
|
+
if audio_format == "AAC"
|
42
|
+
puts "==> Assuming pass through for AAC audio track".yellow.on_black
|
43
|
+
else
|
44
|
+
puts "==> Transcoding #{audio_format} to Stereo AAC audio track".magenta
|
45
|
+
system "ffmpeg -i #{audio_file.inspect} -acodec libfaac -ac 2 -ab 160k #{audio_basename}.aac"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def transcode_ac3
|
50
|
+
if audio_format == "AC-3"
|
51
|
+
puts "==> Assuming pass through for AC-3 audio track".yellow.on_black
|
52
|
+
elsif audio_format == "AAC"
|
53
|
+
puts "==> Skipping AC-3 surround audio track".yellow.on_black
|
54
|
+
@skip_ac3 = true
|
55
|
+
else
|
56
|
+
puts "==> Transcoding #{audio_format} to Surround AC-3 audio track".magenta
|
57
|
+
system "ffmpeg -i #{audio_file.inspect} -acodec ac3 -ac #{max_audio_channels} -ab #{max_audio_bit_rate}k #{audio_basename}.ac3"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def remux
|
62
|
+
puts "==> Remuxing everything into an M4V container".magenta
|
63
|
+
command = "MP4Box"
|
64
|
+
command << " -add #{video_basename.inspect}.h264:lang=en:name=\"AVC Video\" "
|
65
|
+
command << " -add #{audio_basename.inspect}.aac:lang=en:group=1:delay=84:name=\"Stereo\" "
|
66
|
+
unless @skip_ac3
|
67
|
+
command << " -add #{audio_basename.inspect}.ac3:lang=en:group=1:delay=84:disable:name=\"AC3\" "
|
68
|
+
end
|
69
|
+
command << " -new #{m4v_file.inspect}"
|
70
|
+
system command
|
71
|
+
end
|
72
|
+
|
73
|
+
def cleanup
|
74
|
+
FileUtils.rm_rf tmp_dir
|
75
|
+
end
|
76
|
+
|
77
|
+
def video_basename
|
78
|
+
::File.join(tmp_dir, "video")
|
79
|
+
end
|
80
|
+
|
81
|
+
def video_file
|
82
|
+
[video_basename, video_ext].join(".")
|
83
|
+
end
|
84
|
+
|
85
|
+
def video_id
|
86
|
+
@file.ideal_video_track.id
|
87
|
+
end
|
88
|
+
|
89
|
+
def video_format
|
90
|
+
@file.ideal_video_track.format
|
91
|
+
end
|
92
|
+
|
93
|
+
def video_ext
|
94
|
+
if video_format == "AVC"
|
95
|
+
"h264"
|
96
|
+
else
|
97
|
+
video_format.gsub(/\W/, "").downcase
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def audio_basename
|
102
|
+
::File.join(tmp_dir, "audio")
|
103
|
+
end
|
104
|
+
|
105
|
+
def audio_file
|
106
|
+
[audio_basename, audio_ext].join(".")
|
107
|
+
end
|
108
|
+
|
109
|
+
def audio_id
|
110
|
+
@file.ideal_audio_track.id
|
111
|
+
end
|
112
|
+
|
113
|
+
def audio_format
|
114
|
+
@file.ideal_audio_track.format
|
115
|
+
end
|
116
|
+
|
117
|
+
def audio_ext
|
118
|
+
audio_format.gsub(/\W/, "").downcase
|
119
|
+
end
|
120
|
+
|
121
|
+
def max_audio_channels
|
122
|
+
[@file.ideal_audio_track.channel_count, 6].min
|
123
|
+
end
|
124
|
+
|
125
|
+
def max_audio_bit_rate
|
126
|
+
[@file.ideal_audio_track.bit_rate_kbps, 640].min
|
127
|
+
end
|
128
|
+
|
129
|
+
def dir
|
130
|
+
@options[:dir] || ::File.dirname(@file.filename)
|
131
|
+
end
|
132
|
+
|
133
|
+
def tmp_dir
|
134
|
+
::File.join(dir, ::File.basename(@file.name, ".*") + "-tracks")
|
135
|
+
end
|
136
|
+
|
137
|
+
def m4v_file
|
138
|
+
::File.join(dir, ::File.basename(@file.name, ".*") + ".m4v")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/mkv2m4v/version.rb
CHANGED
data/lib/mkv2m4v.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "mkv2m4v/version"
|
2
|
-
require "mkv2m4v/
|
2
|
+
require "mkv2m4v/file"
|
3
3
|
require "trollop"
|
4
4
|
|
5
5
|
module Mkv2m4v
|
@@ -10,56 +10,17 @@ module Mkv2m4v
|
|
10
10
|
|
11
11
|
def run
|
12
12
|
if @options[:info]
|
13
|
-
|
13
|
+
each_file(&:print)
|
14
14
|
else
|
15
|
-
|
15
|
+
each_file(&:transcode)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
-
def convert_files
|
22
|
-
$stderr.puts "Converting files is not yet supported. For now, try the --info option."
|
23
|
-
# each_file do |file|
|
24
|
-
# end
|
25
|
-
end
|
26
|
-
|
27
|
-
def print_info
|
28
|
-
each_file do |file|
|
29
|
-
info = Mediainfo.new file
|
30
|
-
puts "#{info.general.format}: #{file}"
|
31
|
-
info.video.count.times do |i|
|
32
|
-
print_video_track(info.video[i])
|
33
|
-
end
|
34
|
-
info.audio.count.times do |i|
|
35
|
-
print_audio_track(info.audio[i])
|
36
|
-
end
|
37
|
-
puts
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def print_video_track(video)
|
42
|
-
puts "Video Track #{video.stream_id}:"
|
43
|
-
puts " Format: #{video.format} (#{video.format_info}, #{video.codec_id})"
|
44
|
-
puts " Resolution: #{video.frame_size}#{video.interlaced? ? "i" : "p"}"
|
45
|
-
puts " FPS: #{video.fps}"
|
46
|
-
puts " Language: #{video.language}"
|
47
|
-
end
|
48
|
-
|
49
|
-
def print_audio_track(audio)
|
50
|
-
puts "Audio Track #{audio.stream_id}:"
|
51
|
-
puts " Format: #{audio.format} (#{audio.format_info}, #{audio.codec_id})"
|
52
|
-
puts " Channels: #{audio.channel_count} (#{audio.channel_positions})"
|
53
|
-
puts " Language: #{audio.language}"
|
54
|
-
end
|
55
|
-
|
56
21
|
def each_file
|
57
|
-
|
58
|
-
|
59
|
-
yield file
|
60
|
-
else
|
61
|
-
$stderr.puts "#{file} does not exist."
|
62
|
-
end
|
22
|
+
Mkv2m4v::File.each(@filenames, @options) do |file|
|
23
|
+
yield file
|
63
24
|
end
|
64
25
|
end
|
65
26
|
|
@@ -69,7 +30,12 @@ module Mkv2m4v
|
|
69
30
|
version Mkv2m4v::VersionDescription
|
70
31
|
banner [Mkv2m4v::Description, Mkv2m4v::Usage].join("\n")
|
71
32
|
opt :info, "Print media info only"
|
33
|
+
opt :lang, "Preferred languages", :type => :strings, :default => ["English"]
|
34
|
+
opt :dir, "Destination directory", :type => :string
|
35
|
+
opt :verbose, "More output", :type => :boolean
|
72
36
|
end
|
37
|
+
@options[:languages] = @options[:lang].map { |lang| Iso639[lang] }.compact
|
38
|
+
@filenames = ARGV
|
73
39
|
end
|
74
40
|
end
|
75
41
|
end
|
data/mkv2m4v.gemspec
CHANGED
@@ -17,6 +17,11 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_dependency
|
21
|
-
gem.add_dependency
|
20
|
+
gem.add_dependency "trollop", "~> 2.0"
|
21
|
+
gem.add_dependency "mediainfo", "~> 0.7"
|
22
|
+
gem.add_dependency "iso639", "~> 1.0", ">= 1.0.5"
|
23
|
+
gem.add_dependency "colorize", "~> 0.5"
|
24
|
+
|
25
|
+
gem.add_development_dependency "minitest", "~> 4.3"
|
26
|
+
gem.add_development_dependency "rake", "~> 10.0"
|
22
27
|
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: mkv2m4v
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ryan McGeary
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -43,6 +43,76 @@ dependencies:
|
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0.7'
|
45
45
|
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ~>
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '1.0'
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.5
|
55
|
+
none: false
|
56
|
+
name: iso639
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.0'
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.0.5
|
67
|
+
none: false
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0.5'
|
74
|
+
none: false
|
75
|
+
name: colorize
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.5'
|
83
|
+
none: false
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.3'
|
90
|
+
none: false
|
91
|
+
name: minitest
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
requirement: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '4.3'
|
99
|
+
none: false
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
version_requirements: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ~>
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '10.0'
|
106
|
+
none: false
|
107
|
+
name: rake
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ~>
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '10.0'
|
115
|
+
none: false
|
46
116
|
description: ! 'mkv2m4v is a command line utility that converts audio and video tracks
|
47
117
|
from a
|
48
118
|
|
@@ -62,10 +132,15 @@ files:
|
|
62
132
|
- README.md
|
63
133
|
- Rakefile
|
64
134
|
- bin/mkv2m4v
|
135
|
+
- doc/notes.md
|
65
136
|
- lib/mkv2m4v.rb
|
66
|
-
- lib/mkv2m4v/
|
137
|
+
- lib/mkv2m4v/file.rb
|
138
|
+
- lib/mkv2m4v/track.rb
|
139
|
+
- lib/mkv2m4v/track_ranker.rb
|
140
|
+
- lib/mkv2m4v/transcoder.rb
|
67
141
|
- lib/mkv2m4v/version.rb
|
68
142
|
- mkv2m4v.gemspec
|
143
|
+
- test/test_helper.rb
|
69
144
|
homepage: https://github.com/rmm5t/mkv2m4v
|
70
145
|
licenses: []
|
71
146
|
post_install_message:
|
@@ -90,4 +165,5 @@ rubygems_version: 1.8.23
|
|
90
165
|
signing_key:
|
91
166
|
specification_version: 3
|
92
167
|
summary: Makes Apple TV compatible videos
|
93
|
-
test_files:
|
168
|
+
test_files:
|
169
|
+
- test/test_helper.rb
|