Module: Spaceship::Utilities

Defined in:
spaceship/lib/spaceship/du/utilities.rb

Overview

Set of utility methods useful to work with media files

Class Method Summary collapse

Class Method Details

.content_type(path) ⇒ Object

Identifies the content_type of a file based on its file name extension. Supports all formats required by DU-UTC right now (video, images and json)



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 'spaceship/lib/spaceship/du/utilities.rb', line 10

def content_type(path)
  supported_file_types = {
    '.jpg' => 'image/jpeg',
    '.jpeg' => 'image/jpeg',
    '.png' => 'image/png',
    '.geojson' => 'application/json',
    '.mov' => 'video/quicktime',
    '.m4v' => 'video/mp4',
    '.mp4' => 'video/mp4',
    '.txt' => 'text/plain',
    '.pdf' => 'application/pdf',
    '.doc' => 'application/msword',
    '.docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    '.rtf' => 'application/rtf',
    '.pages' => 'application/x-iwork-pages-sffpages',
    '.xls' => 'application/vnd.ms-excel',
    '.xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    '.numbers' => 'application/x-iwork-numbers-sffnumbers',
    '.rar' => 'application/x-rar-compressed',
    '.plist' => 'application/xml',
    '.crash' => 'text/x-apport',
    '.avi' => 'video/x-msvideo',
    '.zip' => 'application/zip'
  }

  extension = File.extname(path.downcase)
  return supported_file_types[extension] if supported_file_types[extension]
  raise "Unknown content-type for file #{path}"
end

.grab_video_preview(video_path, timestamp, dimensions) ⇒ Object

Grabs a screenshot from the specified video at the specified timestamp using ‘ffmpeg`



62
63
64
65
66
67
68
69
70
71
72
# File 'spaceship/lib/spaceship/du/utilities.rb', line 62

def grab_video_preview(video_path, timestamp, dimensions)
  width, height = dimensions
  require 'tempfile'
  tmp = Tempfile.new(['video_preview', ".jpg"])
  file = tmp.path
  command = "ffmpeg -y -i \"#{video_path}\" -s #{width}x#{height} -ss \"#{timestamp}\" -vframes 1 \"#{file}\" 2>&1 >/dev/null"
  # puts "COMMAND: #{command}"
  `#{command}`
  raise "Failed to grab screenshot at #{timestamp} from #{video_path} (using #{command})" unless $CHILD_STATUS.to_i == 0
  tmp
end

.md5digest(file_path) ⇒ String



93
94
95
# File 'spaceship/lib/spaceship/du/utilities.rb', line 93

def md5digest(file_path)
  Digest::MD5.hexdigest(File.read(file_path))
end

.portrait?(path) ⇒ Boolean

Is the video or image in portrait mode ? Supports all video and images required by DU-UTC right now



52
53
54
55
# File 'spaceship/lib/spaceship/du/utilities.rb', line 52

def portrait?(path)
  resolution = resolution(path)
  resolution[0] < resolution[1]
end

.resolution(path) ⇒ Object

Identifies the resolution of a video or an image. Supports all video and images required by DU-UTC right now



43
44
45
46
47
# File 'spaceship/lib/spaceship/du/utilities.rb', line 43

def resolution(path)
  return FastImage.size(path) if content_type(path).start_with?("image")
  return video_resolution(path) if content_type(path).start_with?("video")
  raise "Cannot find resolution of file #{path}"
end

.video_resolution(video_path) ⇒ Array

identifies the resolution of a video using ‘ffmpeg`



77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'spaceship/lib/spaceship/du/utilities.rb', line 77

def video_resolution(video_path)
  command = "ffmpeg -i \"#{video_path}\" 2>&1"
  # puts "COMMAND: #{command}"
  output = `#{command}`
  # Note: ffmpeg exits with 1 if no output specified
  # raise "Failed to find video information from #{video_path} (using #{command})" unless $CHILD_STATUS.to_i == 0
  output = output.force_encoding("BINARY")
  video_infos = output.split("\n").select { |l| l =~ /Stream.*Video/ }
  raise "Unable to find Stream Video information from ffmpeg output of #{command}" if video_infos.count == 0
  video_info = video_infos[0]
  res = video_info.match(/.* ([0-9]+)x([0-9]+).*/)
  raise "Unable to parse resolution information from #{video_info}" if res.size < 3
  [res[1].to_i, res[2].to_i]
end