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
- #aspect_rotated? ⇒ Boolean
-
#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
- #ratio ⇒ Object
-
#raw_duration ⇒ Object
The duration of the movie, as a string.
-
#resolution ⇒ Object
width x height, as a string.
- #rotated? ⇒ Boolean
- #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_orientation ⇒ Object
- #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 = [1] else = [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 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
#aspect_rotated? ⇒ Boolean
416 417 418 |
# File 'lib/rvideo/inspector.rb', line 416 def aspect_rotated? video_orientation % 180 == 90 end |
#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
230 231 232 233 |
# File 'lib/rvideo/inspector.rb', line 230 def audio_bit_rate return nil unless audio? audio_match[7].to_i end |
#audio_bit_rate_units ⇒ Object
235 236 237 238 |
# File 'lib/rvideo/inspector.rb', line 235 def audio_bit_rate_units return nil unless audio? audio_match[8] end |
#audio_bit_rate_with_units ⇒ Object
240 241 242 |
# File 'lib/rvideo/inspector.rb', line 240 def audio_bit_rate_with_units "#{audio_bit_rate} #{audio_bit_rate_units}" end |
#audio_channels ⇒ Object
301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'lib/rvideo/inspector.rb', line 301 def audio_channels return nil unless audio? case audio_match[5] when "mono" then 1 when "stereo" then 2 when /(\d+) channels/ then $1.to_i when /^(\d).(\d)$/ then $1.to_i+$2.to_i else raise RuntimeError, "Unknown number of channels" end end |
#audio_channels_string ⇒ Object
The channels used in the audio stream.
Examples:
"stereo"
"mono"
"5:1"
296 297 298 299 |
# File 'lib/rvideo/inspector.rb', line 296 def audio_channels_string return nil unless audio? audio_match[5] end |
#audio_codec ⇒ Object
The audio codec used.
Example:
"aac"
257 258 259 260 |
# File 'lib/rvideo/inspector.rb', line 257 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.
316 317 318 319 |
# File 'lib/rvideo/inspector.rb', line 316 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
268 269 270 271 |
# File 'lib/rvideo/inspector.rb', line 268 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"
279 280 281 282 |
# File 'lib/rvideo/inspector.rb', line 279 def audio_sample_rate_units return nil unless audio? audio_match[4] end |
#audio_sample_rate_with_units ⇒ Object
285 286 287 |
# File 'lib/rvideo/inspector.rb', line 285 def audio_sample_rate_with_units "#{audio_sample_rate} #{audio_sample_rate_units}" end |
#audio_stream ⇒ Object
244 245 246 247 248 249 |
# File 'lib/rvideo/inspector.rb', line 244 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
326 327 328 329 |
# File 'lib/rvideo/inspector.rb', line 326 def audio_stream_id return nil unless audio? audio_match[1] end |
#bitrate ⇒ Object
The bitrate of the movie.
Example:
3132
210 211 212 213 |
# File 'lib/rvideo/inspector.rb', line 210 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"
221 222 223 224 |
# File 'lib/rvideo/inspector.rb', line 221 def bitrate_units return nil unless valid? bitrate_match[2] end |
#bitrate_with_units ⇒ Object
226 227 228 |
# File 'lib/rvideo/inspector.rb', line 226 def bitrate_with_units "#{bitrate} #{bitrate_units}" end |
#codec_time_base ⇒ Object
458 459 460 461 |
# File 'lib/rvideo/inspector.rb', line 458 def codec_time_base return nil unless video? video_match[15] 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()[1] end |
#display_aspect_ratio ⇒ Object
425 426 427 428 |
# File 'lib/rvideo/inspector.rb', line 425 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"
447 448 449 450 |
# File 'lib/rvideo/inspector.rb', line 447 def fps return nil unless video? video_match[2] || video_match[13] || video_match[14] end |
#height ⇒ Object
The height of the video in pixels.
381 382 383 384 385 386 387 388 |
# File 'lib/rvideo/inspector.rb', line 381 def height return nil unless video? if aspect_rotated? video_match[5].to_i else video_match[6].to_i end 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
420 421 422 423 |
# File 'lib/rvideo/inspector.rb', line 420 def pixel_aspect_ratio return nil unless video? video_match[7] end |
#ratio ⇒ Object
199 200 201 202 |
# File 'lib/rvideo/inspector.rb', line 199 def ratio return nil unless valid? width.to_f / height.to_f 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()[1] end |
#resolution ⇒ Object
width x height, as a string.
Examples:
320x240
1280x720
396 397 398 399 |
# File 'lib/rvideo/inspector.rb', line 396 def resolution return nil unless video? "#{width}x#{height}" end |
#rotated? ⇒ Boolean
412 413 414 |
# File 'lib/rvideo/inspector.rb', line 412 def rotated? video_orientation != 0 end |
#time_base ⇒ Object
453 454 455 456 |
# File 'lib/rvideo/inspector.rb', line 453 def time_base return nil unless video? video_match[14] 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.
431 432 433 434 |
# File 'lib/rvideo/inspector.rb', line 431 def video_bit_rate return nil unless video? video_match[9] end |
#video_bit_rate_units ⇒ Object
436 437 438 439 |
# File 'lib/rvideo/inspector.rb', line 436 def video_bit_rate_units return nil unless video? video_match[10] end |
#video_codec ⇒ Object
The video codec used.
Example:
"mpeg4"
354 355 356 357 |
# File 'lib/rvideo/inspector.rb', line 354 def video_codec return nil unless video? video_match[3] end |
#video_colorspace ⇒ Object
The colorspace of the video stream.
Example:
"yuv420p"
365 366 367 368 |
# File 'lib/rvideo/inspector.rb', line 365 def video_colorspace return nil unless video? video_match[4] end |
#video_orientation ⇒ Object
401 402 403 404 405 406 407 408 409 410 |
# File 'lib/rvideo/inspector.rb', line 401 def video_orientation stdout='' stderr='' open4.spawn "qtrotate #{full_filename}", :stdout=> stdout, :timeout => 10, :stderr => stderr @orientation ||= stdout.chomp.to_i rescue Timeout::Error 0 rescue 0 end |
#video_stream ⇒ Object
331 332 333 334 335 336 |
# File 'lib/rvideo/inspector.rb', line 331 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
343 344 345 346 |
# File 'lib/rvideo/inspector.rb', line 343 def video_stream_id return nil unless video? video_match[1] end |
#width ⇒ Object
The width of the video in pixels.
371 372 373 374 375 376 377 378 |
# File 'lib/rvideo/inspector.rb', line 371 def width return nil unless video? if aspect_rotated? video_match[6].to_i else video_match[5].to_i end end |