'Node - fluent-ffmpeg RTSP to Kinesis Video Stream PutMedia API

What I'm trying to do is go from RTSP -> FFMPEG -> MKV -> PutMedia in a stream with low latency.

This is the best attempt I have so far which has two problems, the first being authentication doesn't work no matter how which variant of trying to sign the request I use.

import KinesisVideo from "aws-sdk/clients/kinesisvideo";
import Stream from "stream";
import aws4 from "aws4";
import fetch from "node-fetch";
import ffmpeg from "fluent-ffmpeg";
import { defaultProvider } from "@aws-sdk/credential-provider-node";


const client = new KinesisVideo({
    region: "ap-southeast-2",
});
const endpoint = await client
    .getDataEndpoint({
        StreamName: "video-stream",
        APIName: "PUT_MEDIA",
    })
    .promise();
if (!endpoint.DataEndpoint) return { statusCode: 400, body: "No stream found." };
const Writable = new Stream.Writable({
    async write(chunk, _, next) {
        const result = await defaultProvider()().then((creds) => {
            return aws4.sign(
                {
                    protocol: "https",
                    host: endpoint.DataEndpoint?.replace("https://", "") || "",
                    path: "/putMedia",
                    service: "kinesisvideo",
                    method: "POST",
                    region: "ap-southeast-2",
                    headers: {
                        "x-amzn-stream-name": "video-stream",
                        "x-amzn-stream-arn": "ARN HERE",
                        "x-amzn-fragment-timecode-type": "RELATIVE",
                        "x-amzn-producer-start-timestamp": new Date().toJSON(),
                    },
                    body: chunk,
                },
                creds,
            );
        });
        fetch(`${endpoint.DataEndpoint}/putMedia`, {
            method: "POST",
            headers: result.headers,
            body: result.body,
        })
            .then((res) => {
                console.log(res);
                return res.text();
            })
            .then((text) => console.log(text))
            .catch((e) => console.log("error: ", e));
        next();
    },
});
ffmpeg("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4").format("matroska").stream(Writable);

I have the correct IAM policies "kinesisvideo:*" and the current error I'm getting doesn't look IAM related.

The error is:

the request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the Service documentation for more detials.

At the moment I'm purely trying to get authentication to /putMedia working over fetch.

How can I fix this error?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source