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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9720e6501e9017095339eeeda71ea175a478645
4
- data.tar.gz: 1779005a50673b1ef183320d7702287ef9186bfa
3
+ metadata.gz: 335f955c6a41d70b64d1512ce6aacef8884a78a5
4
+ data.tar.gz: f59078e50164de065d560d8d4cffa03cbd196840
5
5
  SHA512:
6
- metadata.gz: bb08ab86f81c9c662c708954bad57a92dc49f77ada054d5828b2f5df7ae7d95a646ef2ac0b55ce729aa3fff47330aa3223677ef3e49982ac4a1bb3c37634337f
7
- data.tar.gz: ee31e032b48e4a923df8a4f31525874a80dcac433747039310e069ad40b68ed8d8c9993c5067961d41886b9ccce5f21381231049e640d73685520dcd889db0c4
6
+ metadata.gz: 44f0fd8b01673b663dcfcf5906ff09227d48fe5626cfbe26e98211136ffb0636d839d5258b9bf4ef925b498f7f36ecb56cb956acfd02f8751441acd2d320d66e
7
+ data.tar.gz: 5823b8621fe69ff3b089c7b626854dadb0782ab04867020ac790bcbca4ce8a2eb6bb85ddf6dd2e3ed85031258ea6f765b531881a0bd2e6a389b549cb2d963c10
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --warnings
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.0
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
- MASTER
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, 0.10, 0.11, 1.0, 1.1 and 1.2
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
- 1. Fork it
61
- 2. Create your feature branch (`git checkout -b my-new-feature`)
62
- 3. Commit your changes (`git commit -am 'Added some feature'`)
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.0.beta1"
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) }
@@ -1,7 +1,4 @@
1
1
  module Ffprober
2
2
  class AudioStream < Stream
3
- attr_accessor :sample_fmt, :sample_rate, :channels,
4
- :bits_per_sample
5
-
6
3
  end
7
4
  end
@@ -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
- @@version_regex = /^(ffprobe|avprobe|ffmpeg) version (\d+)\.?(\d+)\.?(\d+)*/
4
- @@nightly_regex = /^(ffprobe|avprobe|ffmpeg) version (N|git)-/
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("0.9.0")
7
- MAX_VERSION = Gem::Version.new("2.2")
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
- self.new.valid?
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
- _p = version_output.match(@@version_regex)
20
- if _p.nil?
21
- [0, 0, 0]
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
- !!(version_output =~ @@nightly_regex)
34
+ !!(ffprobe_version_output =~ NIGHTLY_REGEX)
34
35
  end
35
36
 
36
- def version_output
37
- return "" if Ffprober.path.nil?
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
@@ -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 {|k,v| instance_variable_set("@#{k}",v)}
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
@@ -1,48 +1,52 @@
1
1
  module Ffprober
2
2
  class Parser
3
- @@options = '-v quiet -print_format json -show_format -show_streams'
4
-
5
- class << self
6
- def from_file(file_to_parse)
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
- def from_json(json_to_parse)
17
- parser = self.new
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 parse(json_to_parse)
24
- raise ArgumentError.new("No JSON found") if json_to_parse.nil?
25
- @json_to_parse = json_to_parse
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 parsed_json
29
- @parsed_json ||= begin
30
- json = JSON.parse(@json_to_parse, symbolize_names: true)
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(parsed_json[:format])
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 { |s| Ffprober::VideoStream.new(s) }
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 { |s| Ffprober::AudioStream.new(s) }
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
- parsed_json[:streams]
57
+ @json[:streams]
54
58
  end
55
59
  end
56
60
  end
@@ -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 {|k,v| instance_variable_set("@#{k}",v)}
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
@@ -1,3 +1,3 @@
1
1
  module Ffprober
2
- VERSION = "0.3.7"
2
+ VERSION = '0.4.0'
3
3
  end
@@ -1,7 +1,4 @@
1
1
  module Ffprober
2
2
  class VideoStream < Stream
3
- attr_accessor :width, :height, :has_b_frames,
4
- :sample_aspect_ratio, :display_aspect_ratio,
5
- :pix_fmt, :level, :is_avc, :nal_length_size, :bit_rate
6
3
  end
7
4
  end
data/lib/ffprober.rb CHANGED
@@ -1,22 +1,26 @@
1
- require "ffprober/version"
2
- require "ffprober/parser"
3
- require "ffprober/format"
4
- require "ffprober/stream"
5
- require "ffprober/audio_stream"
6
- require "ffprober/video_stream"
7
- require "ffprober/ffprobe_version"
8
- require "json"
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
- name = 'ffprobe'
13
- name << '.exe' if self.windows?
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
- path = ENV['PATH'].split(File::PATH_SEPARATOR).find do |path|
16
- File.executable?(File.join(path, name))
18
+ path && File.expand_path(executable_name, path)
17
19
  end
