ffprober 0.3.7 → 0.4.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/.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
|