75 lines
2.0 KiB
Ruby
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 |