Class: Aspera::Preview::Utils
- Inherits:
 - 
      Object
      
        
- Object
 - Aspera::Preview::Utils
 
 
- Defined in:
 - lib/aspera/preview/utils.rb
 
Class Method Summary collapse
- 
  
    
      .check_tools(skip_types = [])  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
check that external tools can be executed.
 - 
  
    
      .external_command(command_sym, command_args, check_code: true)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
execute external command one could use “system”, but we would need to redirect stdout/err.
 - .ffmpeg(a) ⇒ Object
 - .ffmpeg_fmt(temp_folder) ⇒ Object
 - .get_tmp_num_filepath(temp_folder, file_number) ⇒ Object
 - 
  
    
      .shell_quote(argument)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
returns string with single quotes suitable for bash if there is any bash meta-character.
 - .video_blend_frames(temp_folder, index1, index2) ⇒ Object
 - .video_dump_frame(input_file, offset_seconds, scale, output_file, index = nil) ⇒ Object
 - .video_dupe_frame(temp_folder, index, count) ⇒ Object
 - 
  
    
      .video_get_duration(input_file)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Float in seconds.
 
Class Method Details
.check_tools(skip_types = []) ⇒ Object
check that external tools can be executed
      30 31 32 33 34 35 36 37 38 39 40 41  | 
    
      # File 'lib/aspera/preview/utils.rb', line 30 def check_tools(skip_types=[]) tools_to_check = EXTERNAL_TOOLS.dup tools_to_check.delete(:unoconv) if skip_types.include?(:office) # Check for binaries tools_to_check.each do |command_sym| external_command(command_sym, ['-h'], check_code: false) rescue Errno::ENOENT => e raise "missing #{command_sym} binary: #{e}" rescue nil end end  | 
  
.external_command(command_sym, command_args, check_code: true) ⇒ Object
execute external command one could use “system”, but we would need to redirect stdout/err
      46 47 48 49 50 51 52 53 54 55 56 57 58 59  | 
    
      # File 'lib/aspera/preview/utils.rb', line 46 def external_command(command_sym, command_args, check_code: true) Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'} # build command line, and quote special characters command_line = command_args.clone.unshift(command_sym).map{|i| shell_quote(i.to_s)}.join(' ') Log.log.debug{"cmd=#{command_line}".blue} stdout, stderr, status = Open3.capture3(command_line) if check_code && !status.success? Log.log.error{"status: #{status}"} Log.log.error{"stdout: #{stdout}"} Log.log.error{"stderr: #{stderr}"} raise "#{command_sym} error #{status}" end return {status: status, stdout: stdout} end  | 
  
.ffmpeg(a) ⇒ Object
      61 62 63 64 65 66 67 68 69 70 71 72  | 
    
      # File 'lib/aspera/preview/utils.rb', line 61 def ffmpeg(a) Aspera.assert_type(a, Hash) # input_file,input_args,output_file,output_args a[:gl_p] ||= [ '-y', # overwrite output without asking '-loglevel', 'error' # show only errors and up ] a[:in_p] ||= [] a[:out_p] ||= [] Aspera.assert(%i[gl_p in_f in_p out_f out_p].eql?(a.keys.sort)){"wrong params (#{a.keys.sort})"} external_command(:ffmpeg, [a[:gl_p], a[:in_p], '-i', a[:in_f], a[:out_p], a[:out_f]].flatten) end  | 
  
.ffmpeg_fmt(temp_folder) ⇒ Object
      84 85 86  | 
    
      # File 'lib/aspera/preview/utils.rb', line 84 def ffmpeg_fmt(temp_folder) return File.join(temp_folder, TEMP_FORMAT) end  | 
  
.get_tmp_num_filepath(temp_folder, file_number) ⇒ Object
      88 89 90  | 
    
      # File 'lib/aspera/preview/utils.rb', line 88 def get_tmp_num_filepath(temp_folder, file_number) return File.join(temp_folder, format(TEMP_FORMAT, file_number)) end  | 
  
.shell_quote(argument) ⇒ Object
returns string with single quotes suitable for bash if there is any bash meta-character
      23 24 25 26 27  | 
    
      # File 'lib/aspera/preview/utils.rb', line 23 def shell_quote(argument) return argument unless argument.chars.any?{|c|BASH_SPECIAL_CHARACTERS.include?(c)} # surround with single quotes, and escape single quotes return %Q{'#{argument.gsub("'"){|_s| %q{'"'"'}}}'} end  | 
  
.video_blend_frames(temp_folder, index1, index2) ⇒ Object
      99 100 101 102 103 104 105 106 107 108  | 
    
      # File 'lib/aspera/preview/utils.rb', line 99 def video_blend_frames(temp_folder, index1, index2) img1 = get_tmp_num_filepath(temp_folder, index1) img2 = get_tmp_num_filepath(temp_folder, index2) count = index2 - index1 - 1 1.upto(count) do |i| percent = i * 100 / (count + 1) filename = get_tmp_num_filepath(temp_folder, index1 + i) external_command(:composite, ['-blend', percent, img2, img1, filename]) end end  | 
  
.video_dump_frame(input_file, offset_seconds, scale, output_file, index = nil) ⇒ Object
      110 111 112 113 114 115 116 117 118  | 
    
      # File 'lib/aspera/preview/utils.rb', line 110 def video_dump_frame(input_file, offset_seconds, scale, output_file, index=nil) output_file = get_tmp_num_filepath(output_file, index) unless index.nil? ffmpeg( in_f: input_file, in_p: ['-ss', offset_seconds], out_f: output_file, out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"]) return output_file end  | 
  
.video_dupe_frame(temp_folder, index, count) ⇒ Object
      92 93 94 95 96 97  | 
    
      # File 'lib/aspera/preview/utils.rb', line 92 def video_dupe_frame(temp_folder, index, count) input_file = get_tmp_num_filepath(temp_folder, index) 1.upto(count) do |i| FileUtils.ln_s(input_file, get_tmp_num_filepath(temp_folder, index + i)) end end  | 
  
.video_get_duration(input_file) ⇒ Object
Returns Float in seconds.
      75 76 77 78 79 80 81 82  | 
    
      # File 'lib/aspera/preview/utils.rb', line 75 def video_get_duration(input_file) result = external_command(:ffprobe, [ '-loglevel', 'error', '-show_entries', 'format=duration', '-print_format', 'default=noprint_wrappers=1:nokey=1', # cspell:disable-line input_file]) return result[:stdout].to_f end  |