Add methods to MediaFile to calculate the duration, frame count, and frame rate of animated GIFs, PNGs, Ugoiras, and videos. Some considerations: * It's possible to have a GIF or PNG that's technically animated but just has one frame. These are treated as non-animated images. * It's possible to have an animated GIF that has an unspecified frame rate. In this case we assume the frame rate is 10 FPS; this is browser dependent and may not be correct. * Animated GIFs, PNGs, and Ugoiras all support variable frame rates. Technically, each frame has a separate delay, and the delays can be different frame-to-frame. We report only the average frame rate. * Getting the duration of an APNG is surprisingly hard. Most tools don't have good support for APNGs since it's a rare and non-standardized format. The best we can do is get the frame count using ExifTool and the frame rate using ffprobe, then calculate the duration from that.
32 lines
665 B
Ruby
32 lines
665 B
Ruby
# A MediaFile for a webm or mp4 video. Uses ffmpeg to generate preview
|
|
# thumbnails.
|
|
#
|
|
# @see https://github.com/streamio/streamio-ffmpeg
|
|
class MediaFile::Video < MediaFile
|
|
delegate :duration, :frame_count, :frame_rate, :has_audio?, to: :video
|
|
|
|
def dimensions
|
|
[video.width, video.height]
|
|
end
|
|
|
|
def preview(max_width, max_height)
|
|
preview_frame.preview(max_width, max_height)
|
|
end
|
|
|
|
def crop(max_width, max_height)
|
|
preview_frame.crop(max_width, max_height)
|
|
end
|
|
|
|
private
|
|
|
|
def video
|
|
FFmpeg.new(file)
|
|
end
|
|
|
|
def preview_frame
|
|
video.smart_video_preview
|
|
end
|
|
|
|
memoize :video, :preview_frame, :dimensions, :duration, :has_audio?
|
|
end
|