我在 node.js 服务器上使用 bitmovin-javascript。我正在尝试为我的 firebase 存储上的视频创建编码,并使用 bitmovin-javascript api 将输出保存在我的 bitmovin 帐户中。
我已经从用于 javascript 的旧 bitmovin api (v1) 升级(现在已弃用),我正在实施当前的 (v2)。但是每次我运行代码时,它都会显示HTTP 请求不成功:我的终端控制台中的 HTTP 响应代码是 403 Forbidden。
我已经交叉检查并确保我用来从 Firebase 存储中读取的 API 密钥(访问密钥和秘密密钥)是有效的,并且 bitmovin API 密钥也是有效的。用于 bitmovin 的输出 ID 也是有效的。
该 API 生成输入和视频编解码器配置、音频编解码器配置和清单,但不生成输出或编码。
该错误似乎发生在api试图创建编码资源的地方。
这是我的代码的样子:
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));
我希望 api 能够读取我的 firebase 存储,对来自该存储的视频进行编码,将其存储在我的 bitmovin 输出下,为我提供指向输出的 bitmovin 链接,以便我可以将其保存到我自己的数据库中。
对此的帮助将不胜感激。