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 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
- }