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 = []) ⇒ nil
Check that external tools can be executed.
-
.execute(*args, **kwargs) ⇒ Object
Execute external command, verify it is in the supported list.
-
.ffmpeg(gl_p: FFMPEG_DEFAULT_PARAMS, in_p: [], in_f:, out_p: [], out_f:) ⇒ nil
Execute ‘ffmpeg`.
-
.ffmpeg_fmt(temp_folder) ⇒ Object
File output format, including temp folder.
- .get_tmp_num_filepath(temp_folder, file_number) ⇒ Object
-
.parse_magick_fonts(output) ⇒ Hash
Parse the output of ‘magick identify -list font` command.
-
.silent_execute(*args) ⇒ nil
Execute external command silently.
- .video_blend_frames(temp_folder, index_begin, index_end) ⇒ Object
-
.video_dump_frame(input_file, offset_seconds, scale, output_file) ⇒ nil
Dump a frame from a video file.
- .video_dupe_frame(temp_folder, index, count) ⇒ Object
-
.video_get_duration(input_file) ⇒ Object
Float in seconds.
Class Method Details
.check_tools(skip_types = []) ⇒ nil
Check that external tools can be executed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/aspera/preview/utils.rb', line 29 def check_tools(skip_types = []) tools_to_check = EXTERNAL_TOOLS.dup if skip_types.include?(:office) tools_to_check.delete(:unoconv) tools_to_check.delete(:soffice) end # Check for binaries tools_to_check.each do |command_sym| silent_execute(command_sym, '-h') rescue Errno::ENOENT => e raise "missing #{command_sym} binary: #{e}" rescue nil end end |
.execute(*args, **kwargs) ⇒ Object
Execute external command, verify it is in the supported list
46 47 48 49 |
# File 'lib/aspera/preview/utils.rb', line 46 def execute(*args, **kwargs) Aspera.assert_values(args.first, EXTERNAL_TOOLS){'command'} Environment.secure_execute(*args, **kwargs) end |
.ffmpeg(gl_p: FFMPEG_DEFAULT_PARAMS, in_p: [], in_f:, out_p: [], out_f:) ⇒ nil
Execute ‘ffmpeg`
60 61 62 63 64 65 |
# File 'lib/aspera/preview/utils.rb', line 60 def ffmpeg(gl_p: FFMPEG_DEFAULT_PARAMS, in_p: [], in_f:, out_p: [], out_f:) Aspera.assert_type(gl_p, Array) Aspera.assert_type(in_p, Array) Aspera.assert_type(out_p, Array) silent_execute(:ffmpeg, *gl_p, *in_p, '-i', in_f, *out_p, out_f) end |
.ffmpeg_fmt(temp_folder) ⇒ Object
File output format, including temp folder
80 81 82 |
# File 'lib/aspera/preview/utils.rb', line 80 def ffmpeg_fmt(temp_folder) return File.join(temp_folder, TEMP_FORMAT) end |
.get_tmp_num_filepath(temp_folder, file_number) ⇒ Object
84 85 86 87 |
# File 'lib/aspera/preview/utils.rb', line 84 def get_tmp_num_filepath(temp_folder, file_number) # Format using {Kernel.format} return File.join(temp_folder, format(TEMP_FORMAT, file_number)) end |
.parse_magick_fonts(output) ⇒ Hash
Parse the output of ‘magick identify -list font` command
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/aspera/preview/utils.rb', line 128 def parse_magick_fonts(output) result = {path: nil, fonts: []} current_font = nil output.each_line do |line| line = line.strip # Parse the Path line if line.start_with?('Path:') result[:path] = line.sub(/^Path:\s*/, '') # Parse Font name elsif line.start_with?('Font:') # Save previous font if exists result[:fonts] << current_font if current_font # Start new font current_font = {name: line.sub(/^Font:\s*/, '')} # Parse font properties elsif current_font && line.include?(':') key, value = line.split(':', 2) key = key.strip.gsub(/\s+/, '_').to_sym value = value.strip # Convert numeric values value = value.to_i if key == :weight || key == :index current_font[key] = value end end # Don't forget the last font result[:fonts] << current_font if current_font result end |
.silent_execute(*args) ⇒ nil
Execute external command silently
53 54 55 56 |
# File 'lib/aspera/preview/utils.rb', line 53 def silent_execute(*args) execute(*args, out: File::NULL, err: File::NULL) nil end |
.video_blend_frames(temp_folder, index_begin, index_end) ⇒ Object
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/aspera/preview/utils.rb', line 96 def video_blend_frames(temp_folder, index_begin, index_end) img1 = get_tmp_num_filepath(temp_folder, index_begin) img2 = get_tmp_num_filepath(temp_folder, index_end) count = index_end - index_begin - 1 1.upto(count) do |i| percent = i * 100 / (count + 1) filename = get_tmp_num_filepath(temp_folder, index_begin + i) silent_execute(:magick, 'composite', '-blend', percent, img2, img1, filename) end end |
.video_dump_frame(input_file, offset_seconds, scale, output_file) ⇒ nil
Dump a frame from a video file
113 114 115 116 117 118 119 120 |
# File 'lib/aspera/preview/utils.rb', line 113 def video_dump_frame(input_file, offset_seconds, scale, output_file) ffmpeg( in_f: input_file, in_p: ['-ss', offset_seconds], out_f: output_file, out_p: ['-frames:v', 1, '-filter:v', "scale=#{scale}"] ) end |
.video_dupe_frame(temp_folder, index, count) ⇒ Object
89 90 91 92 93 94 |
# File 'lib/aspera/preview/utils.rb', line 89 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.
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/aspera/preview/utils.rb', line 68 def video_get_duration(input_file) return execute( :ffprobe, '-loglevel', 'error', '-show_entries', 'format=duration', '-print_format', 'default=noprint_wrappers=1:nokey=1', # cspell:disable-line input_file, mode: :capture ).first.to_f end |