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

def content_type(path)
  path = path.downcase
  return 'image/jpeg' if path.end_with?('.jpg')
  return 'image/jpeg' if path.end_with?('.jpeg')
  return 'image/png' if path.end_with?('.png')
  return 'application/json' if path.end_with?('.geojson')
  return 'video/quicktime' if path.end_with?('.mov')
  return 'video/mp4' if path.end_with?('.m4v')
  return 'video/mp4' if path.end_with?('.mp4')
  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 path to the TempFile containing the generated screenshot


44
45
46
47
48
49
50
51
52
53
54
# File 'spaceship/lib/spaceship/du/utilities.rb', line 44

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.path
end

.md5digest(file_path) ⇒ String

Returns md5 checksum of given file.

Returns:

  • (String)

    md5 checksum of given file


75
76
77
# File 'spaceship/lib/spaceship/du/utilities.rb', line 75

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)

34
35
36
37
# File 'spaceship/lib/spaceship/du/utilities.rb', line 34

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


25
26
27
28
29
# File 'spaceship/lib/spaceship/du/utilities.rb', line 25

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


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

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