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)

Parameters:

  • path (String)

    the path to the file


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`

Parameters:

  • video_path (String)

    the path to the video file

  • timestamp (String)

    the `ffmpeg` timestamp format (e.g. 00.00)

  • dimensions (Array)

    the dimension of the screenshot to generate

Returns:

  • the TempFile containing the generated screenshot


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

Returns md5 checksum of given file.

Returns:

  • (String)

    md5 checksum of given file


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

Parameters:

  • path (String)

    the path to the file

Returns:

  • (Boolean)

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

Parameters:

  • path (String)

    the path to the file


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`

Parameters:

  • video_path (String)

    the path to the video file

Returns:

  • (Array)

    the resolution of the video


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