ffsplitter 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/README.md +9 -1
- data/lib/ffsplitter/args_parser.rb +28 -0
- data/lib/ffsplitter/ffmpeg.rb +7 -6
- data/lib/ffsplitter/splitter.rb +3 -3
- data/lib/ffsplitter/version.rb +1 -1
- data/lib/ffsplitter.rb +3 -1
- data/spec/args_parser_spec.rb +26 -0
- data/spec/end_to_end_spec.rb +20 -9
- data/spec/ffmpeg_spec.rb +10 -10
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fb73758a42682d9201bd6caf2162ededcabcd8c
|
4
|
+
data.tar.gz: 65ce4c8b8095c4b2b0eb2bf92e6ccfeb40d862ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9da2d2e7b5e9d3aa745e2a749b353ffb87ab599e6bba2245f4254126acf0c88b2a1fb67c0651af3e8230f24364e01d6e165e4136e5913bc17c6f179674b7f16
|
7
|
+
data.tar.gz: 6db5c5acb233d025be1508ecd4b0c5492430f013827052e5694c3268416826b0b71fce29cf9f37a560981fbbb21acea50c82441cdabe569925114999a2e3e698
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/README.md
CHANGED
@@ -9,10 +9,18 @@
|
|
9
9
|
|
10
10
|
`ffsplitter my-video.mp4`
|
11
11
|
|
12
|
-
or
|
12
|
+
or
|
13
13
|
|
14
14
|
`ffsplitter my-video.mp4 output-directory/`
|
15
15
|
|
16
|
+
Output files will use the same extension as the input file. For custom output
|
17
|
+
extensions, pass the -e option
|
18
|
+
|
19
|
+
`ffsplitter my-video.mp4 -e .aac`
|
20
|
+
|
21
|
+
This will produce audio-only .aac files for each chapter. NOTE: codecs are copied
|
22
|
+
from the source file, so you must use an compatible extension
|
23
|
+
|
16
24
|
## Testing
|
17
25
|
|
18
26
|
`bundle exec rspec`
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
class ArgsParser
|
5
|
+
DEFAULT_OPTIONS = {
|
6
|
+
audio_only: false
|
7
|
+
}
|
8
|
+
|
9
|
+
def self.parse!(args)
|
10
|
+
options = OpenStruct.new(DEFAULT_OPTIONS)
|
11
|
+
options.filename = args[0]
|
12
|
+
|
13
|
+
parser = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: ffsplitter test.mp4 [options]"
|
15
|
+
|
16
|
+
opts.on("-e", "--output-extension EXTENSION", "Output extension") do |ext|
|
17
|
+
options.output_extension = ext
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on("-o", "--output-path PATH", "Output path") do |dir|
|
21
|
+
options.output_path = File.expand_path(dir)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
parser.parse!(args)
|
26
|
+
options
|
27
|
+
end
|
28
|
+
end
|
data/lib/ffsplitter/ffmpeg.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module FFSplitter
|
2
2
|
class FFMpeg
|
3
3
|
CODEC_OPTIONS= "-c copy -movflags faststart"
|
4
|
-
attr_accessor :filename, :
|
4
|
+
attr_accessor :filename, :output_path, :runner, :output_extension
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@filename
|
8
|
-
@
|
6
|
+
def initialize(options)
|
7
|
+
@filename = options[:filename]
|
8
|
+
@output_path = options[:output_path]
|
9
|
+
@output_extension = options[:output_extension] || File.extname(@filename)
|
9
10
|
@runner = CommandRunner
|
10
11
|
end
|
11
12
|
|
@@ -19,8 +20,8 @@ module FFSplitter
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def chapter_command(chapter)
|
22
|
-
output_file = File.expand_path(chapter.filename,
|
23
|
-
"ffmpeg -ss #{chapter.start_time} -i '#{filename}' -t #{chapter.duration} #{CODEC_OPTIONS} '#{output_file}
|
23
|
+
output_file = File.expand_path(chapter.filename, output_path)
|
24
|
+
"ffmpeg -ss #{chapter.start_time} -i '#{filename}' -t #{chapter.duration} #{CODEC_OPTIONS} '#{output_file}#{output_extension}'"
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
data/lib/ffsplitter/splitter.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module FFSplitter
|
2
2
|
class Splitter
|
3
|
-
def self.split_via_ffmpeg(
|
4
|
-
split(FFMpeg.new(
|
3
|
+
def self.split_via_ffmpeg(options)
|
4
|
+
split(FFMpeg.new(options))
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.split(codec)
|
@@ -10,4 +10,4 @@ module FFSplitter
|
|
10
10
|
codec.encode(chapter_list)
|
11
11
|
end
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
data/lib/ffsplitter/version.rb
CHANGED
data/lib/ffsplitter.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "ffsplitter/version"
|
2
|
+
require "ffsplitter/args_parser"
|
2
3
|
require "ffsplitter/metadata_parser"
|
3
4
|
require "ffsplitter/chapter"
|
4
5
|
require "ffsplitter/chapter_list"
|
@@ -21,7 +22,8 @@ module FFSplitter
|
|
21
22
|
puts "WTF mate?"
|
22
23
|
exit(1)
|
23
24
|
else
|
24
|
-
|
25
|
+
options = ArgsParser.parse!(@argv)
|
26
|
+
Splitter.split_via_ffmpeg(options)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ArgsParser do
|
4
|
+
let(:options) { ArgsParser.parse!(args) }
|
5
|
+
|
6
|
+
context "with an input file" do
|
7
|
+
let(:args) { ["test.mp4"] }
|
8
|
+
specify do
|
9
|
+
expect(options.filename).to eq("test.mp4")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "output_extension" do
|
14
|
+
let(:args) { ["-e", ".mp3"] }
|
15
|
+
specify do
|
16
|
+
expect(options.output_extension).to eq(".mp3")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "output_file" do
|
21
|
+
let(:args) { ["-o", "test/"] }
|
22
|
+
specify do
|
23
|
+
expect(options.output_path).to eq(File.expand_path("test/"))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/end_to_end_spec.rb
CHANGED
@@ -5,15 +5,26 @@ module FFSplitter
|
|
5
5
|
before { Dir.mkdir("tmp") unless Dir.exist?("tmp") }
|
6
6
|
|
7
7
|
describe "split" do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
context "with audio and video" do
|
9
|
+
before { `bundle exec ruby -Ilib bin/ffsplitter 'spec/fixtures/test video.mp4' -o tmp 2>&1` }
|
10
|
+
let(:file_list) { Dir.glob("tmp/*") }
|
11
|
+
it "creates files" do
|
12
|
+
expect(file_list).to include("tmp/01 Chapter 1.mp4")
|
13
|
+
expect(file_list).to include("tmp/02 - Chapter 2.mp4")
|
14
|
+
expect(file_list).to include("tmp/03 Chapter 3.mp4")
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
+
context "with audio only" do
|
19
|
+
before { `bundle exec ruby -Ilib bin/ffsplitter 'spec/fixtures/test video.mp4' -e .aac -o tmp 2>&1` }
|
20
|
+
let(:file_list) { Dir.glob("tmp/*") }
|
21
|
+
it "creates files" do
|
22
|
+
expect(file_list).to include("tmp/01 Chapter 1.aac")
|
23
|
+
expect(file_list).to include("tmp/02 - Chapter 2.aac")
|
24
|
+
expect(file_list).to include("tmp/03 Chapter 3.aac")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
after { FileUtils.rm(file_list) }
|
28
|
+
end
|
18
29
|
end
|
19
|
-
end
|
30
|
+
end
|
data/spec/ffmpeg_spec.rb
CHANGED
@@ -2,13 +2,12 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module FFSplitter
|
4
4
|
describe FFMpeg do
|
5
|
-
let(:
|
6
|
-
let(:output_directory) { nil }
|
7
|
-
let(:ffmpeg){ FFMpeg.new(filename, output_directory) }
|
5
|
+
let(:ffmpeg){ FFMpeg.new(options) }
|
8
6
|
let(:runner) { double("runner") }
|
9
7
|
before { ffmpeg.runner = runner }
|
10
8
|
|
11
9
|
describe "#encode" do
|
10
|
+
let(:options) { {filename: "test.mp4"} }
|
12
11
|
let(:chapter_list) { ChapterList.new }
|
13
12
|
let(:chapter1) { Chapter.new(title: "Chapter 1") }
|
14
13
|
let(:chapter2) { Chapter.new(title: "Chapter 2") }
|
@@ -35,22 +34,22 @@ module FFSplitter
|
|
35
34
|
end
|
36
35
|
|
37
36
|
describe "#chapter_command" do
|
38
|
-
let(:command) { ffmpeg.chapter_command(chapter) }
|
39
37
|
let(:chapter) { Chapter.new(start_frames: 10, end_frames: 30, timebase: 1, title: "test title") }
|
40
|
-
|
38
|
+
let(:command) { ffmpeg.chapter_command(chapter) }
|
41
39
|
context "without an output directory" do
|
42
|
-
let(:
|
40
|
+
let(:options) { {filename: "test.mp4", output_extension: ".m4v"} }
|
43
41
|
it "creates a chapter command" do
|
44
42
|
expect(command).to match("-ss #{chapter.start_time}")
|
45
|
-
expect(command).to match("-i '
|
43
|
+
expect(command).to match("-i 'test.mp4'")
|
46
44
|
expect(command).to match("-t #{chapter.duration}")
|
45
|
+
expect(command).to match("test title.m4v")
|
47
46
|
expect(command).to match(FFSplitter::FFMpeg::CODEC_OPTIONS)
|
48
47
|
expect(command).to match("#{File.expand_path(chapter.filename)}")
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
51
|
context "with an output directory" do
|
53
|
-
let(:
|
52
|
+
let(:options) { {filename: "test.mp4", output_path: File.expand_path("test_dir/")} }
|
54
53
|
it "creates returns the path to that directory" do
|
55
54
|
expect(command).to match("#{File.expand_path(chapter.filename, "test_dir")}")
|
56
55
|
end
|
@@ -58,9 +57,10 @@ module FFSplitter
|
|
58
57
|
end
|
59
58
|
|
60
59
|
describe "#read_metadata" do
|
60
|
+
let(:options) { {filename: "test.mp4"} }
|
61
61
|
it "reads the metadata" do
|
62
|
-
expect(runner).to receive(:run).with("ffmpeg -i 'test.mp4' -v quiet -f ffmetadata -")
|
63
|
-
ffmpeg.read_metadata
|
62
|
+
expect(runner).to receive(:run).with("ffmpeg -i 'test.mp4' -v quiet -f ffmetadata -").and_return "meta"
|
63
|
+
expect(ffmpeg.read_metadata).to eq("meta")
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffsplitter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rockwood
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -75,6 +75,7 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- .gitignore
|
78
|
+
- .rspec
|
78
79
|
- Gemfile
|
79
80
|
- LICENSE.txt
|
80
81
|
- README.md
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- bin/ffsplitter
|
83
84
|
- ffsplitter.gemspec
|
84
85
|
- lib/ffsplitter.rb
|
86
|
+
- lib/ffsplitter/args_parser.rb
|
85
87
|
- lib/ffsplitter/chapter.rb
|
86
88
|
- lib/ffsplitter/chapter_list.rb
|
87
89
|
- lib/ffsplitter/command_runner.rb
|
@@ -89,6 +91,7 @@ files:
|
|
89
91
|
- lib/ffsplitter/metadata_parser.rb
|
90
92
|
- lib/ffsplitter/splitter.rb
|
91
93
|
- lib/ffsplitter/version.rb
|
94
|
+
- spec/args_parser_spec.rb
|
92
95
|
- spec/chapter_list_spec.rb
|
93
96
|
- spec/chapter_spec.rb
|
94
97
|
- spec/end_to_end_spec.rb
|
@@ -123,6 +126,7 @@ signing_key:
|
|
123
126
|
specification_version: 4
|
124
127
|
summary: ffsplitter will split a video file by its chapters
|
125
128
|
test_files:
|
129
|
+
- spec/args_parser_spec.rb
|
126
130
|
- spec/chapter_list_spec.rb
|
127
131
|
- spec/chapter_spec.rb
|
128
132
|
- spec/end_to_end_spec.rb
|