Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test mode #103

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
*.tmproj
tmtags

## idea
.idea/**/*

## EMACS
*~
\#*
Expand All @@ -22,4 +25,6 @@ pkg
## PROJECT::SPECIFIC
script/*
tmp/*
Gemfile.lock
Gemfile.lock

tags
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
source "https://rubygems.org"
source 'https://rubygems.org'

gemspec
69 changes: 67 additions & 2 deletions lib/ffmpeg/encoding_options.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module FFMPEG
class EncodingOptions < Hash
def initialize(options = {})
def initialize(options = {}, movie = nil)
@movie = movie
merge!(options)
end

Expand All @@ -13,6 +14,7 @@ def to_s
# all other parameters go after so that we can override whatever is in the preset
codecs = params.select { |p| p =~ /codec/ }
presets = params.select { |p| p =~ /\-.pre/ }

other = params - codecs - presets
params = codecs + presets + other

Expand All @@ -31,10 +33,15 @@ def height

private
def supports_option?(option)
option = RUBY_VERSION < "1.9" ? "convert_#{option}" : "convert_#{option}".to_sym
option = RUBY_VERSION < '1.9' ? "convert_#{option}" : "convert_#{option}".to_sym
private_methods.include?(option)
end

def supports_filter_option?(filter_option)
filter_option = RUBY_VERSION < '1.9' ? "filter_#{filter_option}" : "filter_#{filter_option}".to_sym
private_methods.include?(filter_option)
end

def convert_aspect(value)
"-aspect #{value}"
end
Expand Down Expand Up @@ -140,6 +147,34 @@ def convert_watermark(value)
"-i #{value}"
end

def convert_disable_audio(value)
value ? '-an' : ''
end

def convert_format(value)
"-f #{value}"
end

def convert_keyframe_interval_minimal(value)
"-keyint_min #{value}"
end

def convert_pass(value)
"-pass #{value}"
end

def convert_pass_log_file(value)
"-passlogfile #{value}"
end

def convert_audio_sync(value)
"-async #{value}"
end

def convert_strict(value)
"-strict #{value}"
end

def convert_watermark_filter(value)
case value[:position].to_s
when "LT"
Expand All @@ -153,6 +188,36 @@ def convert_watermark_filter(value)
end
end

def convert_filters(vf_options)
params = vf_options.collect do |key, value|
send("filter_#{key}", value) if value && supports_filter_option?(key)
end

"-vf '#{params.compact.join(',')}'"
end

def filter_height_divisible(value)
value ? 'scale=trunc(iw/2)*2:trunc(ih/2)*2' : ''
end

def filter_fix_pixels(value)
raise 'Movie undeffined' unless @movie.is_a? Movie
if value && (@movie.pixel_aspect_raito.to_f == 1.0 || @movie.display_aspect_raito_y == 0)
nil
else
"scale=ih*#{@movie.display_aspect_raito_x}/#{@movie.display_aspect_raito_y}:ih,setsar=1"
end
end

def filter_height(value)
value ? "scale=#{value}*iw/ih:#{value}" : ''
end

def filter_fps(value)
value ? "fps=#{value}" : ''
end


def convert_custom(value)
value
end
Expand Down
38 changes: 27 additions & 11 deletions lib/ffmpeg/movie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Movie
attr_reader :video_stream, :video_codec, :video_bitrate, :colorspace, :resolution, :sar, :dar
attr_reader :audio_stream, :audio_codec, :audio_bitrate, :audio_sample_rate
attr_reader :container
attr_reader :display_aspect_raito, :pixel_aspect_raito

def initialize(path)
raise Errno::ENOENT, "the file '#{path}' does not exist" unless File.exists?(path)
Expand All @@ -16,6 +17,12 @@ def initialize(path)
command = "#{FFMPEG.ffmpeg_binary} -i #{Shellwords.escape(path)}"
output = Open3.popen3(command) { |stdin, stdout, stderr| stderr.read }

mediainfo_command = "#{FFMPEG.mediainfo_binary} --Inform=\"Video;%DisplayAspectRatio/String% %PixelAspectRatio%\" #{Shellwords.escape(path)}"
mediainfo_output = Open3.popen3(mediainfo_command) { |stdin, stdout, stderr| stdout.read }

@display_aspect_raito, @pixel_aspect_raito = mediainfo_output.split(' ')


fix_encoding(output)

output[/Input \#\d+\,\s*(\S+),\s*from/]
Expand Down Expand Up @@ -58,20 +65,29 @@ def initialize(path)
end

@invalid = true if @video_stream.to_s.empty? && @audio_stream.to_s.empty?
@invalid = true if output.include?("is not supported")
@invalid = true if output.include?("could not find codec parameters")
@invalid = true if output.include?('is not supported')
@invalid = true if output.include?('could not find codec parameters')
end

def valid?
not @invalid
end

def width
resolution.split("x")[0].to_i rescue nil
resolution.split('x')[0].to_i rescue nil
end

def height
resolution.split("x")[1].to_i rescue nil
resolution.split('x')[1].to_i rescue nil
end


def display_aspect_raito_x
display_aspect_raito.split(':')[0].to_i rescue nil
end

def display_aspect_raito_y
display_aspect_raito.split(":")[1].to_i rescue nil
end

def calculated_aspect_ratio
Expand All @@ -88,10 +104,10 @@ def size

def audio_channels
return nil unless @audio_channels
return @audio_channels[/\d*/].to_i if @audio_channels["channels"]
return 1 if @audio_channels["mono"]
return 2 if @audio_channels["stereo"]
return 6 if @audio_channels["5.1"]
return @audio_channels[/\d*/].to_i if @audio_channels['channels']
return 1 if @audio_channels['mono']
return 2 if @audio_channels['stereo']
return 6 if @audio_channels['5.1']
end

