Class: Ffmprb::File
- Inherits:
-
Object
- Object
- Ffmprb::File
- Defined in:
- lib/ffmprb/file.rb,
lib/ffmprb/file/sample.rb
Class Attribute Summary collapse
-
.image_extname_regex ⇒ Object
Returns the value of attribute image_extname_regex.
-
.movie_extname_regex ⇒ Object
Returns the value of attribute movie_extname_regex.
-
.sound_extname_regex ⇒ Object
Returns the value of attribute sound_extname_regex.
Class Method Summary collapse
-
.async_opener(file, mode) ⇒ Object
NOTE must be timeout-safe.
- .create(path) ⇒ Object
- .image?(extname) ⇒ Boolean
- .movie?(extname) ⇒ Boolean
- .open(path) ⇒ Object
- .sound?(extname) ⇒ Boolean
- .temp(extname) ⇒ Object
- .temp_fifo(extname = '.tmp', &blk) ⇒ Object
- .temp_fifo_path(extname) ⇒ Object
- .threaded_buffered_fifo(extname = '.tmp') ⇒ Object
Instance Method Summary collapse
- #channel?(medium) ⇒ Boolean
-
#exist? ⇒ Boolean
Info.
- #extname ⇒ Object
-
#initialize(path:, mode:) ⇒ File
constructor
A new instance of File.
- #length ⇒ Object
- #path ⇒ Object
-
#read ⇒ Object
Manipulation.
- #remove ⇒ Object
- #resolution ⇒ Object
- #sample(at: 0.01, video: true, audio: true, &blk) ⇒ Object
- #sample_audio(*audio, at: 0.01, &blk) ⇒ Object
- #sample_video(*video, at: 0.01, &blk) ⇒ Object
- #write(s) ⇒ Object
Constructor Details
#initialize(path:, mode:) ⇒ File
Returns a new instance of File.
104 105 106 107 108 109 110 |
# File 'lib/ffmprb/file.rb', line 104 def initialize(path:, mode:) @path = path @path.close if @path && @path.respond_to?(:close) # NOTE specially for temp files path! # NOTE early (exception) raiser @mode = mode.to_sym fail Error, "Open for read, create for write, ??? for #{@mode}" unless i[read write].include?(@mode) end |
Class Attribute Details
.image_extname_regex ⇒ Object
Returns the value of attribute image_extname_regex.
11 12 13 |
# File 'lib/ffmprb/file.rb', line 11 def image_extname_regex @image_extname_regex end |
.movie_extname_regex ⇒ Object
Returns the value of attribute movie_extname_regex.
11 12 13 |
# File 'lib/ffmprb/file.rb', line 11 def movie_extname_regex @movie_extname_regex end |
.sound_extname_regex ⇒ Object
Returns the value of attribute sound_extname_regex.
11 12 13 |
# File 'lib/ffmprb/file.rb', line 11 def sound_extname_regex @sound_extname_regex end |
Class Method Details
.async_opener(file, mode) ⇒ Object
NOTE must be timeout-safe
82 83 84 85 86 87 |
# File 'lib/ffmprb/file.rb', line 82 def async_opener(file, mode) ->{ Ffmprb.logger.debug "Trying to open #{file.path} for #{mode}-buffering" ::File.open(file.path, mode) } end |
.create(path) ⇒ Object
34 35 36 37 38 |
# File 'lib/ffmprb/file.rb', line 34 def create(path) new(path: path, mode: :write).tap do |file| Ffmprb.logger.debug "Created file with path: #{file.path}" end end |
.image?(extname) ⇒ Boolean
89 90 91 |
# File 'lib/ffmprb/file.rb', line 89 def image?(extname) extname =~ image_extname_regex end |
.movie?(extname) ⇒ Boolean
97 98 99 |
# File 'lib/ffmprb/file.rb', line 97 def movie?(extname) extname =~ movie_extname_regex end |
.open(path) ⇒ Object
40 41 42 43 44 |
# File 'lib/ffmprb/file.rb', line 40 def open(path) new(path: (path.respond_to?(:path)? path.path : path), mode: :read).tap do |file| Ffmprb.logger.debug "Opened file with path: #{file.path}" end end |
.sound?(extname) ⇒ Boolean
93 94 95 |
# File 'lib/ffmprb/file.rb', line 93 def sound?(extname) extname =~ sound_extname_regex end |
.temp(extname) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/ffmprb/file.rb', line 46 def temp(extname) file = create(Tempfile.new(['', extname])) Ffmprb.logger.debug "Created temp file with path: #{file.path}" return file unless block_given? begin yield file ensure begin FileUtils.remove_entry file.path rescue Ffmprb.logger.warn "Error removing temp file with path #{file.path}: #{$!.message}" end Ffmprb.logger.debug "Removed temp file with path: #{file.path}" end end |
.temp_fifo(extname = '.tmp', &blk) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ffmprb/file.rb', line 64 def temp_fifo(extname='.tmp', &blk) fifo_file = create(temp_fifo_path extname) ::File.mkfifo fifo_file.path return fifo_file unless block_given? begin yield fifo_file ensure fifo_file.remove end end |
.temp_fifo_path(extname) ⇒ Object
77 78 79 |
# File 'lib/ffmprb/file.rb', line 77 def temp_fifo_path(extname) ::File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('', 'p' + extname) end |
.threaded_buffered_fifo(extname = '.tmp') ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/ffmprb/file.rb', line 13 def threaded_buffered_fifo(extname='.tmp') input_fifo_file = temp_fifo(extname) output_fifo_file = temp_fifo(extname) Ffmprb.logger.debug "Opening #{input_fifo_file.path}>#{output_fifo_file.path} for buffering" Util::Thread.new do begin Util::ThreadedIoBuffer.new async_opener(input_fifo_file, 'r'), async_opener(output_fifo_file, 'w') Util::Thread.join_children! Ffmprb.logger.debug "IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} ended" ensure input_fifo_file.remove if input_fifo_file output_fifo_file.remove if output_fifo_file end end Ffmprb.logger.debug "IoBuffering from #{input_fifo_file.path} to #{output_fifo_file.path} started" # TODO see threaded_io_buffer's XXXs: yield buff if block_given? [input_fifo_file, output_fifo_file] end |
Instance Method Details
#channel?(medium) ⇒ Boolean
126 127 128 129 130 131 132 133 |
# File 'lib/ffmprb/file.rb', line 126 def channel?(medium) case medium when :video self.class.image?(extname) || self.class.movie?(extname) when :audio self.class.sound?(extname) || self.class.movie?(extname) end end |
#exist? ⇒ Boolean
Info
118 119 120 |
# File 'lib/ffmprb/file.rb', line 118 def exist? ::File.exist? path end |
#extname ⇒ Object
122 123 124 |
# File 'lib/ffmprb/file.rb', line 122 def extname ::File.extname path end |
#length ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ffmprb/file.rb', line 135 def length return @duration if @duration # NOTE first attempt @duration = probe['format']['duration'] @duration &&= @duration.to_f return @duration if @duration # NOTE a harder try @duration = probe(true)['frames'].reduce(0) do |sum, frame| sum + frame['pkt_duration_time'].to_f end end |
#path ⇒ Object
112 113 114 |
# File 'lib/ffmprb/file.rb', line 112 def path path! end |
#read ⇒ Object
Manipulation
157 158 159 |
# File 'lib/ffmprb/file.rb', line 157 def read ::File.read path end |
#remove ⇒ Object
164 165 166 167 168 |
# File 'lib/ffmprb/file.rb', line 164 def remove FileUtils.remove_entry path Ffmprb.logger.debug "Removed file with path: #{path}" @path = nil end |
#resolution ⇒ Object
149 150 151 152 |
# File 'lib/ffmprb/file.rb', line 149 def resolution v_stream = probe['streams'].first "#{v_stream['width']}x#{v_stream['height']}" end |
#sample(at: 0.01, video: true, audio: true, &blk) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/ffmprb/file/sample.rb', line 5 def sample( at: 0.01, video: true, audio: true, &blk ) audio = File.temp('.wav') if audio == true video = File.temp('.png') if video == true Ffmprb.logger.debug "Snap shooting files, video path: #{video ? video.path : 'NONE'}, audio path: #{audio ? audio.path : 'NONE'}" fail Error, "Incorrect output extname (must be image)" unless !video || video.channel?(:video) && !video.channel?(:audio) fail Error, "Incorrect audio extname (must be sound)" unless !audio || audio.channel?(:audio) && !audio.channel?(:video) fail Error, "Can sample either video OR audio UNLESS a block is given" unless block_given? || !!audio != !!video cmd = %W[-i #{path}] cmd.concat %W[-deinterlace -an -ss #{at} -r 1 -vcodec mjpeg -f mjpeg #{video.path}] if video cmd.concat %W[-vn -ss #{at} -t 1 #{audio.path}] if audio Util.ffmpeg *cmd return video || audio unless block_given? begin yield *[video || nil, audio || nil].compact ensure begin video.remove if video audio.remove if audio Ffmprb.logger.debug "Removed sample files" rescue Ffmprb.logger.warn "Error removing sample files: #{$!.message}" end end end |
#sample_audio(*audio, at: 0.01, &blk) ⇒ Object
42 43 44 |
# File 'lib/ffmprb/file/sample.rb', line 42 def sample_audio(*audio, at: 0.01, &blk) sample at: at, video: false, audio: (audio.first || true), &blk end |
#sample_video(*video, at: 0.01, &blk) ⇒ Object
39 40 41 |
# File 'lib/ffmprb/file/sample.rb', line 39 def sample_video(*video, at: 0.01, &blk) sample at: at, video: (video.first || true), audio: false, &blk end |
#write(s) ⇒ Object
160 161 162 |
# File 'lib/ffmprb/file.rb', line 160 def write(s) ::File.write path, s end |