Files
velour/app/services/video_transcoder.rb
Dan Milne 88a906064f
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Much base work started
2025-10-31 14:36:14 +11:00

75 lines
2.0 KiB
Ruby

class VideoTranscoder
require 'streamio-ffmpeg'
def initialize
@ffmpeg_path = ENV['FFMPEG_PATH'] || 'ffmpeg'
@ffprobe_path = ENV['FFPROBE_PATH'] || 'ffprobe'
end
def transcode_for_web(input_path:, output_path:, on_progress: nil)
movie = FFMPEG::Movie.new(input_path)
# Calculate progress callback
progress_callback = ->(progress) {
on_progress&.call(progress, 100)
}
# Transcoding options for web compatibility
options = {
video_codec: 'libx264',
audio_codec: 'aac',
custom: [
'-pix_fmt yuv420p',
'-preset medium',
'-crf 23',
'-movflags +faststart',
'-tune fastdecode'
]
}
movie.transcode(output_path, options, &progress_callback)
output_path
end
def extract_frame(input_path, seconds)
movie = FFMPEG::Movie.new(input_path)
output_path = "#{Rails.root}/tmp/thumbnail_#{SecureRandom.hex(8)}.jpg"
movie.screenshot(output_path, seek_time: seconds, resolution: '320x240')
output_path
end
def extract_metadata(input_path)
movie = FFMPEG::Movie.new(input_path)
{
width: movie.width,
height: movie.height,
duration: movie.duration,
video_codec: movie.video_codec,
audio_codec: movie.audio_codec,
bit_rate: movie.bitrate,
frame_rate: movie.frame_rate,
format: movie.container
}
end
def web_compatible?(input_path)
movie = FFMPEG::Movie.new(input_path)
# Check if video is already web-compatible
return false unless movie.valid?
# Common web-compatible formats
web_formats = %w[mp4 webm]
web_video_codecs = %w[h264 av1 vp9]
web_audio_codecs = %w[aac opus]
format_compatible = web_formats.include?(movie.container.downcase)
video_compatible = web_video_codecs.include?(movie.video_codec&.downcase)
audio_compatible = movie.audio_codec.blank? || web_audio_codecs.include?(movie.audio_codec&.downcase)
format_compatible && video_compatible && audio_compatible
end
end