So we want to implement DRM on our current implementation of progressive-ts muxing. How can we go about it? We want to implement it on both android and iOS. Please find our current encoding code pasted below. Also, We are using m3u8 files on both android and iOS. To start encoding one needs to call encodeMedia function. On the player side, we are using exoplayer for android and AVQueuePlayer for iOS.If any more info is required please do let me know.
const BitmovinApi = require("@bitmovin/api-sdk").default;
const {
AacAudioConfiguration,
AclEntry,
AclPermission,
AudioMediaInfo,
CloudRegion,
Encoding,
EncodingOutput,
GcsInput,
GcsOutput,
HlsManifest,
HlsVersion,
MuxingStream,
ProgressiveTsMuxing,
Stream,
StreamInput,
StreamSelectionMode,
} = require('@bitmovin/api-sdk');
const createInputGCSHandle = (bitmovinApi, gcsHandleName, bucketName) => {
return bitmovinApi.encoding.inputs.gcs.create(
new GcsInput({
name: gcsHandleName,
accessKey: process.env.GCS_ACCESS_KEY,
secretKey: process.env.GCS_SECRET_KEY,
bucketName: bucketName,
})
);
}
const createOutputGCSHandle = (bitmovinApi, gcsHandleName, bucketName) => {
return bitmovinApi.encoding.outputs.gcs.create(
new GcsInput({
name: gcsHandleName,
accessKey: process.env.GCS_ACCESS_KEY,
secretKey: process.env.GCS_SECRET_KEY,
bucketName: bucketName,
})
);
}
const getEncodingHandle = (bitmovinApi, encodingHandleName) => {
return bitmovinApi.encoding.encodings.create(
new Encoding({
name: encodingHandleName,
cloudRegion: CloudRegion.GOOGLE_ASIA_SOUTHEAST_1
})
);
}
const createCodecConfigHandle = (bitmovinApi, audioConfigName, bitrateValue) => {
return bitmovinApi.encoding.configurations.audio.aac.create(
new AacAudioConfiguration({
name: audioConfigName,
bitrate: bitrateValue
})
);
}
const createStreamInputObject = (gcsId, inputPath) => {
return new StreamInput({
inputId: gcsId,
inputPath: inputPath,
selectionMode: StreamSelectionMode.AUTO
});
}
const createAudioStreamHandle = (bitmovinApi, encodingHandleId, audioCodecConfigurationId, audioStreamInput) => {
return bitmovinApi.encoding.encodings.streams.create(
encodingHandleId,
new Stream({
codecConfigId: audioCodecConfigurationId,
inputStreams: [audioStreamInput]
})
);
}
const createAudioMuxingHandle = (bitmovinApi, encodingHandleId, fileName, audioStreamHandleId, gcsOutputHandleId, fileOutputPath) => {
// const segmentLength = 10;// 0
// const segmentNaming = 'seg_%number%.ts';
return bitmovinApi.encoding.encodings.muxings.progressiveTs.create(
encodingHandleId,
new ProgressiveTsMuxing({
// segmentLength: segmentLength,
// segmentNaming: segmentNaming,
filename: fileName,
streams: [new MuxingStream({ streamId: audioStreamHandleId })],
outputs: [
new EncodingOutput({
outputId: gcsOutputHandleId,
outputPath: fileOutputPath || '/',
acl: [new AclEntry({
permission: AclPermission.PUBLIC_READ
})]
})
]
})
);
}
const createHlsManifest = (bitmovinApi, handleName, fileName, gcsOutputHandleId, fileOutputPath) => {
return bitmovinApi.encoding.manifests.hls.create(
new HlsManifest({
name: handleName,
manifestName: fileName,
hlsMediaPlaylistVersion: HlsVersion.HLS_V4,
hlsMasterPlaylistVersion: HlsVersion.HLS_V4,
outputs: [
new EncodingOutput({
outputId: gcsOutputHandleId,
outputPath: fileOutputPath || '/',
acl: [new AclEntry({
permission: AclPermission.PUBLIC_READ
})]
})
]
})
);
}
exports.getCurrentStatus = async (encodingId) => {
const bitmovinApi = new BitmovinApi({
apiKey: process.env.BITMOVIN_API_KEY
});
return await bitmovinApi.encoding.encodings.status(encodingId)
}
exports.encodeMedia = async (filePath, outputPath, bucketName) => {
const inputPath = filePath;
const fileName = filePath.replace(/^.*[\\\/]/, '').split('.')[0];
const bitmovinApi = new BitmovinApi({
apiKey: process.env.BITMOVIN_API_KEY
});
try {
console.info('encodeMedia', 'Started encoding file:', inputPath, 'For output:', outputPath, 'For bucket', bucketName);
const gcsInputHandle = await createInputGCSHandle(bitmovinApi, 'GCS_INPUT', bucketName);
console.info('encodeMedia', `Created Input GCS`);
const encodingHandle = await getEncodingHandle(bitmovinApi, 'MEDIA_ENCODER')
console.info('encodeMedia', 'Created encoding instance');
const gcsOutputHandle = await createOutputGCSHandle(bitmovinApi, 'GCS_OUTPUT', bucketName);
console.info('encodeMedia', 'Created Output GCS');
console.debug('encodeMedia', 'Bitrates', process.env.BITRATE_LOW, process.env.BITRATE_MED, process.env.BITRATE_HIGH);
const audioCodecConfigurationLow = await createCodecConfigHandle(bitmovinApi, 'AUDIO_CODEC_LOW', process.env.BITRATE_LOW);
const audioCodecConfigurationMed = await createCodecConfigHandle(bitmovinApi, 'AUDIO_CODEC_MED', process.env.BITRATE_MED);
const audioCodecConfigurationHigh = await createCodecConfigHandle(bitmovinApi, 'AUDIO_CODEC_HIGH', process.env.BITRATE_HIGH);
console.info('encodeMedia', 'Created audioCode configs');
const audioStreamInputLow = createStreamInputObject(gcsInputHandle.id, inputPath);
const audioStreamInputMed = createStreamInputObject(gcsInputHandle.id, inputPath);
const audioStreamInputHigh = createStreamInputObject(gcsInputHandle.id, inputPath);
console.info('encodeMedia', 'Created Audio stream Input');
const audioStreamHandleLow = await createAudioStreamHandle(bitmovinApi,
encodingHandle.id,
audioCodecConfigurationLow.id,
audioStreamInputLow);
const audioStreamHandleMed = await createAudioStreamHandle(bitmovinApi,
encodingHandle.id,
audioCodecConfigurationMed.id,
audioStreamInputMed);
const audioStreamHandleHigh = await createAudioStreamHandle(bitmovinApi,
encodingHandle.id,
audioCodecConfigurationHigh.id,
audioStreamInputHigh);
console.info('encodeMedia', 'Created Audio stream Handle');
const lowAudioMuxingHandle = await createAudioMuxingHandle(
bitmovinApi,
encodingHandle.id,
`${fileName}Low.ts`,
audioStreamHandleLow.id,
gcsOutputHandle.id,
outputPath);
const medAudioMuxingHandle = await createAudioMuxingHandle(
bitmovinApi,
encodingHandle.id,
`${fileName}Med.ts`,
audioStreamHandleMed.id,
gcsOutputHandle.id,
outputPath);
const highAudioMuxingHandle = await createAudioMuxingHandle(
bitmovinApi,
encodingHandle.id,
`${fileName}High.ts`,
audioStreamHandleHigh.id,
gcsOutputHandle.id,
outputPath);
console.info('encodeMedia', 'Audio Muxing handle created');
console.info('encodeMedia', 'Encoding started');
await bitmovinApi.encoding.encodings.start(encodingHandle.id);
console.info('encodeMedia', 'Encoding Ended');
const manifest = await createHlsManifest(bitmovinApi,
'MANIFEST_FILE',
`${fileName}.m3u8`,
gcsOutputHandle.id,
outputPath);
const audioMediaInfoLow = new AudioMediaInfo({
name: 'my-audio-media-low',
groupId: 'audio_group_low',
segmentPath: '',
uri: `${fileName}Low.m3u8`,
encodingId: encodingHandle.id,
streamId: audioStreamHandleLow.id,
muxingId: lowAudioMuxingHandle.id,
language: 'en',
autoselect: true,
isDefault: true
});
const audioMediaInfoMed = new AudioMediaInfo({
name: 'my-audio-media-med',
groupId: 'audio_group_med',
segmentPath: '',
uri: `${fileName}Med.m3u8`,
encodingId: encodingHandle.id,
streamId: audioStreamHandleMed.id,
muxingId: medAudioMuxingHandle.id,
language: 'en',
autoselect: true
});
const audioMediaInfoHigh = new AudioMediaInfo({
name: 'my-audio-media-high',
groupId: 'audio_group_high',
segmentPath: '',
uri: `${fileName}High.m3u8`,
encodingId: encodingHandle.id,
streamId: audioStreamHandleHigh.id,
muxingId: highAudioMuxingHandle.id,
language: 'en',
autoselect: true
});
console.info('encodeMedia', 'Creating Manifest');
await bitmovinApi.encoding.manifests.hls.media.audio.create(manifest.id, audioMediaInfoLow);
await bitmovinApi.encoding.manifests.hls.media.audio.create(manifest.id, audioMediaInfoMed);
await bitmovinApi.encoding.manifests.hls.media.audio.create(manifest.id, audioMediaInfoHigh);
//await bitmovinApi.encoding.manifests.hls.start(manifest.id);
console.info('encodeMedia', 'Manifest creation done');
console.info('encodeMedia', 'Ended encoding.');
return {
manifestFilePath: `${outputPath}${manifest.manifestName}`,
inputFilePath: inputPath,
outputPath: outputPath,
manfestFile: manifest.manifestName,
encodingId: encodingHandle.id,
manifestId: manifest.id
};
} catch (ex) {
console.error('encodeMedia', 'Error while encoding', ex);
}
}
exports.startManifestCreation = async (manifestId) => {
const bitmovinApi = new BitmovinApi({
apiKey: process.env.BITMOVIN_API_KEY
});
await bitmovinApi.encoding.manifests.hls.start(manifestId);
};