Class: RVideo::Inspector
- Inherits:
-
Object
- Object
- RVideo::Inspector
- Defined in:
- lib/rvideo/inspector.rb
Overview
To inspect a video or audio file, initialize an Inspector object.
file = RVideo::Inspector.new()
Inspector accepts three options: file, raw_response, and ffmpeg_binary. Either raw_response or file is required; ffmpeg binary is optional.
:file is a path to a file to be inspected.
:raw_response is the full output of “ffmpeg -i [file]”. If the :raw_response option is used, RVideo will not actually inspect a file; it will simply parse the provided response. This is useful if your application has already collected the ffmpeg -i response, and you don’t want to call it again.
:ffmpeg_binary is an optional argument that specifies the path to the ffmpeg binary to be used. If a path is not explicitly declared, RVideo will assume that ffmpeg exists in the Unix path. Type “which ffmpeg” to check if ffmpeg is installed and exists in your operating system’s path.
Instance Attribute Summary collapse
-
#ffmpeg_binary ⇒ Object
Returns the value of attribute ffmpeg_binary.
-
#filename ⇒ Object
readonly
Returns the value of attribute filename.
-
#full_filename ⇒ Object
readonly
Returns the value of attribute full_filename.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#raw_metadata ⇒ Object
readonly
Returns the value of attribute raw_metadata.
-
#raw_response ⇒ Object
readonly
Returns the value of attribute raw_response.
Instance Method Summary collapse
-
#audio? ⇒ Boolean
Does the file have an audio stream?.
- #audio_bit_rate ⇒ Object
- #audio_bit_rate_units ⇒ Object
- #audio_bit_rate_with_units ⇒ Object
- #audio_channels ⇒ Object
-
#audio_channels_string ⇒ Object
The channels used in the audio stream.
-
#audio_codec ⇒ Object
The audio codec used.
-
#audio_sample_bit_depth ⇒ Object
This should almost always return 16, as the vast majority of audio is 16 bit.
-
#audio_sample_rate ⇒ Object
The sampling rate of the audio stream.
-
#audio_sample_rate_units ⇒ Object
(also: #audio_sample_units)
The units used for the sampling rate.
- #audio_sample_rate_with_units ⇒ Object
- #audio_stream ⇒ Object
-
#audio_stream_id ⇒ Object
The ID of the audio stream (useful for troubleshooting).
-
#bitrate ⇒ Object
The bitrate of the movie.
-
#bitrate_units ⇒ Object
The bitrate units used.
- #bitrate_with_units ⇒ Object
- #codec_time_base ⇒ Object
-
#container ⇒ Object
Returns the container format for the file.
- #display_aspect_ratio ⇒ Object
-
#duration ⇒ Object
The duration of the movie in milliseconds, as an integer.
-
#ffmpeg_build ⇒ Object
Returns the build description for ffmpeg.
-
#ffmpeg_configuration ⇒ Object
Returns the configuration options used to build ffmpeg.
-
#ffmpeg_libav ⇒ Object
Returns the versions of libavutil, libavcodec, and libavformat used by ffmpeg.
-
#ffmpeg_version ⇒ Object
Returns the version of ffmpeg used, In practice, this may or may not be useful.
-
#fps ⇒ Object
(also: #framerate)
The frame rate of the video in frames per second.
-
#height ⇒ Object
The height of the video in pixels.
-
#initialize(options = {}) ⇒ Inspector
constructor
A new instance of Inspector.
- #initialize_with_file(file, ffmpeg_binary = nil) ⇒ Object
- #initialize_with_raw_response(raw_response) ⇒ Object
-
#invalid? ⇒ Boolean
Returns false if the file can be read successfully.
- #pixel_aspect_ratio ⇒ Object
-
#raw_duration ⇒ Object
The duration of the movie, as a string.
-
#resolution ⇒ Object
width x height, as a string.
- #time_base ⇒ Object
-
#unknown_format? ⇒ Boolean
True if the format is not understood (“Unknown Format”).
-
#unreadable_file? ⇒ Boolean
True if the file is not readable (“Duration: N/A, bitrate: N/A”).
-
#valid? ⇒ Boolean
Returns true if the file can be read successfully.
-
#video? ⇒ Boolean
Does the file have a video stream?.
-
#video_bit_rate ⇒ Object
The portion of the overall bitrate the video is responsible for.
- #video_bit_rate_units ⇒ Object
-
#video_codec ⇒ Object
The video codec used.
-
#video_colorspace ⇒ Object
The colorspace of the video stream.
- #video_stream ⇒ Object
-
#video_stream_id ⇒ Object
The ID of the video stream (useful for troubleshooting).
-
#width ⇒ Object
The width of the video in pixels.
Constructor Details
#initialize(options = {}) ⇒ Inspector
Returns a new instance of Inspector.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rvideo/inspector.rb', line 26 def initialize( = {}) if not ([:raw_response] or [:file]) raise ArgumentError, "Must supply either an input file or a pregenerated response" end if [:raw_response] initialize_with_raw_response([:raw_response]) elsif [:file] initialize_with_file([:file], [:ffmpeg_binary]) end = /(Input \#.*)\n(Must|At\sleast)/m.match(@raw_response) # metadata = /(Input \#.*)\n.+\n\Z/m.match(@raw_response) if /Unknown format/i.match(@raw_response) || .nil? @unknown_format = true elsif /Duration: N\/A/im.match(@raw_response) # in this case, we can at least still get the container type @unreadable_file = true @raw_metadata = [1] else @raw_metadata = [1] end end |
Instance Attribute Details
#ffmpeg_binary ⇒ Object
Returns the value of attribute ffmpeg_binary.
24 25 26 |
# File 'lib/rvideo/inspector.rb', line 24 def ffmpeg_binary @ffmpeg_binary end |
#filename ⇒ Object (readonly)
Returns the value of attribute filename.
22 23 24 |
# File 'lib/rvideo/inspector.rb', line 22 def filename @filename end |
#full_filename ⇒ Object (readonly)
Returns the value of attribute full_filename.
22 23 24 |
# File 'lib/rvideo/inspector.rb', line 22 def full_filename @full_filename end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
22 23 24 |
# File 'lib/rvideo/inspector.rb', line 22 def path @path end |
#raw_metadata ⇒ Object (readonly)
Returns the value of attribute raw_metadata.
22 23 24 |
# File 'lib/rvideo/inspector.rb', line 22 def @raw_metadata end |
#raw_response ⇒ Object (readonly)
Returns the value of attribute raw_response.
22 23 24 |
# File 'lib/rvideo/inspector.rb', line 22 def raw_response @raw_response end |
Instance Method Details
#audio? ⇒ Boolean
Does the file have an audio stream?
101 102 103 |
# File 'lib/rvideo/inspector.rb', line 101 def audio? not audio_match.nil? end |
#audio_bit_rate ⇒ Object
225 226 227 228 |
# File 'lib/rvideo/inspector.rb', line 225 def audio_bit_rate return nil unless audio? audio_match[7].to_i end |
#audio_bit_rate_units ⇒ Object
230 231 232 233 |
# File 'lib/rvideo/inspector.rb', line 230 def audio_bit_rate_units return nil unless audio? audio_match[8] end |
#audio_bit_rate_with_units ⇒ Object
235 236 237 |
# File 'lib/rvideo/inspector.rb', line 235 def audio_bit_rate_with_units "#{audio_bit_rate} #{audio_bit_rate_units}" end |
#audio_channels ⇒ Object
296 297 298 299 300 301 302 303 304 305 |
# File 'lib/rvideo/inspector.rb', line 296 def audio_channels return nil unless audio? case audio_match[5] when "mono" then 1 when "stereo" then 2 else raise RuntimeError, "Unknown number of channels: #{audio_channels}" end end |
#audio_channels_string ⇒ Object
The channels used in the audio stream.
Examples:
"stereo"
"mono"
"5:1"
291 292 293 294 |
# File 'lib/rvideo/inspector.rb', line 291 def audio_channels_string return nil unless audio? audio_match[5] end |
#audio_codec ⇒ Object
The audio codec used.
Example:
"aac"
252 253 254 255 |
# File 'lib/rvideo/inspector.rb', line 252 def audio_codec return nil unless audio? audio_match[2] end |
#audio_sample_bit_depth ⇒ Object
This should almost always return 16, as the vast majority of audio is 16 bit.
309 310 311 312 |
# File 'lib/rvideo/inspector.rb', line 309 def audio_sample_bit_depth return nil unless audio? audio_match[6].to_i end |
#audio_sample_rate ⇒ Object
The sampling rate of the audio stream.
Example:
44100
263 264 265 266 |
# File 'lib/rvideo/inspector.rb', line 263 def audio_sample_rate return nil unless audio? audio_match[3].to_i end |
#audio_sample_rate_units ⇒ Object Also known as: audio_sample_units
The units used for the sampling rate. May always be Hz.
Example:
"Hz"
274 275 276 277 |
# File 'lib/rvideo/inspector.rb', line 274 def audio_sample_rate_units return nil unless audio? audio_match[4] end |
#audio_sample_rate_with_units ⇒ Object
280 281 282 |
# File 'lib/rvideo/inspector.rb', line 280 def audio_sample_rate_with_units "#{audio_sample_rate} #{audio_sample_rate_units}" end |
#audio_stream ⇒ Object
239 240 241 242 243 244 |
# File 'lib/rvideo/inspector.rb', line 239 def audio_stream return nil unless valid? match = /\n\s*Stream.*Audio:.*\n/.match(@raw_response) match[0].strip if match end |
#audio_stream_id ⇒ Object
The ID of the audio stream (useful for troubleshooting).
Example:
#0.1
319 320 321 322 |
# File 'lib/rvideo/inspector.rb', line 319 def audio_stream_id return nil unless audio? audio_match[1] end |
#bitrate ⇒ Object
The bitrate of the movie.
Example:
3132
205 206 207 208 |
# File 'lib/rvideo/inspector.rb', line 205 def bitrate return nil unless valid? bitrate_match[1].to_i end |
#bitrate_units ⇒ Object
The bitrate units used. In practice, this may always be kb/s.
Example:
"kb/s"
216 217 218 219 |
# File 'lib/rvideo/inspector.rb', line 216 def bitrate_units return nil unless valid? bitrate_match[2] end |
#bitrate_with_units ⇒ Object
221 222 223 |
# File 'lib/rvideo/inspector.rb', line 221 def bitrate_with_units "#{bitrate} #{bitrate_units}" end |
#codec_time_base ⇒ Object
424 425 426 427 |
# File 'lib/rvideo/inspector.rb', line 424 def codec_time_base return nil unless video? video_match[13] end |
#container ⇒ Object
Returns the container format for the file. Instead of returning a single format, this may return a string of related formats.
Examples:
"avi"
"mov,mp4,m4a,3gp,3g2,mj2"
166 167 168 169 |
# File 'lib/rvideo/inspector.rb', line 166 def container return nil if @unknown_format /Input \#\d+\,\s*(\S+),\s*from/.match(@raw_metadata)[1] end |
#display_aspect_ratio ⇒ Object
391 392 393 394 |
# File 'lib/rvideo/inspector.rb', line 391 def display_aspect_ratio return nil unless video? video_match[8] end |
#duration ⇒ Object
The duration of the movie in milliseconds, as an integer.
Example:
24400 # 24.4 seconds
Note that the precision of the duration is in tenths of a second, not thousandths, but milliseconds are a more standard unit of time than deciseconds.
192 193 194 195 196 197 |
# File 'lib/rvideo/inspector.rb', line 192 def duration return nil unless valid? units = raw_duration.split(":") (units[0].to_i * 60 * 60 * 1000) + (units[1].to_i * 60 * 1000) + (units[2].to_f * 1000).to_i end |
#ffmpeg_build ⇒ Object
Returns the build description for ffmpeg.
Example:
built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build
5250)
153 154 155 |
# File 'lib/rvideo/inspector.rb', line 153 def ffmpeg_build /(\n\s*)(built on.*)(\n)/.match(@raw_response)[2] end |
#ffmpeg_configuration ⇒ Object
Returns the configuration options used to build ffmpeg.
Example:
--enable-mp3lame --enable-gpl --disable-ffplay --disable-ffserver
--enable-a52 --enable-xvid
129 130 131 |
# File 'lib/rvideo/inspector.rb', line 129 def ffmpeg_configuration /(\s*configuration:)(.*)\n/.match(@raw_response)[2].strip end |
#ffmpeg_libav ⇒ Object
Returns the versions of libavutil, libavcodec, and libavformat used by ffmpeg.
Example:
libavutil version: 49.0.0
libavcodec version: 51.9.0
libavformat version: 50.4.0
142 143 144 |
# File 'lib/rvideo/inspector.rb', line 142 def ffmpeg_libav /^(\s*lib.*\n)+/.match(@raw_response)[0].split("\n").each {|l| l.strip! } end |
#ffmpeg_version ⇒ Object
Returns the version of ffmpeg used, In practice, this may or may not be useful.
Examples:
SVN-r6399
CVS
118 119 120 |
# File 'lib/rvideo/inspector.rb', line 118 def ffmpeg_version @ffmpeg_version = @raw_response.split("\n").first.split("version").last.split(",").first.strip end |
#fps ⇒ Object Also known as: framerate
The frame rate of the video in frames per second
Example:
"29.97"
413 414 415 416 |
# File 'lib/rvideo/inspector.rb', line 413 def fps return nil unless video? video_match[2] or video_match[11] end |
#height ⇒ Object
The height of the video in pixels.
370 371 372 373 |
# File 'lib/rvideo/inspector.rb', line 370 def height return nil unless video? video_match[6].to_i end |
#initialize_with_file(file, ffmpeg_binary = nil) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rvideo/inspector.rb', line 55 def initialize_with_file(file, ffmpeg_binary = nil) if ffmpeg_binary @ffmpeg_binary = ffmpeg_binary if not FileTest.exist?(@ffmpeg_binary) raise "ffmpeg could not be found (trying #{@ffmpeg_binary})" end else # assume it is in the unix path if not FileTest.exist?(`which ffmpeg`.chomp) raise "ffmpeg could not be found (expected ffmpeg to be found in the Unix path)" end @ffmpeg_binary = "ffmpeg" end if not FileTest.exist?(file.gsub('"','')) raise TranscoderError::InputFileNotFound, "File not found (#{file})" end @full_filename = file @filename = File.basename(@full_filename) @path = File.dirname(@full_filename) @raw_response = `#{@ffmpeg_binary} -i #{@full_filename.shell_quoted} 2>&1` end |
#initialize_with_raw_response(raw_response) ⇒ Object
51 52 53 |
# File 'lib/rvideo/inspector.rb', line 51 def initialize_with_raw_response(raw_response) @raw_response = raw_response end |
#invalid? ⇒ Boolean
Returns false if the file can be read successfully. Returns false otherwise.
86 87 88 |
# File 'lib/rvideo/inspector.rb', line 86 def invalid? not valid? end |
#pixel_aspect_ratio ⇒ Object
386 387 388 389 |
# File 'lib/rvideo/inspector.rb', line 386 def pixel_aspect_ratio return nil unless video? video_match[7] end |
#raw_duration ⇒ Object
The duration of the movie, as a string.
Example:
"00:00:24.4" # 24.4 seconds
177 178 179 180 |
# File 'lib/rvideo/inspector.rb', line 177 def raw_duration return nil unless valid? /Duration:\s*([0-9\:\.]+),/.match(@raw_metadata)[1] end |
#resolution ⇒ Object
width x height, as a string.
Examples:
320x240
1280x720
381 382 383 384 |
# File 'lib/rvideo/inspector.rb', line 381 def resolution return nil unless video? "#{width}x#{height}" end |
#time_base ⇒ Object
419 420 421 422 |
# File 'lib/rvideo/inspector.rb', line 419 def time_base return nil unless video? video_match[12] end |
#unknown_format? ⇒ Boolean
True if the format is not understood (“Unknown Format”)
91 92 93 |
# File 'lib/rvideo/inspector.rb', line 91 def unknown_format? @unknown_format ? true : false end |
#unreadable_file? ⇒ Boolean
True if the file is not readable (“Duration: N/A, bitrate: N/A”)
96 97 98 |
# File 'lib/rvideo/inspector.rb', line 96 def unreadable_file? @unreadable_file ? true : false end |
#valid? ⇒ Boolean
Returns true if the file can be read successfully. Returns false otherwise.
81 82 83 |
# File 'lib/rvideo/inspector.rb', line 81 def valid? not (@unknown_format or @unreadable_file) end |
#video? ⇒ Boolean
Does the file have a video stream?
106 107 108 |
# File 'lib/rvideo/inspector.rb', line 106 def video? not video_match.nil? end |
#video_bit_rate ⇒ Object
The portion of the overall bitrate the video is responsible for.
397 398 399 400 |
# File 'lib/rvideo/inspector.rb', line 397 def video_bit_rate return nil unless video? video_match[9] end |
#video_bit_rate_units ⇒ Object
402 403 404 405 |
# File 'lib/rvideo/inspector.rb', line 402 def video_bit_rate_units return nil unless video? video_match[10] end |
#video_codec ⇒ Object
The video codec used.
Example:
"mpeg4"
347 348 349 350 |
# File 'lib/rvideo/inspector.rb', line 347 def video_codec return nil unless video? video_match[3] end |
#video_colorspace ⇒ Object
The colorspace of the video stream.
Example:
"yuv420p"
358 359 360 361 |
# File 'lib/rvideo/inspector.rb', line 358 def video_colorspace return nil unless video? video_match[4] end |
#video_stream ⇒ Object
324 325 326 327 328 329 |
# File 'lib/rvideo/inspector.rb', line 324 def video_stream return nil unless valid? match = /\n\s*Stream.*Video:.*\n/.match(@raw_response) match[0].strip unless match.nil? end |
#video_stream_id ⇒ Object
The ID of the video stream (useful for troubleshooting).
Example:
#0.0
336 337 338 339 |
# File 'lib/rvideo/inspector.rb', line 336 def video_stream_id return nil unless video? video_match[1] end |
#width ⇒ Object
The width of the video in pixels.
364 365 366 367 |
# File 'lib/rvideo/inspector.rb', line 364 def width return nil unless video? video_match[5].to_i end |