Much base work started
This commit is contained in:
75
app/services/video_transcoder.rb
Normal file
75
app/services/video_transcoder.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
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
|
||||
Reference in New Issue
Block a user