Class: Aspera::Preview::Utils

Inherits:
Object
  • Object
show all
Defined in:
lib/aspera/preview/utils.rb

Class Method Summary collapse

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'], out: File::NULL)
  rescue Errno::ENOENT => e
    raise "missing #{command_sym} binary: #{e}"
  rescue
    nil
  end
end

.external_capture(command_sym, command_args) ⇒ Object



51
52
53
54
# File 'lib/aspera/preview/utils.rb', line 51

def external_capture(command_sym, command_args)
  Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'}
  return Environment.secure_capture(exec: command_sym.to_s, args: command_args.map(&:to_s))
end

.external_command(command_sym, command_args) ⇒ Object

execute external command one could use “system”, but we would need to redirect stdout/err

Returns:

  • nil



46
47
48
49
# File 'lib/aspera/preview/utils.rb', line 46

def external_command(command_sym, command_args)
  Aspera.assert_values(command_sym, EXTERNAL_TOOLS){'command'}
  Environment.secure_execute(exec: command_sym.to_s, args: command_args.map(&:to_s), out: File::NULL, err: File::NULL)
end

.ffmpeg(a) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/aspera/preview/utils.rb', line 56

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



78
79
80
# File 'lib/aspera/preview/utils.rb', line 78

def ffmpeg_fmt(temp_folder)
  return File.join(temp_folder, TEMP_FORMAT)
end

.get_tmp_num_filepath(temp_folder, file_number) ⇒ Object



82
83
84
# File 'lib/aspera/preview/utils.rb', line 82

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



93
94
95
96
97
98
99
100
101
102
# File 'lib/aspera/preview/utils.rb', line 93

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(:magick, ['composite', '-blend', percent, img2, img1, filename])
  end
end

.video_dump_frame(input_file, offset_seconds, scale, output_file, index = nil) ⇒ Object



104
105
106
107
108
109
110
111
112
# File 'lib/aspera/preview/utils.rb', line 104

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



86
87
88
89
90
91
# File 'lib/aspera/preview/utils.rb', line 86

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.

Returns:

  • Float in seconds



70
71
72
73
74
75
76
# File 'lib/aspera/preview/utils.rb', line 70

def video_get_duration(input_file)
  return external_capture(:ffprobe, [
    '-loglevel', 'error',
    '-show_entries', 'format=duration',
    '-print_format', 'default=noprint_wrappers=1:nokey=1', # cspell:disable-line
    input_file]).to_f
end