uploads: add support for uploading .avif files.
Features of AVIF include: * Lossless and lossy compression. * High dynamic range (HDR) images * Wide color gamut images (i.e. 10- and 12-bit color depths) * Transparency (through alpha planes). * Animations (with an optional cover image). * Auxiliary image sequences, where the file contains a single primary image and a short secondary video, like Apple's Live Photos. * Metadata rotation, mirroring, and cropping. The AVIF format is still relatively new and some of these features aren't well supported by browsers or other software: * Animated AVIFs aren't supported by Firefox or by libvips. * HDR images aren't supported by Firefox. * Rotated, mirrored, and cropped AVIFs aren't supported by Firefox or Chrome. * Image grids, where the file contains multiple images that are tiled together into one big image, aren't supported by Firefox. * AVIF as a whole has only been supported for a year or two by Chrome and Firefox, and less than a year by Safari. For these reasons, only basic AVIFs that don't use animation, rotation, cropping, or image grids can be uploaded.
This commit is contained in:
@@ -32,13 +32,17 @@ class FFmpeg
|
||||
end
|
||||
|
||||
# Get file metadata using ffprobe.
|
||||
#
|
||||
# @see https://ffmpeg.org/ffprobe.html
|
||||
# @see https://gist.github.com/nrk/2286511
|
||||
# @return [Hash] a hash of the file's metadata
|
||||
#
|
||||
# @return [Hash] A hash of the file's metadata. Will be empty if reading the file failed for any reason.
|
||||
def metadata
|
||||
output = shell!("ffprobe -v quiet -print_format json -show_format -show_streams #{file.path.shellescape}")
|
||||
json = JSON.parse(output)
|
||||
json.with_indifferent_access
|
||||
rescue Error
|
||||
{}
|
||||
end
|
||||
|
||||
def width
|
||||
@@ -64,7 +68,7 @@ class FFmpeg
|
||||
|
||||
# @return [Integer, nil] The number of frames in the video or animation, or nil if unknown.
|
||||
def frame_count
|
||||
if video_streams.first.has_key?(:nb_frames)
|
||||
if video_streams.first&.has_key?(:nb_frames)
|
||||
video_streams.first[:nb_frames].to_i
|
||||
elsif playback_info.has_key?(:frame)
|
||||
playback_info[:frame].to_i
|
||||
@@ -80,11 +84,11 @@ class FFmpeg
|
||||
end
|
||||
|
||||
def video_streams
|
||||
metadata[:streams].select { |stream| stream[:codec_type] == "video" }
|
||||
metadata[:streams].to_a.select { |stream| stream[:codec_type] == "video" }
|
||||
end
|
||||
|
||||
def audio_streams
|
||||
metadata[:streams].select { |stream| stream[:codec_type] == "audio" }
|
||||
metadata[:streams].to_a.select { |stream| stream[:codec_type] == "audio" }
|
||||
end
|
||||
|
||||
def has_audio?
|
||||
|
||||
Reference in New Issue
Block a user