ffsplitter 0.0.6 → 0.1.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/.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
|