ffprober 0.3.7 → 0.4.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/.ruby-version +1 -1
- data/CONTRIBUTING.md +42 -0
- data/Changes.md +25 -2
- data/README.md +4 -6
- data/ffprober.gemspec +1 -1
- data/lib/ffprober/audio_stream.rb +0 -3
- data/lib/ffprober/chapter.rb +15 -0
- data/lib/ffprober/ffprobe_version.rb +16 -16
- data/lib/ffprober/format.rb +9 -5
- data/lib/ffprober/parser.rb +32 -28
- data/lib/ffprober/stream.rb +9 -7
- data/lib/ffprober/version.rb +1 -1
- data/lib/ffprober/video_stream.rb +0 -3
- data/lib/ffprober.rb +17 -13
- data/spec/assets/sample video.json +177 -0
- data/spec/assets/sample video.m4v +0 -0
- data/spec/assets/version_outputs/osx-2_2_2 +16 -0
- data/spec/assets/version_outputs/osx-2_3_2 +12 -0
- data/spec/ffprober/ffprobe_version_spec.rb +22 -21
- data/spec/ffprober/parser_spec.rb +59 -69
- data/spec/ffprober_spec.rb +8 -8
- data/spec/spec_helper.rb +60 -0
- metadata +15 -9
- data/spec/assets/301-extracting_a_ruby_gem.json +0 -74
- data/spec/assets/301-extracting_a_ruby_gem.m4v +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 335f955c6a41d70b64d1512ce6aacef8884a78a5
|
4
|
+
data.tar.gz: f59078e50164de065d560d8d4cffa03cbd196840
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44f0fd8b01673b663dcfcf5906ff09227d48fe5626cfbe26e98211136ffb0636d839d5258b9bf4ef925b498f7f36ecb56cb956acfd02f8751441acd2d320d66e
|
7
|
+
data.tar.gz: 5823b8621fe69ff3b089c7b626854dadb0782ab04867020ac790bcbca4ce8a2eb6bb85ddf6dd2e3ed85031258ea6f765b531881a0bd2e6a389b549cb2d963c10
|
data/.rspec
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.2
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Contributing
|
2
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
3
|
+
improve this project.
|
4
|
+
|
5
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
6
|
+
|
7
|
+
Here are some ways *you* can contribute:
|
8
|
+
|
9
|
+
* by using alpha, beta, and prerelease versions
|
10
|
+
* by reporting bugs
|
11
|
+
* by suggesting new features
|
12
|
+
* by writing or editing documentation
|
13
|
+
* by writing specifications
|
14
|
+
* by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace )
|
15
|
+
* by refactoring code
|
16
|
+
* by closing [issues][]
|
17
|
+
* by reviewing patches
|
18
|
+
|
19
|
+
[issues]: https://github.com/beanieboi/ffprober/issues
|
20
|
+
|
21
|
+
## Submitting an Issue
|
22
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
23
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
24
|
+
already been submitted. When submitting a bug report, please include a [Gist][]
|
25
|
+
that includes a stack trace and any details that may be necessary to reproduce
|
26
|
+
the bug, including your gem version, Ruby version, and operating system.
|
27
|
+
Ideally, a bug report should include a pull request with failing specs.
|
28
|
+
|
29
|
+
[gist]: https://gist.github.com/
|
30
|
+
|
31
|
+
## Submitting a Pull Request
|
32
|
+
1. [Fork the repository.][fork]
|
33
|
+
2. [Create a topic branch.][branch]
|
34
|
+
3. Implement your feature or bug fix.
|
35
|
+
4. Add, commit, and push your changes.
|
36
|
+
5. [Submit a pull request.][pr]
|
37
|
+
|
38
|
+
[fork]: http://help.github.com/fork-a-repo/
|
39
|
+
[branch]: http://learn.github.com/p/branching.html
|
40
|
+
[pr]: http://help.github.com/send-pull-requests/
|
41
|
+
|
42
|
+
This file was taken from https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md
|
data/Changes.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
0.4.0 / 2014-08-22
|
2
|
+
==================
|
3
|
+
|
4
|
+
* update sample video
|
5
|
+
* set 2.3.2 as new max version
|
6
|
+
* Merge pull request #42 from beanieboi/feature/chapters-new
|
7
|
+
* warn if file to parse does not exist
|
8
|
+
* add Chapters
|
9
|
+
* Merge pull request #41 from beanieboi/feature/refator-specs
|
10
|
+
* update ruby-version to 2.1.2
|
11
|
+
* share specs and add sample json with chapters
|
12
|
+
* use self.options
|
13
|
+
* Merge pull request #40 from beanieboi/feature/refactor
|
14
|
+
* set max version to 2.2.2
|
15
|
+
* fix variable shadowing
|
16
|
+
* allow all object attributes, smaller cleanup
|
17
|
+
* Merge pull request #39 from beanieboi/feature/upgrade-rspec
|
18
|
+
* Merge pull request #38 from mbkulik/ffmpeg-2.2.2-support
|
19
|
+
* update Changes.md
|
20
|
+
* relax rspec dependency and add a sample spec_helper
|
21
|
+
* fix shadowing path in ffprober.rb:15
|
22
|
+
* enable rspec warnings
|
23
|
+
* add CONTRIBUTING.md
|
24
|
+
* Update README.md
|
25
|
+
* some code style fixes
|
3
26
|
|
4
27
|
0.3.7
|
5
28
|
-----------
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
## FFMPEG version
|
29
29
|
|
30
|
-
tested with ffprobe version 0.9
|
30
|
+
tested with ffprobe version 0.9 upto 2.2
|
31
31
|
|
32
32
|
according to [ffmpeg changelog](http://git.videolan.org/?p=ffmpeg.git;a=blob_plain;f=Changelog) json output was added in version 0.9
|
33
33
|
|
@@ -57,11 +57,9 @@ Ffprober is tested under 1.9.3, 2.0, 2.1, JRuby (1.9mode) and Rubinius (1.9mode)
|
|
57
57
|
|
58
58
|
## Contributing
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
-
5. Create new Pull Request
|
60
|
+
see [CONTRIBUTING.md][contributing]
|
61
|
+
|
62
|
+
[contributing]: https://github.com/beanieboi/ffprober/blob/master/CONTRIBUTING.md
|
65
63
|
|
66
64
|
## License
|
67
65
|
|
data/ffprober.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
|
14
14
|
gem.licenses = ['MIT']
|
15
15
|
|
16
|
-
gem.add_development_dependency "rspec", "~> 3.0
|
16
|
+
gem.add_development_dependency "rspec", "~> 3.0"
|
17
17
|
|
18
18
|
gem.files = `git ls-files`.split("\n")
|
19
19
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Ffprober
|
2
|
+
class Chapter
|
3
|
+
def initialize(object_attribute_hash)
|
4
|
+
object_attribute_hash.each do |key, value|
|
5
|
+
instance_variable_set("@#{key}", value)
|
6
|
+
|
7
|
+
unless self.class.method_defined?(key)
|
8
|
+
self.class.send(:define_method, key) do
|
9
|
+
instance_variable_get("@#{key}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module Ffprober
|
2
2
|
class FfprobeVersion
|
3
|
-
|
4
|
-
|
3
|
+
VERSION_REGEX = /^(ffprobe|avprobe|ffmpeg) version (\d+)\.?(\d+)\.?(\d+)*/
|
4
|
+
NIGHTLY_REGEX = /^(ffprobe|avprobe|ffmpeg) version (N|git)-/
|
5
5
|
|
6
|
-
MIN_VERSION = Gem::Version.new(
|
7
|
-
MAX_VERSION = Gem::Version.new(
|
6
|
+
MIN_VERSION = Gem::Version.new('0.9.0')
|
7
|
+
MAX_VERSION = Gem::Version.new('2.3.2')
|
8
8
|
|
9
9
|
def self.valid?
|
10
|
-
|
10
|
+
new.valid?
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.version
|
14
|
+
new.version
|
11
15
|
end
|
12
16
|
|
13
17
|
def valid?
|
@@ -16,26 +20,22 @@ module Ffprober
|
|
16
20
|
|
17
21
|
def parse_version
|
18
22
|
@parse_version ||= begin
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
[_p[2].to_i, _p[3].to_i, _p[4].to_i]
|
24
|
-
end
|
23
|
+
ffprobe_version_output.match(VERSION_REGEX) do |match|
|
24
|
+
[match[2].to_i, match[3].to_i, match[4].to_i]
|
25
|
+
end || [0, 0, 0]
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
def version
|
29
|
-
@version ||= Gem::Version.new(parse_version.join(
|
30
|
+
@version ||= Gem::Version.new(parse_version.join('.'))
|
30
31
|
end
|
31
32
|
|
32
33
|
def nightly?
|
33
|
-
!!(
|
34
|
+
!!(ffprobe_version_output =~ NIGHTLY_REGEX)
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
-
|
38
|
-
@version_output ||= `#{Ffprober.path} -version`
|
37
|
+
def ffprobe_version_output
|
38
|
+
@ffprobe_version_output ||= Ffprober.path.nil? ? '' : `#{Ffprober.path} -version`
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/lib/ffprober/format.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
module Ffprober
|
2
2
|
class Format
|
3
|
-
attr_reader :filename, :nb_streams, :format_name,
|
4
|
-
:format_long_name, :start_time, :duration,
|
5
|
-
:size, :bit_rate
|
6
|
-
|
7
3
|
def initialize(object_attribute_hash)
|
8
|
-
object_attribute_hash.each
|
4
|
+
object_attribute_hash.each do |key, value|
|
5
|
+
instance_variable_set("@#{key}", value)
|
6
|
+
|
7
|
+
unless self.class.method_defined?(key)
|
8
|
+
self.class.send(:define_method, key) do
|
9
|
+
instance_variable_get("@#{key}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
data/lib/ffprober/parser.rb
CHANGED
@@ -1,48 +1,52 @@
|
|
1
1
|
module Ffprober
|
2
2
|
class Parser
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
unless FfprobeVersion.valid?
|
8
|
-
raise ArgumentError.new("no or unsupported ffprobe version found.\
|
9
|
-
(version: #{FfprobeVersion.new.version.to_s})")
|
10
|
-
end
|
11
|
-
|
12
|
-
json_output = `#{Ffprober.path} #{@@options} '#{file_to_parse}'`
|
13
|
-
from_json(json_output)
|
3
|
+
def self.from_file(file_to_parse)
|
4
|
+
unless FfprobeVersion.valid?
|
5
|
+
fail ArgumentError.new("no or unsupported ffprobe version found.\
|
6
|
+
(version: #{FfprobeVersion.new.version})")
|
14
7
|
end
|
15
8
|
|
16
|
-
|
17
|
-
|
18
|
-
parser.parse(json_to_parse)
|
19
|
-
parser
|
9
|
+
unless File.exist?(file_to_parse)
|
10
|
+
fail ArgumentError.new("File not found #{file_to_parse}")
|
20
11
|
end
|
12
|
+
|
13
|
+
json_output = `#{Ffprober.path} #{options} '#{file_to_parse}'`
|
14
|
+
from_json(json_output)
|
21
15
|
end
|
22
16
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
17
|
+
def self.from_json(json_to_parse)
|
18
|
+
parser = new
|
19
|
+
parser.parse(json_to_parse)
|
20
|
+
parser
|
26
21
|
end
|
27
22
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
raise InvalidInputFileError.new("Invalid input file") if json.empty?
|
32
|
-
json
|
33
|
-
end
|
23
|
+
def parse(json_to_parse)
|
24
|
+
fail ArgumentError.new('No JSON input data') if json_to_parse.nil?
|
25
|
+
@json = JSON.parse(json_to_parse, symbolize_names: true)
|
34
26
|
end
|
35
27
|
|
36
28
|
def format
|
37
|
-
@format ||= Ffprober::Format.new(
|
29
|
+
@format ||= Ffprober::Format.new(@json[:format])
|
38
30
|
end
|
39
31
|
|
40
32
|
def video_streams
|
41
|
-
@video_streams ||= stream_by_codec('video').map { |
|
33
|
+
@video_streams ||= stream_by_codec('video').map { |stream| Ffprober::VideoStream.new(stream) }
|
42
34
|
end
|
43
35
|
|
44
36
|
def audio_streams
|
45
|
-
@audio_streams ||= stream_by_codec('audio').map { |
|
37
|
+
@audio_streams ||= stream_by_codec('audio').map { |stream| Ffprober::AudioStream.new(stream) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def chapters
|
41
|
+
@chapters ||= @json[:chapters].map { |chapter| Ffprober::Chapter.new(chapter) }
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def self.options
|
47
|
+
options = '-v quiet -print_format json -show_format -show_streams'
|
48
|
+
options << ' -show_chapters' if FfprobeVersion.version >= Gem::Version.new('2.0.0')
|
49
|
+
options
|
46
50
|
end
|
47
51
|
|
48
52
|
def stream_by_codec(codec_type)
|
@@ -50,7 +54,7 @@ module Ffprober
|
|
50
54
|
end
|
51
55
|
|
52
56
|
def streams
|
53
|
-
|
57
|
+
@json[:streams]
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
data/lib/ffprober/stream.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
module Ffprober
|
2
2
|
class Stream
|
3
|
-
attr_reader :codec_name, :codec_long_name, :codec_type,
|
4
|
-
:codec_time_base, :codec_tag_string, :codec_tag,
|
5
|
-
:r_frame_rate, :avg_frame_rate,
|
6
|
-
:time_base, :start_time, :duration,
|
7
|
-
:nb_frames
|
8
|
-
|
9
3
|
def initialize(object_attribute_hash)
|
10
|
-
object_attribute_hash.each
|
4
|
+
object_attribute_hash.each do |key, value|
|
5
|
+
instance_variable_set("@#{key}", value)
|
6
|
+
|
7
|
+
unless self.class.method_defined?(key)
|
8
|
+
self.class.send(:define_method, key) do
|
9
|
+
instance_variable_get("@#{key}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/lib/ffprober/version.rb
CHANGED
data/lib/ffprober.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
require_relative 'ffprober/version'
|
2
|
+
require_relative 'ffprober/parser'
|
3
|
+
require_relative 'ffprober/format'
|
4
|
+
require_relative 'ffprober/stream'
|
5
|
+
require_relative 'ffprober/audio_stream'
|
6
|
+
require_relative 'ffprober/video_stream'
|
7
|
+
require_relative 'ffprober/chapter'
|
8
|
+
require_relative 'ffprober/ffprobe_version'
|
9
|
+
require 'json'
|
9
10
|
|
10
11
|
module Ffprober
|
11
12
|
def self.path
|
12
|
-
|
13
|
-
|
13
|
+
@path ||= begin
|
14
|
+
path = ENV['PATH'].split(File::PATH_SEPARATOR).find do |path_to_check|
|
15
|
+
File.executable?(File.join(path_to_check, executable_name))
|
16
|
+
end
|
14
17
|
|
15
|
-
|
16
|
-
File.executable?(File.join(path, name))
|
18
|
+
path && File.expand_path(executable_name, path)
|
17
19
|
end
|
20
|
+
end
|
18
21
|
|
19
|
-
|
22
|
+
def self.executable_name
|
23
|
+
@executable_name ||= self.windows? ? 'ffprobe.exe' : 'ffprobe'
|
20
24
|
end
|
21
25
|
|
22
26
|
def self.windows?
|
@@ -0,0 +1,177 @@
|
|
1
|
+
{
|
2
|
+
"streams": [
|
3
|
+
{
|
4
|
+
"index": 0,
|
5
|
+
"codec_name": "aac",
|
6
|
+
"codec_long_name": "AAC (Advanced Audio Coding)",
|
7
|
+
"codec_type": "audio",
|
8
|
+
"codec_time_base": "1/44100",
|
9
|
+
"codec_tag_string": "mp4a",
|
10
|
+
"codec_tag": "0x6134706d",
|
11
|
+
"sample_fmt": "fltp",
|
12
|
+
"sample_rate": "44100",
|
13
|
+
"channels": 2,
|
14
|
+
"channel_layout": "stereo",
|
15
|
+
"bits_per_sample": 0,
|
16
|
+
"r_frame_rate": "0/0",
|
17
|
+
"avg_frame_rate": "0/0",
|
18
|
+
"time_base": "1/44100",
|
19
|
+
"start_pts": 0,
|
20
|
+
"start_time": "0.000000",
|
21
|
+
"duration_ts": 7168,
|
22
|
+
"duration": "0.162540",
|
23
|
+
"bit_rate": "73582",
|
24
|
+
"nb_frames": "7",
|
25
|
+
"disposition": {
|
26
|
+
"default": 1,
|
27
|
+
"dub": 0,
|
28
|
+
"original": 0,
|
29
|
+
"comment": 0,
|
30
|
+
"lyrics": 0,
|
31
|
+
"karaoke": 0,
|
32
|
+
"forced": 0,
|
33
|
+
"hearing_impaired": 0,
|
34
|
+
"visual_impaired": 0,
|
35
|
+
"clean_effects": 0,
|
36
|
+
"attached_pic": 0
|
37
|
+
},
|
38
|
+
"tags": {
|
39
|
+
"creation_time": "2013-12-28 21:17:44",
|
40
|
+
"language": "und",
|
41
|
+
"handler_name": "Core Media Audio"
|
42
|
+
}
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"index": 1,
|
46
|
+
"codec_name": "h264",
|
47
|
+
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
48
|
+
"profile": "Constrained Baseline",
|
49
|
+
"codec_type": "video",
|
50
|
+
"codec_time_base": "1/5000",
|
51
|
+
"codec_tag_string": "avc1",
|
52
|
+
"codec_tag": "0x31637661",
|
53
|
+
"width": 480,
|
54
|
+
"height": 272,
|
55
|
+
"has_b_frames": 0,
|
56
|
+
"sample_aspect_ratio": "0:1",
|
57
|
+
"display_aspect_ratio": "0:1",
|
58
|
+
"pix_fmt": "yuv420p",
|
59
|
+
"level": 21,
|
60
|
+
"r_frame_rate": "25/1",
|
61
|
+
"avg_frame_rate": "25/1",
|
62
|
+
"time_base": "1/2500",
|
63
|
+
"start_pts": 0,
|
64
|
+
"start_time": "0.000000",
|
65
|
+
"duration_ts": 300,
|
66
|
+
"duration": "0.120000",
|
67
|
+
"bit_rate": "79066",
|
68
|
+
"nb_frames": "3",
|
69
|
+
"disposition": {
|
70
|
+
"default": 1,
|
71
|
+
"dub": 0,
|
72
|
+
"original": 0,
|
73
|
+
"comment": 0,
|
74
|
+
"lyrics": 0,
|
75
|
+
"karaoke": 0,
|
76
|
+
"forced": 0,
|
77
|
+
"hearing_impaired": 0,
|
78
|
+
"visual_impaired": 0,
|
79
|
+
"clean_effects": 0,
|
80
|
+
"attached_pic": 0
|
81
|
+
},
|
82
|
+
"tags": {
|
83
|
+
"creation_time": "2013-12-28 21:17:44",
|
84
|
+
"language": "und",
|
85
|
+
"handler_name": "Core Media Video"
|
86
|
+
}
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"index": 2,
|
90
|
+
"codec_name": "mov_text",
|
91
|
+
"codec_long_name": "3GPP Timed Text subtitle",
|
92
|
+
"codec_type": "subtitle",
|
93
|
+
"codec_time_base": "1/1000",
|
94
|
+
"codec_tag_string": "text",
|
95
|
+
"codec_tag": "0x74786574",
|
96
|
+
"r_frame_rate": "0/0",
|
97
|
+
"avg_frame_rate": "0/0",
|
98
|
+
"time_base": "1/1000",
|
99
|
+
"start_pts": 0,
|
100
|
+
"start_time": "0.000000",
|
101
|
+
"duration_ts": 98,
|
102
|
+
"duration": "0.098000",
|
103
|
+
"bit_rate": "5690",
|
104
|
+
"nb_frames": "3",
|
105
|
+
"disposition": {
|
106
|
+
"default": 0,
|
107
|
+
"dub": 0,
|
108
|
+
"original": 0,
|
109
|
+
"comment": 0,
|
110
|
+
"lyrics": 0,
|
111
|
+
"karaoke": 0,
|
112
|
+
"forced": 0,
|
113
|
+
"hearing_impaired": 0,
|
114
|
+
"visual_impaired": 0,
|
115
|
+
"clean_effects": 0,
|
116
|
+
"attached_pic": 0
|
117
|
+
},
|
118
|
+
"tags": {
|
119
|
+
"creation_time": "2013-12-28 21:28:08",
|
120
|
+
"language": "eng"
|
121
|
+
}
|
122
|
+
}
|
123
|
+
],
|
124
|
+
"chapters": [
|
125
|
+
{
|
126
|
+
"id": 0,
|
127
|
+
"time_base": "1/1000",
|
128
|
+
"start": 0,
|
129
|
+
"start_time": "0.000000",
|
130
|
+
"end": 10,
|
131
|
+
"end_time": "0.010000",
|
132
|
+
"tags": {
|
133
|
+
"title": "Chapter 1"
|
134
|
+
}
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"id": 1,
|
138
|
+
"time_base": "1/1000",
|
139
|
+
"start": 10,
|
140
|
+
"start_time": "0.010000",
|
141
|
+
"end": 20,
|
142
|
+
"end_time": "0.020000",
|
143
|
+
"tags": {
|
144
|
+
"title": "Chapter 2"
|
145
|
+
}
|
146
|
+
},
|
147
|
+
{
|
148
|
+
"id": 2,
|
149
|
+
"time_base": "1/1000",
|
150
|
+
"start": 20,
|
151
|
+
"start_time": "0.020000",
|
152
|
+
"end": 97,
|
153
|
+
"end_time": "0.097000",
|
154
|
+
"tags": {
|
155
|
+
"title": "Chapter 3"
|
156
|
+
}
|
157
|
+
}
|
158
|
+
],
|
159
|
+
"format": {
|
160
|
+
"filename": "spec/assets/sample video.m4v",
|
161
|
+
"nb_streams": 3,
|
162
|
+
"nb_programs": 0,
|
163
|
+
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
|
164
|
+
"format_long_name": "QuickTime / MOV",
|
165
|
+
"start_time": "0.000000",
|
166
|
+
"duration": "0.097600",
|
167
|
+
"size": "4611",
|
168
|
+
"bit_rate": "377950",
|
169
|
+
"probe_score": 100,
|
170
|
+
"tags": {
|
171
|
+
"major_brand": "M4V ",
|
172
|
+
"minor_version": "1",
|
173
|
+
"compatible_brands": "M4V M4A mp42isom",
|
174
|
+
"creation_time": "2013-12-28 21:17:44"
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
ffprobe version 2.2.2-tessus Copyright (c) 2007-2014 the FFmpeg developers
|
2
|
+
built on May 7 2014 23:17:42 with clang version 3.3 (tags/RELEASE_33/final)
|
3
|
+
configuration: --cc=/opt/local/bin/clang-mp-3.3 --prefix=/Users/tessus/data/ext/ffmpeg/sw --as=yasm --extra-version=tessus --disable-shared --enable-static --disable-ffplay --enable-gpl --enable-pthreads --enable-postproc --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libx265 --enable-libxvid --enable-libspeex --enable-bzlib --enable-zlib --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libxavs --enable-version3 --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvpx --enable-libgsm --enable-libopus --enable-libmodplug --enable-fontconfig --enable-libfreetype --enable-libass --enable-libbluray --enable-filters --disable-indev=qtkit --enable-runtime-cpudetect
|
4
|
+
libavutil 52. 66.100 / 52. 66.100
|
5
|
+
libavcodec 55. 52.102 / 55. 52.102
|
6
|
+
libavformat 55. 33.100 / 55. 33.100
|
7
|
+
libavdevice 55. 10.100 / 55. 10.100
|
8
|
+
libavfilter 4. 2.100 / 4. 2.100
|
9
|
+
libswscale 2. 5.102 / 2. 5.102
|
10
|
+
libswresample 0. 18.100 / 0. 18.100
|
11
|
+
libpostproc 52. 3.100 / 52. 3.100
|
12
|
+
Simple multimedia streams analyzer
|
13
|
+
usage: ffprobe [OPTIONS] [INPUT_FILE]
|
14
|
+
|
15
|
+
You have to specify one input file.
|
16
|
+
Use -h to get full help or, even better, run 'man ffprobe'.
|
@@ -0,0 +1,12 @@
|
|
1
|
+
ffprobe version 2.3.2 Copyright (c) 2007-2014 the FFmpeg developers
|
2
|
+
built on Aug 22 2014 12:11:42 with Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
|
3
|
+
configuration: --prefix=/usr/local/Cellar/ffmpeg/2.3.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid
|
4
|
+
libavutil 52. 92.100 / 52. 92.100
|
5
|
+
libavcodec 55. 69.100 / 55. 69.100
|
6
|
+
libavformat 55. 48.100 / 55. 48.100
|
7
|
+
libavdevice 55. 13.102 / 55. 13.102
|
8
|
+
libavfilter 4. 11.100 / 4. 11.100
|
9
|
+
libavresample 1. 3. 0 / 1. 3. 0
|
10
|
+
libswscale 2. 6.100 / 2. 6.100
|
11
|
+
libswresample 0. 19.100 / 0. 19.100
|
12
|
+
libpostproc 52. 3.100 / 52. 3.100
|
@@ -3,18 +3,19 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Ffprober::FfprobeVersion do
|
5
5
|
VERSION_CHECKS = [
|
6
|
-
{ version:
|
7
|
-
{ version:
|
8
|
-
{ version:
|
9
|
-
{ version:
|
10
|
-
{ version:
|
11
|
-
{ version:
|
12
|
-
{ version:
|
13
|
-
{ version:
|
14
|
-
{ version:
|
15
|
-
{ version:
|
16
|
-
{ version:
|
17
|
-
{ version:
|
6
|
+
{ version: '0.9.0', pass: true },
|
7
|
+
{ version: '1.0.0', pass: true },
|
8
|
+
{ version: '1.1.0', pass: true },
|
9
|
+
{ version: '2.9.0', pass: false },
|
10
|
+
{ version: '1.2.1', pass: true },
|
11
|
+
{ version: '2.0', pass: true },
|
12
|
+
{ version: '2.0.1', pass: true },
|
13
|
+
{ version: '2.0.2', pass: true },
|
14
|
+
{ version: '2.1.1', pass: true },
|
15
|
+
{ version: '2.1.2', pass: true },
|
16
|
+
{ version: '2.1.4', pass: true },
|
17
|
+
{ version: '2.2', pass: true },
|
18
|
+
{ version: '2.2.2', pass: true }
|
18
19
|
]
|
19
20
|
|
20
21
|
subject(:ffprobe_version) { Ffprober::FfprobeVersion.new }
|
@@ -29,27 +30,27 @@ describe Ffprober::FfprobeVersion do
|
|
29
30
|
end
|
30
31
|
|
31
32
|
describe 'detects the version of ffprobe' do
|
32
|
-
Dir.new(
|
33
|
-
next if [
|
34
|
-
os, expected_version = entry.split(
|
33
|
+
Dir.new('spec/assets/version_outputs').each do |entry|
|
34
|
+
next if ['.', '..', '.DS_Store'].include?(entry)
|
35
|
+
os, expected_version = entry.split('-')
|
35
36
|
|
36
37
|
it "on #{os} from #{expected_version}" do
|
37
|
-
version_output = File.read(
|
38
|
+
version_output = File.read('spec/assets/version_outputs/' + entry)
|
38
39
|
|
39
|
-
allow(ffprobe_version).to receive(:
|
40
|
+
allow(ffprobe_version).to receive(:ffprobe_version_output).and_return(version_output)
|
40
41
|
|
41
|
-
if expected_version ==
|
42
|
+
if expected_version == 'nightly'
|
42
43
|
expect(ffprobe_version.nightly?).to eq(true)
|
43
44
|
expect(ffprobe_version.valid?).to eq(true)
|
44
45
|
else
|
45
|
-
expect(ffprobe_version.version).to eq(Gem::Version.new(expected_version.gsub(
|
46
|
+
expect(ffprobe_version.version).to eq(Gem::Version.new(expected_version.gsub('_', '.')))
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
it
|
51
|
+
it 'should not be valid if no ffprobe could be found in PATH' do
|
51
52
|
allow(Ffprober).to receive(:path).and_return(nil)
|
52
|
-
expect(ffprobe_version.version.to_s).to eq(
|
53
|
+
expect(ffprobe_version.version.to_s).to eq('0.0.0')
|
53
54
|
expect(Ffprober::FfprobeVersion.valid?).to eq(false)
|
54
55
|
end
|
55
56
|
|
@@ -1,103 +1,93 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
|
-
|
4
|
+
def shared_specs
|
5
|
+
describe 'format' do
|
6
|
+
it 'should determine the correct filename' do
|
7
|
+
expect(ffprobe.format.filename).to eq('spec/assets/sample video.m4v')
|
8
|
+
end
|
5
9
|
|
6
|
-
|
7
|
-
|
10
|
+
it 'should find the correct size' do
|
11
|
+
expect(ffprobe.format.size).to eq('4611')
|
12
|
+
end
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
it 'should find the correct bit_rate' do
|
15
|
+
expect(ffprobe.format.bit_rate).to eq('377950')
|
16
|
+
end
|
17
|
+
end
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
19
|
+
describe 'audio_streams' do
|
20
|
+
it 'should determine the correct number of audio streams' do
|
21
|
+
expect(ffprobe.audio_streams.count).to eq(1)
|
22
|
+
end
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
24
|
+
it 'should determine the correct sample rate of the first audio stream' do
|
25
|
+
expect(ffprobe.audio_streams.first.sample_rate).to eq('44100')
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
24
|
-
describe
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
it "should determine the correct filename" do
|
29
|
-
expect(ffprobe.format.filename).to eq("spec/assets/301-extracting_a_ruby_gem.m4v")
|
30
|
-
end
|
29
|
+
describe 'video_streams' do
|
30
|
+
it 'should determine the correct width of the first video streams' do
|
31
|
+
expect(ffprobe.video_streams.first.width).to eq(480)
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
it 'should determine the correct width of the first video streams' do
|
35
|
+
expect(ffprobe.video_streams.first.height).to eq(272)
|
36
|
+
end
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
38
|
+
it 'should determine the correct number of video streams' do
|
39
|
+
expect(ffprobe.video_streams.count).to eq(1)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
describe
|
43
|
-
|
43
|
+
describe 'chapters' do
|
44
|
+
it 'should contain the chapters' do
|
45
|
+
expect(ffprobe.chapters.count).to eq(3)
|
46
|
+
end
|
44
47
|
|
45
|
-
describe
|
46
|
-
|
47
|
-
expect { ffprobe.format.filename }.to raise_error
|
48
|
-
end
|
48
|
+
describe 'chapter' do
|
49
|
+
subject(:chapter) { ffprobe.chapters.first }
|
49
50
|
|
50
|
-
it
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
it
|
55
|
-
|
56
|
-
end
|
51
|
+
it 'should contain id' do expect(chapter.id).to eq(0) end
|
52
|
+
it 'should contain time_base' do expect(chapter.time_base).to eq('1/1000') end
|
53
|
+
it 'should contain start' do expect(chapter.start).to eq(0) end
|
54
|
+
it 'should contain start_time' do expect(chapter.start_time).to eq('0.000000') end
|
55
|
+
it 'should contain end' do expect(chapter.end).to eq(10) end
|
56
|
+
it 'should contain end_time' do expect(chapter.end_time).to eq('0.010000') end
|
57
|
+
it 'should contain tags' do expect(chapter.tags).to eq(title: 'Chapter 1') end
|
57
58
|
end
|
58
59
|
end
|
60
|
+
end
|
59
61
|
|
60
|
-
|
61
|
-
let(:ffprobe) { Ffprober::Parser.from_json(File.read('spec/assets/301-extracting_a_ruby_gem.json')) }
|
62
|
-
|
63
|
-
describe "format" do
|
64
|
-
it "should determine the correct filename" do
|
65
|
-
expect(ffprobe.format.filename).to eq("301-extracting-a-ruby-gem.mp4")
|
66
|
-
end
|
62
|
+
describe Ffprober::Parser do
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
end
|
64
|
+
context 'from_file', if: Ffprober::FfprobeVersion.valid? do
|
65
|
+
let(:ffprobe) { Ffprober::Parser.from_file('spec/assets/sample video.m4v') }
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
67
|
+
shared_specs
|
68
|
+
end
|
76
69
|
|
77
|
-
|
78
|
-
|
79
|
-
expect(ffprobe.audio_streams.count).to eq(1)
|
80
|
-
end
|
70
|
+
context 'from_json' do
|
71
|
+
let(:ffprobe) { Ffprober::Parser.from_json(File.read('spec/assets/sample video.json')) }
|
81
72
|
|
82
|
-
|
83
|
-
|
84
|
-
end
|
73
|
+
shared_specs
|
74
|
+
end
|
85
75
|
|
86
|
-
|
76
|
+
context 'from invalid file', if: Ffprober::FfprobeVersion.valid? do
|
77
|
+
let(:ffprobe) { Ffprober::Parser.from_file('spec/assets/empty_file') }
|
87
78
|
|
88
|
-
describe
|
89
|
-
it
|
90
|
-
expect
|
79
|
+
describe 'format' do
|
80
|
+
it 'should determine the correct filename' do
|
81
|
+
expect { ffprobe.format.filename }.to raise_error
|
91
82
|
end
|
92
83
|
|
93
|
-
it
|
94
|
-
expect
|
84
|
+
it 'should find the correct size' do
|
85
|
+
expect { ffprobe.format.size }.to raise_error
|
95
86
|
end
|
96
87
|
|
97
|
-
it
|
98
|
-
expect
|
88
|
+
it 'should find the correct bit_rate' do
|
89
|
+
expect { ffprobe.format.bit_rate }.to raise_error
|
99
90
|
end
|
100
91
|
end
|
101
92
|
end
|
102
|
-
|
103
93
|
end
|
data/spec/ffprober_spec.rb
CHANGED
@@ -3,21 +3,21 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
describe Ffprober do
|
5
5
|
|
6
|
-
describe
|
7
|
-
it
|
8
|
-
allow(Ffprober).to receive(:path).and_return(
|
6
|
+
describe 'if no ffprobe is found' do
|
7
|
+
it 'should raise a exception if there is no ffmpeg' do
|
8
|
+
allow(Ffprober).to receive(:path).and_return('nonexistant')
|
9
9
|
|
10
|
-
expect
|
10
|
+
expect do
|
11
11
|
Ffprober::Parser.from_file('spec/assets/301-extracting_a_ruby_gem.m4v')
|
12
|
-
|
12
|
+
end.to raise_error
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'should raise a exception if there is no valid ffmpeg' do
|
16
16
|
allow(Ffprober::FfprobeVersion).to receive(:valid?).and_return(false)
|
17
17
|
|
18
|
-
expect
|
18
|
+
expect do
|
19
19
|
Ffprober::Parser.from_file('spec/assets/301-extracting_a_ruby_gem.m4v')
|
20
|
-
|
20
|
+
end.to raise_error(ArgumentError)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1 +1,61 @@
|
|
1
1
|
require 'ffprober'
|
2
|
+
|
3
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# These two settings work together to allow you to limit a spec run
|
6
|
+
# to individual examples or groups you care about by tagging them with
|
7
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
8
|
+
# get run.
|
9
|
+
config.filter_run :focus
|
10
|
+
config.run_all_when_everything_filtered = true
|
11
|
+
|
12
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
13
|
+
# file, and it's useful to allow more verbose output when running an
|
14
|
+
# individual spec file.
|
15
|
+
if config.files_to_run.one?
|
16
|
+
# Use the documentation formatter for detailed output,
|
17
|
+
# unless a formatter has already been configured
|
18
|
+
# (e.g. via a command-line flag).
|
19
|
+
config.default_formatter = 'doc'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Print the 10 slowest examples and example groups at the
|
23
|
+
# end of the spec run, to help surface which specs are running
|
24
|
+
# particularly slow.
|
25
|
+
config.profile_examples = 10
|
26
|
+
|
27
|
+
# Run specs in random order to surface order dependencies. If you find an
|
28
|
+
# order dependency and want to debug it, you can fix the order by providing
|
29
|
+
# the seed, which is printed after each run.
|
30
|
+
# --seed 1234
|
31
|
+
config.order = :random
|
32
|
+
|
33
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
34
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
35
|
+
# test failures related to randomization by passing the same `--seed` value
|
36
|
+
# as the one that triggered the failure.
|
37
|
+
Kernel.srand config.seed
|
38
|
+
|
39
|
+
# rspec-expectations config goes here. You can use an alternate
|
40
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
41
|
+
# assertions if you prefer.
|
42
|
+
config.expect_with :rspec do |expectations|
|
43
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
44
|
+
# For more details, see:
|
45
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
46
|
+
expectations.syntax = :expect
|
47
|
+
end
|
48
|
+
|
49
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
50
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
51
|
+
config.mock_with :rspec do |mocks|
|
52
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
53
|
+
# For more details, see:
|
54
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
55
|
+
mocks.syntax = :expect
|
56
|
+
|
57
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
58
|
+
# a real object. This is generally recommended.
|
59
|
+
mocks.verify_partial_doubles = true
|
60
|
+
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffprober
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- beanieboi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0
|
19
|
+
version: '3.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.0
|
26
|
+
version: '3.0'
|
27
27
|
description: a Ruby wrapper for ffprobe
|
28
28
|
email:
|
29
29
|
- beanie@benle.de
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- ".rspec"
|
36
36
|
- ".ruby-version"
|
37
37
|
- ".travis.yml"
|
38
|
+
- CONTRIBUTING.md
|
38
39
|
- Changes.md
|
39
40
|
- Gemfile
|
40
41
|
- LICENSE
|
@@ -42,6 +43,7 @@ files:
|
|
42
43
|
- ffprober.gemspec
|
43
44
|
- lib/ffprober.rb
|
44
45
|
- lib/ffprober/audio_stream.rb
|
46
|
+
- lib/ffprober/chapter.rb
|
45
47
|
- lib/ffprober/ffprobe_version.rb
|
46
48
|
- lib/ffprober/format.rb
|
47
49
|
- lib/ffprober/parser.rb
|
@@ -49,9 +51,9 @@ files:
|
|
49
51
|
- lib/ffprober/version.rb
|
50
52
|
- lib/ffprober/video_stream.rb
|
51
53
|
- spec/assets/301 extracting a ruby gem.m4v
|
52
|
-
- spec/assets/301-extracting_a_ruby_gem.json
|
53
|
-
- spec/assets/301-extracting_a_ruby_gem.m4v
|
54
54
|
- spec/assets/empty_file
|
55
|
+
- spec/assets/sample video.json
|
56
|
+
- spec/assets/sample video.m4v
|
55
57
|
- spec/assets/version_outputs/linux-nightly
|
56
58
|
- spec/assets/version_outputs/osx-1_0
|
57
59
|
- spec/assets/version_outputs/osx-1_2_0
|
@@ -60,6 +62,8 @@ files:
|
|
60
62
|
- spec/assets/version_outputs/osx-2_1_2
|
61
63
|
- spec/assets/version_outputs/osx-2_1_4
|
62
64
|
- spec/assets/version_outputs/osx-2_2
|
65
|
+
- spec/assets/version_outputs/osx-2_2_2
|
66
|
+
- spec/assets/version_outputs/osx-2_3_2
|
63
67
|
- spec/assets/version_outputs/raspian-0_8_6
|
64
68
|
- spec/assets/version_outputs/ubuntu-0_10_6
|
65
69
|
- spec/assets/version_outputs/windows-nightly
|
@@ -87,15 +91,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
91
|
version: '0'
|
88
92
|
requirements: []
|
89
93
|
rubyforge_project: ffprober
|
90
|
-
rubygems_version: 2.2.
|
94
|
+
rubygems_version: 2.2.2
|
91
95
|
signing_key:
|
92
96
|
specification_version: 4
|
93
97
|
summary: a Ruby wrapper for ffprobe (part of ffmpeg)
|
94
98
|
test_files:
|
95
99
|
- spec/assets/301 extracting a ruby gem.m4v
|
96
|
-
- spec/assets/301-extracting_a_ruby_gem.json
|
97
|
-
- spec/assets/301-extracting_a_ruby_gem.m4v
|
98
100
|
- spec/assets/empty_file
|
101
|
+
- spec/assets/sample video.json
|
102
|
+
- spec/assets/sample video.m4v
|
99
103
|
- spec/assets/version_outputs/linux-nightly
|
100
104
|
- spec/assets/version_outputs/osx-1_0
|
101
105
|
- spec/assets/version_outputs/osx-1_2_0
|
@@ -104,6 +108,8 @@ test_files:
|
|
104
108
|
- spec/assets/version_outputs/osx-2_1_2
|
105
109
|
- spec/assets/version_outputs/osx-2_1_4
|
106
110
|
- spec/assets/version_outputs/osx-2_2
|
111
|
+
- spec/assets/version_outputs/osx-2_2_2
|
112
|
+
- spec/assets/version_outputs/osx-2_3_2
|
107
113
|
- spec/assets/version_outputs/raspian-0_8_6
|
108
114
|
- spec/assets/version_outputs/ubuntu-0_10_6
|
109
115
|
- spec/assets/version_outputs/windows-nightly
|
@@ -1,74 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"streams": [
|
3
|
-
{
|
4
|
-
"index": 0,
|
5
|
-
"codec_name": "h264",
|
6
|
-
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
7
|
-
"codec_type": "video",
|
8
|
-
"codec_time_base": "1/180000",
|
9
|
-
"codec_tag_string": "avc1",
|
10
|
-
"codec_tag": "0x31637661",
|
11
|
-
"width": 960,
|
12
|
-
"height": 600,
|
13
|
-
"has_b_frames": 2,
|
14
|
-
"sample_aspect_ratio": "1:1",
|
15
|
-
"display_aspect_ratio": "8:5",
|
16
|
-
"pix_fmt": "yuv420p",
|
17
|
-
"level": 31,
|
18
|
-
"is_avc": "1",
|
19
|
-
"nal_length_size": "4",
|
20
|
-
"r_frame_rate": "25/1",
|
21
|
-
"avg_frame_rate": "320805000/44607683",
|
22
|
-
"time_base": "1/90000",
|
23
|
-
"start_time": "0.000000",
|
24
|
-
"duration": "991.281844",
|
25
|
-
"nb_frames": "7129",
|
26
|
-
"tags": {
|
27
|
-
"creation_time": "2011-11-21 06:45:09",
|
28
|
-
"language": "und",
|
29
|
-
"handler_name": ""
|
30
|
-
}
|
31
|
-
},
|
32
|
-
{
|
33
|
-
"index": 1,
|
34
|
-
"codec_name": "aac",
|
35
|
-
"codec_long_name": "Advanced Audio Coding",
|
36
|
-
"codec_type": "audio",
|
37
|
-
"codec_time_base": "1/48000",
|
38
|
-
"codec_tag_string": "mp4a",
|
39
|
-
"codec_tag": "0x6134706d",
|
40
|
-
"sample_fmt": "s16",
|
41
|
-
"sample_rate": "48000",
|
42
|
-
"channels": 1,
|
43
|
-
"bits_per_sample": 0,
|
44
|
-
"r_frame_rate": "0/0",
|
45
|
-
"avg_frame_rate": "375/8",
|
46
|
-
"time_base": "1/48000",
|
47
|
-
"start_time": "0.000000",
|
48
|
-
"duration": "991.338667",
|
49
|
-
"nb_frames": "46469",
|
50
|
-
"tags": {
|
51
|
-
"creation_time": "2011-11-21 06:45:09",
|
52
|
-
"language": "eng",
|
53
|
-
"handler_name": ""
|
54
|
-
}
|
55
|
-
}
|
56
|
-
],
|
57
|
-
"format": {
|
58
|
-
"filename": "301-extracting-a-ruby-gem.mp4",
|
59
|
-
"nb_streams": 2,
|
60
|
-
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
|
61
|
-
"format_long_name": "QuickTime/MPEG-4/Motion JPEG 2000 format",
|
62
|
-
"start_time": "0.000000",
|
63
|
-
"duration": "991.338667",
|
64
|
-
"size": "44772490",
|
65
|
-
"bit_rate": "361309",
|
66
|
-
"tags": {
|
67
|
-
"major_brand": "mp42",
|
68
|
-
"minor_version": "0",
|
69
|
-
"compatible_brands": "mp42isomavc1",
|
70
|
-
"creation_time": "2011-11-21 06:45:09",
|
71
|
-
"encoder": "HandBrake 0.9.5 2011010300"
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
Binary file
|