Reputation: 106
I'm using bitmovin-javascript on a node.js server. I'm trying to create encodings for videos on my firebase storage and save the output in my bitmovin account using the bitmovin-javascript api.
I've upgraded from the old bitmovin api (v1) for javascript (which is now deprecated) and I'm implementing the current one (v2). But every time I run the code, it shows HTTP Request was unsuccessful: HTTP Response Code was 403 Forbidden in my terminal console.
I have cross-checked and ensured that the API keys I'm using to read from the firebase storage (accesss-key & secret-key) are the valid ones as well as the bitmovin API key is also a valid one. The output-id is for bitmovin is also a valid one.
The api generates inputs and video-codec-configuarations, audio-codec-configurations & manifests but does not generate outputs or encodings.
The error seems to be occurring at the point where the api is trying to create an encoding resource.
Here's how my code looks like:
const Bitmovin = require('bitmovin-javascript').default;
const start = async () => {
const bitmovin = Bitmovin({ 'apiKey': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' });
// create the input
const input = await bitmovin.encoding.inputs.gcs.create({
name: 'Input',
accessKey: 'GOOGXXXXXXXXXXXXXXXX',
secretKey: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
bucketName: 'project-name.appspot.com'
});
// create the output
const outputId = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
// create the video and audio codec configurations
const videoCodecConfig1 = await bitmovin.encoding.codecConfigurations.h264.create({
name: 'H264 Codec Config',
bitrate: 240000,
width: 384,
profile: 'HIGH'
});
const audioCodecConfig = await bitmovin.encoding.codecConfigurations.aac.create({
name: 'my-aac-128kbit-cc',
bitrate: 128000, // 128 KBit/s
rate: 48000
});
// create the encoding resource
const encoding = await bitmovin.encoding.encodings.create({
name: 'Encoding',
cloudRegion: 'AUTO',
encoderVersion: '2.12.1'
});
// add the video and audio streams to the encoding
const inputPath = 'https://firebasestorage.googleapis.com/v0/b/project-name.appspot.com/o/new%2Fvideos%2Fsample.mp4?alt=media&token=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';
const videoStreamConfig1 = {
codecConfigId: videoCodecConfig1.id,
inputStreams: [{
inputId: input.id,
inputPath: inputPath,
selectionMode: 'AUTO'
}]
};
const streamVideo1 = await bitmovin.encoding.encodings(encoding.id).streams.add(videoStreamConfig1);
const audioStreamConfig = {
codecConfigId: audioCodecConfig.id,
inputStreams: [{
inputId: input.id,
inputPath: inputPath,
selectionMode: 'AUTO'
}]
};
const audioStream = await bitmovin.encoding.encodings(encoding.id).streams.add(audioStreamConfig);
// add the video muxings to the encoding
const segmentLength = 4;
const outputPath = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/' + Date.now();
const segmentNaming = 'seg_%number%.m4s';
const initSegmentName = 'init.mp4';
const fmp4VideoMuxingConfig1 = {
segmentLength,
segmentNaming,
initSegmentName,
streams: [{
streamId: streamVideo1.id
}],
outputs: [{
outputId: outputId,
outputPath: outputPath + '/video/384_240000/fmp4/',
acl: [{
permission: 'PUBLIC_READ'
}]
}]
};
const videoMuxing1 = await bitmovin.encoding.encodings(encoding.id).muxings.fmp4.add(fmp4VideoMuxingConfig1);
// add the audio muxing to the encoding
const fmp4AudioMuxingConfig = {
segmentLength,
segmentNaming,
initSegmentName,
streams: [{
streamId: audioStream.id
}],
outputs: [{
outputId: outputId,
outputPath: outputPath + '/audio/128000/fmp4/',
acl: [{
permission: 'PUBLIC_READ'
}]
}]
};
const fmp4AudioMuxing = await bitmovin.encoding.encodings(encoding.id).muxings.fmp4.add(fmp4AudioMuxingConfig);
//create the manifest
const manifestConfig = {
name: 'Manifest',
manifestName: 'manifest.mpd',
outputs: [{
outputId: outputId,
outputPath: outputPath,
acl: [{
permission: 'PUBLIC_READ'
}]
}]
};
const manifest = await bitmovin.encoding.manifests.dash.create(manifestConfig);
const period = await bitmovin.encoding.manifests.dash(manifest.id).periods.add({});
let videoAdaptationSet = {
};
let audioAdaptationSet = {
lang: 'en'
};
videoAdaptationSet = await bitmovin.encoding.manifests
.dash(manifest.id)
.periods(period.id)
.adaptationSets.video.create(videoAdaptationSet);
audioAdaptationSet = await bitmovin.encoding.manifests
.dash(manifest.id)
.periods(period.id)
.adaptationSets.audio.create(audioAdaptationSet);
// Adding Audio Representation
const fmp4AudioRepresentation = {
type: 'TEMPLATE',
encodingId: encoding.id,
muxingId: fmp4AudioMuxing.id,
segmentPath: 'audio/128000/fmp4'
};
await bitmovin.encoding.manifests
.dash(manifest.id)
.periods(period.id)
.adaptationSets(audioAdaptationSet.id)
.representations.fmp4
.add(fmp4AudioRepresentation);
// Adding Video Representation
const fmp4VideoRepresentation1 = {
type: 'TEMPLATE',
encodingId: encoding.id,
muxingId: videoMuxing1.id,
segmentPath: 'video/384_240000/fmp4'
};
await bitmovin.encoding.manifests
.dash(manifest.id)
.periods(period.id)
.adaptationSets(videoAdaptationSet.id)
.representations.fmp4
.add(fmp4VideoRepresentation1);
// start the encoding
await bitmovin.encoding.encodings(encoding.id).start();
// wait for the encoding to be finished
await finish(encoding);
//start and wait for the manifest to be finished
await bitmovin.encoding.manifests.dash(manifest.id).start();
console.log('Generating DASH manifest...');
const waitForManifestToBeFinished = async () => {
let manifestResponse;
do {
await bitmovin.encoding.manifests
.dash(manifest.id)
.status()
.then(response => {
console.log('DASH Manifest status is ' + response.status);
manifestResponse = response;
});
await new Promise(resolve => setTimeout(resolve, 2000));
}
while (manifestResponse.status === 'RUNNING' || manifestResponse.status === 'CREATED');
};
await waitForManifestToBeFinished();
console.log('Everything finished...');
function getStatus(encoding) {
return bitmovin.encoding.encodings(encoding.id).status();
}
function finish(encoding, interval = 5 * 1000, timeout = 5 * 60 * 1000) {
let t, s = new Date();
const check = (resolve, reject) => {
clearTimeout(t);
t = setTimeout(() => {
getStatus(encoding)
.then(current => {
console.log('Encoding progress: ' + current.progress);
if (current.status === 'FINISHED') {
return resolve(current);
}
if (current.status === 'ERROR') {
return reject('Encoding error');
}
if (new Date() - s >= timeout) {
return reject('Timeout reached');
}
check(resolve, reject);
});
}, interval);
}
return new Promise((resolve, reject) => {
check(resolve, reject);
});
}
}
start().catch(e => console.log(e.message));
I expect the api to read my firebase storage, encode the video from that storage, store it under my bitmovin outputs, provide me with a bitmovin link to the output so that I can save it to my own database.
Help on this would greatly be appreciated.
Upvotes: 0
Views: 525
Reputation: 31
I haven't noticed any specific issue with the code snippet you provided so far. The issue could however be caused by another factor, such as the input / output settings or the input file itself.
Please feel free to reach out to [email protected] and provide the encoding ID as well as the input file in order for us to investigate this into more detail.
Upvotes: 1