Fix .webm files not including the `FFmpeg:VideoBitRate` and `FFmpeg:AudioBitRate`
fields in the media_metadata table. This was because the .webm format
doesn't include the video or audio bit rates in the metadata, and
ffprobe doesn't calculate them either, so we have to calculate them
ourselves by hand.
Fixup for 523d7afdd.
66 lines
2.3 KiB
Ruby
66 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# 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?, :is_corrupt?, :major_brand, :pix_fmt, :video_codec, :video_bit_rate, :video_stream, :video_streams, :audio_codec, :audio_bit_rate, :audio_stream, :audio_streams, :error, to: :video
|
|
|
|
def dimensions
|
|
[video.width, video.height]
|
|
end
|
|
|
|
def preview!(max_width, max_height, **options)
|
|
preview_frame.preview!(max_width, max_height, **options)
|
|
end
|
|
|
|
def metadata
|
|
super.merge({
|
|
"FFmpeg:Error" => error,
|
|
"FFmpeg:MajorBrand" => major_brand,
|
|
"FFmpeg:PixFmt" => pix_fmt,
|
|
"FFmpeg:FrameCount" => frame_count,
|
|
"FFmpeg:VideoCodec" => video_codec,
|
|
"FFmpeg:VideoProfile" => video_stream[:profile],
|
|
"FFmpeg:VideoBitRate" => video_bit_rate,
|
|
"FFmpeg:AudioCodec" => audio_codec,
|
|
"FFmpeg:AudioProfile" => audio_stream[:profile],
|
|
"FFmpeg:AudioLayout" => audio_stream[:channel_layout],
|
|
"FFmpeg:AudioBitRate" => audio_bit_rate,
|
|
}.compact_blank)
|
|
end
|
|
|
|
def is_supported?
|
|
return false if video_streams.size != 1
|
|
return false if audio_streams.size > 1
|
|
return false if is_webm? && exif_metadata["Matroska:DocType"] != "webm"
|
|
return false if is_mp4? && !video_codec.in?(["h264", "vp9"])
|
|
|
|
# Only allow pixel formats supported by most browsers. Don't allow 10-bit video or 4:4:4 subsampling (neither are supported by Firefox).
|
|
#
|
|
# yuv420p: 8-bit YUV, 4:2:0 subsampling. The vast majority of videos use this format.
|
|
# yuvj420p: 8-bit YUV, 4:2:0 subsampling, color range restricted to 16-235. Uncommon, but widely supported.
|
|
# yuv444p: 8-bit YUV, 4:4:4 subsampling (i.e. no subsampling). Uncommon, not supported by Firefox.
|
|
# yuv420p10le: 10-bit YUV, 4:2:0 subsampling (i.e. 10-bit video). Uncommon, not supported by Firefox.
|
|
# gbrp: 8-bit RGB (used by VP9). Uncommon, but widely supported.
|
|
#
|
|
# https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/pixfmt.h
|
|
return false if !pix_fmt.in?(%w[yuv420p yuvj420p gbrp])
|
|
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def video
|
|
FFmpeg.new(self)
|
|
end
|
|
|
|
def preview_frame
|
|
video.smart_video_preview
|
|
end
|
|
|
|
memoize :video, :preview_frame, :dimensions, :metadata, :duration, :has_audio?
|
|
end
|