Class: XMorph::Base
- Inherits:
-
Object
- Object
- XMorph::Base
- Defined in:
- lib/xmorph/base.rb
Direct Known Subclasses
Constant Summary collapse
- IGNORE =
"ignore"- VALIDATE =
"validate"- ALLOWED_ASPECT_RATIO =
"allowed_aspect_ratio"- ALLOWED_HEIGHT =
"allowed_height"- ALLOWED_WIDTH =
"allowed_width"- ALLOWED_FRAME_RATE =
"allowed_frame_rate"- ALLOWED_VIDEO_BIT_RATE =
"allowed_video_bit_rate"- ALLOWED_SCAN_TYPE =
"allowed_scan_type"- PRESENCE_OF_AUDIO_TRACK =
"presence_of_audio_track"- ALLOWED_NUMBER_OF_AUDIO_TRACKS =
"allowed_number_of_audio_tracks"- ALLOWED_AUDIO_CODECS =
"allowed_audio_codecs"- ALLOWED_AUDIO_BIT_RATE =
"allowed_audio_bit_rate"- ALLOWED_NUMBER_OF_AUDIO_CHANNELS =
"allowed_number_of_audio_channels"
Instance Attribute Summary collapse
-
#asset_path ⇒ Object
Returns the value of attribute asset_path.
-
#default_audio_checks ⇒ Object
Returns the value of attribute default_audio_checks.
-
#default_video_checks ⇒ Object
Returns the value of attribute default_video_checks.
-
#error ⇒ Object
Returns the value of attribute error.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#mediainfo_output ⇒ Object
Returns the value of attribute mediainfo_output.
-
#profile_name ⇒ Object
Returns the value of attribute profile_name.
-
#profiles ⇒ Object
Returns the value of attribute profiles.
Class Method Summary collapse
- .get_transcode_template(host, domain, name, asset_path, return_loaded_filepath = false) ⇒ Object
- .logger ⇒ Object
- .logger=(logger) ⇒ Object
- .root ⇒ Object
Instance Method Summary collapse
- #get_asset_details ⇒ Object
- #get_profile(return_profile_name = false) ⇒ Object
-
#initialize(asset_path) ⇒ Base
constructor
A new instance of Base.
- #perform_default_audio_validations ⇒ Object
-
#perform_default_video_validations ⇒ Object
def audio_checks { PRESENCE_OF_AUDIO_TRACK => IGNORE || VALIDATE, ALLOWED_NUMBER_OF_AUDIO_TRACKS => (1..16)|| [2, 4, 6, 8] || IGNORE, ALLOWED_AUDIO_CODECS => [‘aac’, ‘ac3’, ‘mp2’, ‘mp4’] || IGNORE, ALLOWED_AUDIO_BIT_RATE => (120..317) || [192, 317] || IGNORE, ALLOWED_NUMBER_OF_AUDIO_CHANNELS => (1..16) || [1, 2] || IGNORE, } end.
- #post_process ⇒ Object
- #set_validations ⇒ Object
- #transcode(cmd) ⇒ Object
- #validate_asset ⇒ Object
Constructor Details
#initialize(asset_path) ⇒ Base
Returns a new instance of Base.
34 35 36 37 |
# File 'lib/xmorph/base.rb', line 34 def initialize(asset_path) self.asset_path = asset_path self.set_profiles end |
Instance Attribute Details
#asset_path ⇒ Object
Returns the value of attribute asset_path.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def asset_path @asset_path end |
#default_audio_checks ⇒ Object
Returns the value of attribute default_audio_checks.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def default_audio_checks @default_audio_checks end |
#default_video_checks ⇒ Object
Returns the value of attribute default_video_checks.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def default_video_checks @default_video_checks end |
#error ⇒ Object
Returns the value of attribute error.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def error @error end |
#logger ⇒ Object
Returns the value of attribute logger.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def logger @logger end |
#mediainfo_output ⇒ Object
Returns the value of attribute mediainfo_output.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def mediainfo_output @mediainfo_output end |
#profile_name ⇒ Object
Returns the value of attribute profile_name.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def profile_name @profile_name end |
#profiles ⇒ Object
Returns the value of attribute profiles.
20 21 22 |
# File 'lib/xmorph/base.rb', line 20 def profiles @profiles end |
Class Method Details
.get_transcode_template(host, domain, name, asset_path, return_loaded_filepath = false) ⇒ Object
39 40 41 42 43 44 45 46 47 |
# File 'lib/xmorph/base.rb', line 39 def self.get_transcode_template(host, domain, name, asset_path, return_loaded_filepath=false) return nil unless domain file_path = File.join(self.root, "xmorph", "customers", host, domain, "transcode.rb") raise TranscoderError.new("Transcoding profile doesn't exist for account, #{name}.") unless File.exist? file_path XMorph::Base.logger.debug("XMorph#get_transcode_template: loading file #{file_path} to transcode #{asset_path}") load file_path return Transcode.new(asset_path), file_path if return_loaded_filepath return Transcode.new(asset_path) end |
.logger ⇒ Object
26 27 28 |
# File 'lib/xmorph/base.rb', line 26 def self.logger @@logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT) end |
.logger=(logger) ⇒ Object
30 31 32 |
# File 'lib/xmorph/base.rb', line 30 def self.logger=(logger) @@logger = logger end |
.root ⇒ Object
22 23 24 |
# File 'lib/xmorph/base.rb', line 22 def self.root File.dirname __dir__ end |
Instance Method Details
#get_asset_details ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/xmorph/base.rb', line 49 def get_asset_details mediainfo_command = "#{File.dirname(self.class.root)}/bin/mediainfo --output=XML #{self.asset_path}" success, response = Util.run_cmd_with_response(mediainfo_command) raise TranscoderError.new("Failed to get mediainfo for the asset.") unless success begin self.mediainfo_output = Util.mediainfo_xml_to_hash(response)[1] rescue => e raise TranscoderError.new("Failed to get mediainfo for the asset.") end set_validations end |
#get_profile(return_profile_name = false) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/xmorph/base.rb', line 81 def get_profile(return_profile_name=false) self.set_profile_name if (self.profile_name.blank? or self.profiles[self.profile_name].blank?) raise TranscoderError.new(self.error || "Media doesnt match any transcoding profiles.") end XMorph::Base.logger.debug("XMorph#get_profile: Using ffmpeg command: #{self.profiles[self.profile_name]} to transcode #{asset_path}") return self.profile_name, self.profiles[self.profile_name] if return_profile_name return self.profiles[self.profile_name] end |
#perform_default_audio_validations ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/xmorph/base.rb', line 198 def perform_default_audio_validations mediainfo = self.mediainfo_output audio_tracks = mediainfo["Audio"] default_checks = self.default_audio_checks number_of_audio_tracks = audio_tracks.count if number_of_audio_tracks > 0 audio_codecs = []; bit_rate = []; number_of_audio_channels = [] audio_tracks.each do |a| audio_codecs << a["Format"] bit_rate << (a["Bit_rate"] || a["Nominal_bit_rate"]).split(" ")[0].to_f if (a["Bit_rate"] || a["Nominal_bit_rate"]).present? number_of_audio_channels << a["Channel_s_"].split(" ")[0].to_i if a["Channel_s_"].present? end end if (default_checks[PRESENCE_OF_AUDIO_TRACK] != IGNORE) and (number_of_audio_tracks <= 0) self.error = "No audio tracks found" return false end errors = [] missing = [] if number_of_audio_tracks > 0 if default_checks[ALLOWED_NUMBER_OF_AUDIO_TRACKS] != IGNORE errors << "Unexpected number of audio tracks #{number_of_audio_tracks}. We support #{default_checks[ALLOWED_NUMBER_OF_AUDIO_TRACKS]} tracks" unless default_checks[ALLOWED_NUMBER_OF_AUDIO_TRACKS].include? number_of_audio_tracks end if default_checks[ALLOWED_AUDIO_BIT_RATE] != IGNORE if bit_rate.empty? || (bit_rate.uniq.include? nil) missing << "Bit rate" else unsupported_bit_rate = bit_rate.map{|b| b unless default_checks[ALLOWED_AUDIO_BIT_RATE].include? b} errors << "Unexpected Bit rate #{unsupported_bit_rate}. We support #{default_checks[ALLOWED_AUDIO_BIT_RATE]}" unless unsupported_bit_rate.empty? end end if default_checks[ALLOWED_AUDIO_CODECS] != IGNORE if audio_codecs.empty? || (audio_codecs.uniq.include? nil) missing << "audio codecs" else audio_codecs = audio_codecs.map{|a| a.downcase} unsupported_audio_codecs = audio_codecs - default_checks[ALLOWED_AUDIO_CODECS].to_a errors << "Unexpected audio codecs #{unsupported_audio_codecs}. We support #{default_checks[ALLOWED_AUDIO_CODECS]}" unless unsupported_audio_codecs.empty? end end if default_checks[ALLOWED_NUMBER_OF_AUDIO_CHANNELS] != IGNORE if number_of_audio_channels.empty? || (number_of_audio_channels.uniq.include? nil) missing << "number of audio channels" else unsupported_number_of_audio_channels = number_of_audio_channels - default_checks[ALLOWED_NUMBER_OF_AUDIO_CHANNELS].to_a errors << "Unexpected number of audio channels #{unsupported_number_of_audio_channels}. We support #{default_checks[ALLOWED_NUMBER_OF_AUDIO_CHANNELS]} channels" unless unsupported_number_of_audio_channels.empty? end end end unless missing.empty? self.error = "Couldn't find #{missing.join(",")} of the Video correctly" return false end unless errors.empty? self.error = errors.join("\n") return false end return true end |
#perform_default_video_validations ⇒ Object
def audio_checks
{
PRESENCE_OF_AUDIO_TRACK => IGNORE || VALIDATE,
ALLOWED_NUMBER_OF_AUDIO_TRACKS => (1..16)|| [2, 4, 6, 8] || IGNORE,
ALLOWED_AUDIO_CODECS => ['aac', 'ac3', 'mp2', 'mp4'] || IGNORE,
ALLOWED_AUDIO_BIT_RATE => (120..317) || [192, 317] || IGNORE,
ALLOWED_NUMBER_OF_AUDIO_CHANNELS => (1..16) || [1, 2] || IGNORE,
}
end
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/xmorph/base.rb', line 126 def perform_default_video_validations mediainfo = self.mediainfo_output video_info = mediainfo["Video"] default_checks = self.default_video_checks aspect_ratio = video_info["Display_aspect_ratio"] height = (video_info["Original_height"] || video_info["Height"]) width = (video_info["Original_width"] || video_info["Width"]) frame_rate = video_info["Frame_rate"] bit_rate = video_info["Bit_rate"] || video_info["Nominal_bit_rate"] scan_type = video_info["Scan_type"] errors = [] missing = [] if default_checks[ALLOWED_ASPECT_RATIO] != IGNORE if aspect_ratio.present? errors << "Unexpected Aspect ratio #{aspect_ratio}. We support #{default_checks[ALLOWED_ASPECT_RATIO]}" unless default_checks[ALLOWED_ASPECT_RATIO].include? aspect_ratio else missing << "Aspect ratio" end end if default_checks[ALLOWED_HEIGHT] != IGNORE if height.present? height = height.split("pixels")[0].gsub(/ /,"").to_i errors << "Unexpected Height #{height}. We support #{default_checks[ALLOWED_HEIGHT]}" unless default_checks[ALLOWED_HEIGHT].include? height else missing << "Height" end end if default_checks[ALLOWED_WIDTH] != IGNORE if width.present? width = width.split("pixels")[0].gsub(/ /,"").to_i errors << "Unexpected Width #{width}. We support #{default_checks[ALLOWED_WIDTH]}" unless default_checks[ALLOWED_WIDTH].include? width else missing << "Width" end end if default_checks[ALLOWED_FRAME_RATE] != IGNORE if frame_rate.present? frame_rate = frame_rate.split(" ")[0].to_f errors << "Unexpected Frame rate #{frame_rate}. We support #{default_checks[ALLOWED_FRAME_RATE]}" unless default_checks[ALLOWED_FRAME_RATE].include? frame_rate else missing << "Frame rate" end end if default_checks[ALLOWED_VIDEO_BIT_RATE] != IGNORE if bit_rate.present? bit_rate = bit_rate.split(" ")[0].to_f errors << "Unexpected Bit rate #{bit_rate}. We support #{default_checks[ALLOWED_VIDEO_BIT_RATE]}" unless default_checks[ALLOWED_VIDEO_BIT_RATE].include? bit_rate else missing << "Bit rate" end end if default_checks[ALLOWED_SCAN_TYPE] != IGNORE if scan_type.present? errors << "Unexpected Scan type #{scan_type}. We support #{default_checks[ALLOWED_SCAN_TYPE]}" unless default_checks[ALLOWED_SCAN_TYPE].include? scan_type.downcase else missing << "Scan type" end end unless missing.empty? self.error = "Couldn't find #{missing.join(",")} of the Video correctly" return false end unless errors.empty? self.error = errors.join("\n") return false end return true end |
#post_process ⇒ Object
98 99 100 |
# File 'lib/xmorph/base.rb', line 98 def post_process #do some post processing end |
#set_validations ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/xmorph/base.rb', line 61 def set_validations begin self.default_video_checks = self.video_checks rescue => e raise TranscoderError.new("Default video validation requirements are not defined.") end begin self.default_audio_checks = self.audio_checks rescue => e raise TranscoderError.new("Default audio validation requirements are not defined.") end return true end |
#transcode(cmd) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/xmorph/base.rb', line 91 def transcode(cmd) raise TranscoderError.new("Command passed to transcode is empty.") unless cmd status, response = Util.run_cmd_with_response(cmd) raise TranscoderError.new(self.error || response.split("\n").last) unless status return status end |
#validate_asset ⇒ Object
75 76 77 78 79 |
# File 'lib/xmorph/base.rb', line 75 def validate_asset raise TranscoderError.new(self.error || "Failed to perform default video validations.") unless perform_default_video_validations raise TranscoderError.new(self.error || "Failed to perform default audio validations.") unless perform_default_audio_validations return true end |