UNPKG

@eluvio/elv-utils-js

Version:

Utilities for the Eluvio Content Fabric

186 lines (168 loc) 5.51 kB
// arguments for working with variant streams const R = require('@eluvio/ramda-fork') const FractionStrModel = require('@eluvio/elv-js-helpers/Model/FractionStrModel') const {NewOpt} = require('../options') const ArgAlternateFor = require('./args/ArgAlternateFor') const ArgRole = require('./args/ArgRole') const ArgStreamKey = require('./ArgStreamKey') const ArgVariantKey = require('./ArgVariantKey') const blueprint = { name: 'VariantStreamArgs', concerns: [ArgAlternateFor, ArgRole, ArgStreamKey, ArgVariantKey], options: [ NewOpt('deinterlace', { descTemplate: 'Video deinterlace method', type: 'string', choices: ['bwdif_field', 'bwdif_frame'] }), NewOpt('label', { descTemplate: 'Stream label to show in UI', type: 'string' }), NewOpt('language', { alias: 'lang', descTemplate: 'Language code for stream (ISO 639-1)', type: 'string' }), NewOpt('isDefault', { descTemplate: 'Make this stream the default for its media type', type: 'boolean' }), NewOpt('file', { descTemplate: 'File within master object to use as stream source', type: 'string' }), NewOpt('targetFrameRate', { descTemplate: 'Frame rate to use for mezzanine video stream', type: 'string', coerce: FractionStrModel }), NewOpt('targetTimebase', { descTemplate: 'Timebase to use for mezzanine stream', type: 'string', coerce: FractionStrModel }), NewOpt('mapping', { choices: [ '2MONO_1STEREO', // combine 2 mono audio streams into a single stereo audio stream '2CHANNELS_1STEREO', // extract 2 channels from a single multichannel stream, combine into a single stereo audio stream '5CHANNELS_1STEREO', // extract 5 channels from a single multichannel stream, combine into a single stereo stream (mixdown) '5MONO_1STEREO', // combine 5 mono streams into a single stereo stream (mixdown) '6CHANNELS_1SURROUND', // extract 6 channels from a single multichannel stream, combine into a single 5.1 audio stream '6MONO_1SURROUND' // combine 6 mono audio streams into a single 5.1 audio stream ], descTemplate: 'Mapping for an audio stream', type: 'string' }), NewOpt('channelIndex', { descTemplate: 'Channel(s) of stream to use from file. (Only applies to audio streams)', type: 'array' }), NewOpt('streamIndex', { descTemplate: 'Index(es) of stream(s) to use from file. (Currently only audio streams can use more than 1 stream index)', type: 'array' }), NewOpt('multipliers', { alias: 'mult', descTemplate: 'Audio level adjustment factor(s)', type: 'array' }), ] } const New = () => { const optsFromStream = stream => { const {label, language, role} = stream const alternateFor = stream.alternate_for const deinterlace = stream.deinterlace const isDefault = stream.default_for_media_type const mapping = stream.mapping_info const file = stream.sources[0].files_api_path const streamIndex = stream.sources.map(x => x.stream_index) const targetFrameRate = stream.target_frame_rate const targetTimebase = stream.target_timebase const foundChannelIndexes = stream.sources.map(x => x.channel_index).filter(x=>x) const channelIndex = R.isEmpty(foundChannelIndexes) ? undefined : foundChannelIndexes const foundMultipliers = stream.sources.map(x => x.multiplier).filter(x=>x) const multipliers = R.isEmpty(foundMultipliers) ? undefined : foundMultipliers return { alternateFor, channelIndex, deinterlace, file, label, language, isDefault, mapping, multipliers, role, streamIndex, targetFrameRate, targetTimebase } } const streamFromOpts = (sources, opts) => { const { alternateFor, channelIndex, deinterlace, file, label, language, isDefault, mapping, multipliers, role, streamIndex, targetFrameRate, targetTimebase } = opts if(!sources[file]) throw Error(`Source '${file}' not found in master. If the file exists in the object, run utilities/MasterUpdateSources.js first.`) const result = { alternate_for: alternateFor, default_for_media_type: isDefault, deinterlace, label, language, mapping_info: mapping, role, sources: [], target_frame_rate: targetFrameRate, target_timebase: targetTimebase } const source = sources[file] result.type = source.streams[streamIndex[0]].type .replace('Stream','').toLowerCase() for(const [streamArgNum, sIndex] of streamIndex.entries()) { if(channelIndex) { for(const [channelArgNum, cIndex] of channelIndex.entries()) { result.sources.push( { channel_index: cIndex, files_api_path: file, multiplier: multipliers ? multipliers[channelArgNum] : undefined, stream_index: sIndex, }) } } else { result.sources.push( { files_api_path: file, multiplier: multipliers ? multipliers[streamArgNum] : undefined, stream_index: sIndex, }) } } return result } // instance interface return { optsFromStream, streamFromOpts } } module.exports = { blueprint, New }