将 Kinesis Vides Stream /GetMedia 结果转换为音频文件 - node.js

问题描述 投票:0回答:1

目前,我正在尝试将 Kinesis Vides Stream GetMedia API 的响应转换为音频文件,但没有成功。根据 AWS 文档, - GetMedia 请求 的结果?建议使用Kinesis Video Stream Parser Library。但我想使用 js/ts 实现。是否可以仅使用 js/ts 将此流转换为音频文件?

谢谢您的帮助。

node.js amazon-web-services mkv amazon-kinesis-video-streams
1个回答
0
投票

我终于弄清楚如何将 Kinesis Video Stream 转换为音频文件。这就是我使用 Node.js 和适用于 JavaScript 的 AWS 开发工具包完成此操作的方法:

>> mkdir aws-sdk-js && cd aws-sdk-js
>> npm init

选择默认的npm选项后,打开新生成的

package.json
文件并添加以下内容:

 "dependencies": {
    "aws-sdk": "^2.1587.0”,
    “ebml”: “^3.0.0”
 }

现在安装 SDK 模块:

>> npm install
>> touch index.js

然后在

index.js
文件中,复制并粘贴以下内容:

const AWS = require("aws-sdk");
const ebml = require("ebml");
const fs = require("fs");

const region = "<your AWS region>";
const streamInfo = {
    streamName: "<your Kinesis Video stream name>",
    startFragmentNumber: "<your Kinesis Video fragment number>",
    //streamArn: "<your Kinesis Video stream ARN>"
};

// Suppress AWS SDK version warning message
process.env["AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE"] = 1;


async function main() {        
    //const streamName = streamInfo.streamArn.split("stream/")[1].split("/")[0];
    const streamName = streamInfo.streamName;
    const fragmentNumber =  streamInfo.startFragmentNumber;
    
    const raw = await getMedia(streamName, fragmentNumber);

    const wav = Converter.createWav(raw, 8000);

    fs.writeFile("audio.wav", Buffer.from(wav.buffer), (err) => {
        if (err) throw err;
        console.log("Audio file saved.");
    });
    
    return {};
};


async function getMedia(streamName, fragmentNumber) {
    // Obtain the Kinesis Video endpoint URL
    const kinesisvideo = new AWS.KinesisVideo({region: region});
    var params = {
        APIName: "GET_MEDIA",
        StreamName: streamName
    };
    const end = await kinesisvideo.getDataEndpoint(params).promise();

    // Get the raw audio data
    const kinesisvideomedia = new AWS.KinesisVideoMedia({endpoint: end.DataEndpoint, region:region});
    var params = {
        StartSelector: { 
            StartSelectorType: "FRAGMENT_NUMBER",
            AfterFragmentNumber: fragmentNumber,
        },
        StreamName: streamName
    };
    const data = await kinesisvideomedia.getMedia(params).promise();
    const decoder = new ebml.Decoder();
    let chunks = [];
    decoder.on("data", chunk => {
        if(chunk[1].name == "SimpleBlock"){
            chunks.push(chunk[1].data);
        }
    });
    decoder.write(data["Payload"]);
    
    // Join the audio chunks
    const margin = 4;
    var sumLength = 0;
    chunks.forEach( chunk => {
        sumLength += chunk.byteLength - margin;
    })
    var sample = new Uint8Array(sumLength);
    var pos = 0;
    chunks.forEach(chunk => {
        let tmp = new Uint8Array(chunk.byteLength - margin);
        for(var e = 0; e < chunk.byteLength -  margin; e++){
            tmp[e] = chunk[e + margin];
        }
        sample.set(tmp, pos);
        pos += chunk.byteLength - margin;

    })
    return sample.buffer;
}


class Converter {
    // Convert the raw audio into wav format
    static createWav(samples, sampleRate) {
        const len = samples.byteLength;
        const view = new DataView(new ArrayBuffer(44 + len));
        this._writeString(view, 0, "RIFF");
        view.setUint32(4, 32 + len, true);
        this._writeString(view, 8, "WAVE");
        this._writeString(view, 12, "fmt ");
        view.setUint32(16, 16, true);
        view.setUint16(20, 1, true); // リニアPCM
        view.setUint16(22, 1, true); // モノラル
        view.setUint32(24, sampleRate, true); 
        view.setUint32(28, sampleRate * 2, true);
        view.setUint16(32, 2, true);
        view.setUint16(34, 16, true);
        this._writeString(view, 36, "data");
        view.setUint32(40, len, true);
        let offset = 44;
        const srcView = new DataView(samples);
        for (var i = 0; i < len; i+=4, offset+=4) {
            view.setInt32(offset, srcView.getUint32(i));
        }
        return view;
    }
    
    static _writeString(view, offset, string) {
        for (var i = 0; i < string.length; i++) {
          view.setUint8(offset + i, string.charCodeAt(i));
        }
    }
}

main();

运行脚本:

>> node index.js

这应该输出

audio.wav
文件!

© www.soinside.com 2019 - 2024. All rights reserved.