
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
Morphs things from one kind to another. Transcodes, in local speak, for example..
$ gem install xmorph
For a specific version:
$ gem install xmorph -v 0.1.5
Once you have written XMorph profile for a customer, test if it's working fine. Get base class object for a given customer
transcoder = XMorph::Base.get_transcode_template(HOST, ACCOUNT_DOMAIN, ACCOUNT_NAME, ASSET_PATH)
transcoder = XMorph::Base.get_transcode_template("cinedigm", "Cinedigm", "amagi", "/home/tejaswini/volt/cinedigm/PRAYERLINK112718CC.mxf")
transcoder is object for a customer class, in case XMorph is able to find corresponding customers transcoding setup, else it'll raise TranscoderError exception. You can also pass extra param, which will return the filepath it loaded inorder to pick customer specific transcode setup.
transcoder, loaded_filepath = XMorph::Base.get_transcode_template("cinedigm", "Cinedigm", "amagi", "/home/tejaswini/volt/cinedigm/PRAYERLINK112718CC.mxf", true)
Here loaded_filepath will be
/home/tejaswini/src/xmorph/lib/xmorph/customers/cinedigm/Cinedigm/transcode.rb
Get mediainfo for the asset with:
transcoder.get_asset_details
If XMorph is not able to get mediainfo of the asset, it will raise exception. If it was success you can access mediainfo with, which will be a hash.
transcoder.mediainfo_output
Perform default validations on the asset once you get mediainfo.
transcoder.validate_asset
This function will validate the asset against the requirements mentioned in video_checks and audio_checks methods for a given customer. It will either return true or raise exception incase of failure.
Once the asset is validated, try to get suitable profile for the same.
ruby ffmpeg_command = transcoder.get_profile
or profile_name, ffmpeg_cmd = transcoder.get_profile
to get profile name as well.
The ffmpeg command come with %{IN} and %{OUT} replace them with input filepath and output filepath and pass as parameter for, transcoder.transcode(updated_ffmpeg_command)
$ cd xmorph
$ ./bin/console
$ transcoder = XMorph::Base.get_transcode_template("cinedigm", "Cinedigm", "amagi", "/home/tejaswini/volt/cbn/PRAYERLINK112718CC.mxf")
$ transcoder, loaded_filepath = XMorph::Base.get_transcode_template("cinedigm", "Cinedigm", "amagi", "/home/tejaswini/volt/cbn/PRAYERLINK112718CC.mxf", true)
$ transcoder.get_asset_details
$ transcoder.validate_asset
$ ffmpeg_cmd = transcoder.get_profile
$ profile_name, ffmpeg_cmd = transcoder.get_profile(true)
$ transcoder.transcode(ffmpeg_cmd % {IN: asset_path, OUT: tmp_file.path})
$ cd xmorph/lib/xmorph/customers
$ mkdir -p HOST/ACCOUNT_DOMAIN/
$ cd HOST/ACCOUNT_DOMAIN/
$ vi transcode.rb
Here, HOST is customer in customer.amagi.tv and ACCOUNT_DOMAIN is account.domain EX: for cinedigm.amagi.tv HOST is cinedigm and account's domain is Cinedigm Interfaces to be implemented in transcodee.rb,
class Transcode < XMorph::Base
#define constants for set of profiles which says what the corresponding command does, or what the input asset is
SCALE_TO_720x480_4_3 = "720x480_4_3"
SCALE_TO_720x480_16_9 = "720x480_16_9"
SCALE_TO_1920x1080_16_9 = "1920x1080_16_9"
SCALE_TO_720x480_3_2 = "720x480_3_2"
#set the profiles using the constants defined earlier
def set_profiles
self.profiles = {
SCALE_TO_720x480_4_3 => "ffmpeg -y -i %{IN} $options to perform transcoding/encoding$ %{OUT} 2>&1",
SCALE_TO_720x480_16_9 => "ffmpeg -y -i %{IN} $options to perform transcoding/encoding$ %{OUT} 2>&1",
SCALE_TO_1920x1080_16_9 => "ffmpeg -y -i %{IN} $options to perform transcoding/encoding$ %{OUT} 2>&1",
SCALE_TO_720x480_3_2 => "ffmpeg -y -i %{IN} $options to perform transcoding/encoding$ %{OUT} 2>&1",
}
end
#values for the sollowing validations can be Range, Array or IGNORE(upcase)
#Range - (n1..n2) - applicable if the values are numbers, validates if value x is between n1 and n2, it also includes fractions. ex 5: in (1..10) -> true and 29.97 in (25..30) -> true
#Array - [n1,n2] - validates if value x is in the given array. ex: 5 in [1,10] -> false and 1 in [1,10] -> true
#IGNORE will skip validation for the corresponding parameter. it will not even check if media has that parameter. i.e if mediainfo is not able to read parameter x for the asset, its validation will still return true.
#These methods are to be implemented in the sub class, there's no defaut method defined in the base class, exception is raised if these methods are not found.
def video_checks
{
ALLOWED_ASPECT_RATIO => ["4:3", "16:9"] || IGNORE,
ALLOWED_HEIGHT => (400..1080) || [720, 1080, 546] || IGNORE,
ALLOWED_WIDTH => (640..720) || [720, 1920] || IGNORE,
ALLOWED_FRAME_RATE => (25..30) || [25, 29.970, 24] || IGNORE,
ALLOWED_VIDEO_BIT_RATE => (8..32) || [8, 32] || IGNORE,
ALLOWED_SCAN_TYPE => ['progressive', 'interlaced'] || IGNORE,
}
end
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', 'ac-3', 'mp2', 'mp4', 'dolby e', 'mpeg audio'] || IGNORE,
ALLOWED_AUDIO_BIT_RATE => (120..317) || [192, 317] || IGNORE,
ALLOWED_NUMBER_OF_AUDIO_CHANNELS => (1..16) || [1, 2] || IGNORE,
}
end
#Write summary as what are the combinations of profiles we get for this customer, and based on which parameters we choose the profile.
# have a set of conditional statements to choose a profile defined above.
def set_profile_name
self.profile_name = nil
self.error = nil
mediainfo = self.mediainfo_output
video_info = mediainfo["Video"]
audio_tracks = mediainfo["Audio"]
#Once you have videoinfo and audiotracks info, write a set of if else statements to choose a profile from the above defined
#Assign profile name to self.profile_name
#Assign any error messages you want to display on UI to self.error, make sure error messages are unambiguous
#EX: self.error = "Got unexpected width-#{width} for video with AR-#{aspect_ratio}, expected width: 640 or 720"
#Ensure there's only if..elseif statements rather than if..else
XMorph::Base.logger.debug("XMorph#set_profile_name#Cinedigm: using profile #{self.profile_name}") unless self.profile_name.nil?
return true
end
FAQs
Unknown package
We found that amagi_transcode demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.