20
+ end
18
21
 
19
- path && File.expand_path(name, path)
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: "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 }
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("spec/assets/version_outputs").each do |entry|
33
- next if [".", "..", ".DS_Store"].include?(entry)
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("spec/assets/version_outputs/" + entry)
38
+ version_output = File.read('spec/assets/version_outputs/' + entry)
38
39
 
39
- allow(ffprobe_version).to receive(:version_output).and_return(version_output)
40
+ allow(ffprobe_version).to receive(:ffprobe_version_output).and_return(version_output)
40
41
 
41
- if expected_version == "nightly"
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 "should not be valid if no ffprobe could be found in PATH" do
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("0.0.0")
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
- describe Ffprober::Parser do
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
- describe "from_file with whitespace", if: Ffprober::FfprobeVersion.valid? do
7
- let(:ffprobe) { Ffprober::Parser.from_file('spec/assets/301 extracting a ruby gem.m4v') }
10
+ it 'should find the correct size' do
11
+ expect(ffprobe.format.size).to eq('4611')
12
+ end
8
13
 
9
- describe "format" do
10
- it "should determine the correct filename" do
11
- expect(ffprobe.format.filename).to eq("spec/assets/301 extracting a ruby gem.m4v")
12
- end
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
- it "should find the correct size" do
15
- expect(ffprobe.format.size).to eq("130694")
16
- end
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
- it "should find the correct bit_rate" do
19
- expect(ffprobe.format.bit_rate).to eq("502669")
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 "from_file", if: Ffprober::FfprobeVersion.valid? do
25
- let(:ffprobe) { Ffprober::Parser.from_file('spec/assets/301-extracting_a_ruby_gem.m4v') }
26
-
27
- describe "format" do
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
- it "should find the correct size" do
33
- expect(ffprobe.format.size).to eq("130694")
34
- end
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
- it "should find the correct bit_rate" do
37
- expect(ffprobe.format.bit_rate).to eq("502669")
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 "from invalid file", if: Ffprober::FfprobeVersion.valid? do
43
- let(:ffprobe) { Ffprober::Parser.from_file('spec/assets/empty_file') }
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 "format" do
46
- it "should determine the correct filename" do
47
- expect { ffprobe.format.filename }.to raise_error
48
- end
48
+ describe 'chapter' do
49
+ subject(:chapter) { ffprobe.chapters.first }
49
50
 
50
- it "should find the correct size" do
51
- expect { ffprobe.format.size }.to raise_error
52
- end
53
-
54
- it "should find the correct bit_rate" do
55
- expect { ffprobe.format.bit_rate }.to raise_error
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
- describe "from_json" do
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
- it "should find the correct size" do
69
- expect(ffprobe.format.size).to eq("44772490")
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
- it "should find the correct bit_rate" do
73
- expect(ffprobe.format.bit_rate).to eq("361309")
74
- end
75
- end
67
+ shared_specs
68
+ end
76
69
 
77
- describe "audio_streams" do
78
- it "should determine the correct number of audio streams" do
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
- it "should determine the correct sample rate of the first audio stream" do
83
- expect(ffprobe.audio_streams.first.sample_rate).to eq("48000")
84
- end
73
+ shared_specs
74
+ end
85
75
 
86
- end
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 "video_streams" do
89
- it "should determine the correct width of the first video streams" do
90
- expect(ffprobe.video_streams.first.width).to eq(960)
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 "should determine the correct width of the first video streams" do
94
- expect(ffprobe.video_streams.first.height).to eq(600)
84
+ it 'should find the correct size' do
85
+ expect { ffprobe.format.size }.to raise_error
95
86
  end
96
87
 
97
- it "should determine the correct number of video streams" do
98
- expect(ffprobe.video_streams.count).to eq(1)
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
@@ -3,21 +3,21 @@ require 'spec_helper'
3
3
 
4
4
  describe Ffprober do
5
5
 
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")
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
- }.to raise_error
12
+ end.to raise_error
13
13
  end
14
14
 
15
- it "should raise a exception if there is no valid ffmpeg" do
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
- }.to raise_error(ArgumentError)
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.3.7
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-04-13 00:00:00.000000000 Z
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.0.beta1
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.0.beta1
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.0
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
- }