def frame_rate
Expand All @@ -110,14 +126,14 @@ def screenshot(output_file, options = EncodingOptions.new, transcoder_options =
protected
def aspect_from_dar
return nil unless dar
w, h = dar.split(":")
w, h = dar.split(':')
aspect = w.to_f / h.to_f
aspect.zero? ? nil : aspect
end

def aspect_from_sar
return nil unless sar
w, h = sar.split(":")
w, h = sar.split(':')
aspect = w.to_f / h.to_f
aspect.zero? ? nil : aspect
end
Expand All @@ -130,7 +146,7 @@ def aspect_from_dimensions
def fix_encoding(output)
output[/test/] # Running a regexp on the string throws error if it's not UTF-8
rescue ArgumentError
output.force_encoding("ISO-8859-1")
output.force_encoding('ISO-8859-1')
end
end
end
30 changes: 24 additions & 6 deletions lib/ffmpeg/transcoder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

module FFMPEG
class Transcoder
@@timeout = 30
@@timeout = 300

def self.timeout=(time)
@@timeout = time
Expand All @@ -20,7 +20,7 @@ def initialize(movie, output_file, options = EncodingOptions.new, transcoder_opt
if options.is_a?(String) || options.is_a?(EncodingOptions)
@raw_options = options
elsif options.is_a?(Hash)
@raw_options = EncodingOptions.new(options)
@raw_options = EncodingOptions.new(options, movie)
else
raise ArgumentError, "Unknown options format '#{options.class}', should be either EncodingOptions, Hash or String."
end
Expand Down Expand Up @@ -54,9 +54,24 @@ def encoded
private
# frame= 4855 fps= 46 q=31.0 size= 45306kB time=00:02:42.28 bitrate=2287.0kbits/
def transcode_movie
@command = "#{FFMPEG.ffmpeg_binary} -y -i #{Shellwords.escape(@movie.path)} #{@raw_options} #{Shellwords.escape(@output_file)}"
priority = @transcoder_options.try(:[], :priority) || 0

if FFMPEG.cp_mode
if @output_file == '/dev/null'
@command = "cp ./features/data/example.log-0.log #{Shellwords.escape("#{File.dirname(@movie.path)}/hds_preprocessing.log-0.log")}
&& cp ./features/data/example.log-0.log.mbtree #{Shellwords.escape("#{File.dirname(@movie.path)}/hds_preprocessing.log-0.log.mbtree")}"
else
@command = "cp ./features/data/example#{File.extname(@output_file)} #{@output_file}"
end
else
@command = "nice -n #{priority} #{FFMPEG.ffmpeg_binary} -y -i #{Shellwords.escape(@movie.path)} #{@raw_options} #{Shellwords.escape(@output_file)}#{' || exit 1' if @transcoder_options.try(:[], :or_exit)}"
@command = "#{@command} && #{FFMPEG.qtfaststart_binary} #{Shellwords.escape(@output_file)}" if @transcoder_options.try(:[], :meta_2_begin)
end

FFMPEG.logger.info("Running transcoding...\n#{@command}\n")
@output = ""
@output = ''

# raise @command

Open3.popen3(@command) do |stdin, stdout, stderr, wait_thr|
begin
Expand Down Expand Up @@ -100,21 +115,24 @@ def validate_output_file(&block)
end

def apply_transcoder_options

# if true runs #validate_output_file
@transcoder_options[:validate] = @transcoder_options.fetch(:validate) { true }

return if @movie.calculated_aspect_ratio.nil?
case @transcoder_options[:preserve_aspect_ratio].to_s
when "width"
when ['width', 'video']
new_height = @raw_options.width / @movie.calculated_aspect_ratio
new_height = new_height.ceil.even? ? new_height.ceil : new_height.floor
new_height += 1 if new_height.odd? # needed if new_height ended up with no decimals in the first place
@raw_options[:resolution] = "#{@raw_options.width}x#{new_height}"
when "height"
when ['height', 'video']
new_width = @raw_options.height * @movie.calculated_aspect_ratio
new_width = new_width.ceil.even? ? new_width.ceil : new_width.floor
new_width += 1 if new_width.odd?
@raw_options[:resolution] = "#{new_width}x#{@raw_options.height}"
when ['height', 'screenshot']
when ['width', 'screenshot']
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ffmpeg/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module FFMPEG
VERSION = "1.0.0"
VERSION = '1.0.9'
end
41 changes: 41 additions & 0 deletions lib/streamio-ffmpeg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,51 @@ def self.ffmpeg_binary=(bin)
@ffmpeg_binary = bin
end

# Set the path of the mediainfo binary.
# Can be useful if you need to specify a path such as /usr/local/bin/mediainfo
#
# @param [String] path to the ffmpeg binary
# @return [String] the path you set
def self.mediainfo_binary=(bin)
@mediainfo_binary = bin
end

# Set the path of the qtfaststart binary.
# Can be useful if you need to specify a path such as /usr/local/bin/qtfaststart
#
# @param [String] path to the ffmpeg binary
# @return [String] the path you set
def self.qtfaststart_binary=(bin)
@qtfaststart_binary = bin
end

def self.cp_mode=(is_enable)
@cp_mode = is_enable
end

# Get the path to the ffmpeg binary, defaulting to 'ffmpeg'
#
# @return [String] the path to the ffmpeg binary
def self.ffmpeg_binary
@ffmpeg_binary || 'ffmpeg'
end

# Get the path to the ffmpeg binary, defaulting to 'mediainfo'
#
# @return [String] the path to the ffmpeg binary
def self.mediainfo_binary
@mediainfo_binary || 'mediainfo'
end

# Get the path to the ffmpeg binary, defaulting to 'qtfaststart'
#
# @return [String] the path to the ffmpeg binary
def self.qtfaststart_binary
@qtfaststart_binary || 'qtfaststart'
end

def self.cp_mode
@cp_mode == 'true' || @cp_mode == true
end

end
2 changes: 1 addition & 1 deletion streamio-ffmpeg.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
lib = File.expand_path('../lib/', __FILE__)
$:.unshift lib unless $:.include?(lib)

require "ffmpeg/version"
require 'ffmpeg/version'

Gem::Specification.new do |s|
s.name = "streamio-ffmpeg"
Expand Down