无法从kinesis下载视频剪辑

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

我使用下面的代码来下载该剪辑。我已成功收到回复,我正在尝试下载视频,但无法下载。

const completeUrl = url + "/getClip";

const res = await client.post(completeUrl, params, {
          headers: {
            "Content-Type": "video/mp4",
            "X-Amz-Target": "CodeBuild_20161006.StartBuild",
          },
        });
    
console.log("axios signedRquest is ", res);


   var binaryData: any = [];
        binaryData.push(res.data);

        const downloadElement = document.createElement("a");
        const href = window.URL.createObjectURL(
          new Blob(binaryData, { type: contentType })
        );
        downloadElement.href = href;
        downloadElement.download = "test.mp4";
        document.body.appendChild(downloadElement);
        downloadElement.click();
        document.body.removeChild(downloadElement);
        window.URL.revokeObjectURL(href);
amazon-kinesis-video-streams amazon-kinesis
3个回答
0
投票

我通过在请求中添加

responseType: "blob"
找到了解决方案

const res = await client.post(completeUrl, params, {
          headers: {
            "Content-Type": "video/mp4",
            "X-Amz-Target": "CodeBuild_20161006.StartBuild",
          },
          responseType: "blob", // added this line
        });

0
投票

万一有人来到这里...

这有效!

export const downloadStream = async function (stream, timeStampStart, length) {


var streamName = stream.id;
const credentials = await Auth.currentCredentials();
var params = {
    credentials: credentials,
    region: "us-east-1"
}

const timeStampEnd = timeStampStart + (length * 60 * 1000);


//get endpoint first
const kinesisVideo = new KinesisVideoClient(params);

params["APIName"] = "GET_CLIP";
params["StreamName"] = streamName;

const endPCommand = new GetDataEndpointCommand(params);


await kinesisVideo
    .send(endPCommand)
    .then((data) => {
        // console.log(JSON.stringify(data))
        params["endpoint"] = data.DataEndpoint;
    })
    .catch((error) => {
        console.log(error)
    })
    .finally(() => {
        // finally.
    });



const kinesisVideoArchived = new KinesisVideoArchivedMedia(params);

const dnlparams = {


    StreamName: streamName,

    ClipFragmentSelector: {
        FragmentSelectorType: ClipFragmentSelectorType.PRODUCER_TIMESTAMP,
        TimestampRange: {

            StartTimestamp: new Date(timeStampStart),
            EndTimestamp: new Date(timeStampEnd)
        }
    },
};

const dnlCommand = new GetClipCommand(dnlparams);

//getClip

await kinesisVideoArchived
    .send(dnlCommand)
    .then(async (data) => {
        console.log(data)
        const link = document.createElement("a");

        const byt = await data.Payload.transformToByteArray();

        const file = new Blob([byt], { type: 'video/mp4' });

        link.href = URL.createObjectURL(file);
        link.download = "clip.mp4";
        link.click();
        URL.revokeObjectURL(link.href);
  
    })
    .catch((error) => {
        console.log(error)
    })
    .finally(() => {
        // finally.
    });

}


0
投票

对于那些一直坚持这个问题并想要一个使用 python 的简单端到端解决方案的人。下面是代码:

import boto3
from datetime import datetime, timedelta
import time

def lambda_handler(event, context):

    # Initialize AWS SDK
    session = boto3.Session()
    client = session.client('kinesis-video-archived-media')
    kvs = session.client('kinesisvideo')

    # Obtain the endpoint using GetDataEndpoint
    get_data_endpoint_response = kvs.get_data_endpoint(
        StreamName='<Your-stream-name>',
        APIName='GET_CLIP'
    )

    # Extract the endpoint
    endpoint = get_data_endpoint_response['DataEndpoint']

    # Create a new client using the obtained endpoint
    client = session.client('kinesis-video-archived-media', endpoint_url=endpoint)

    # Specify the stream name and timestamp range for the clip
    stream_name = '<Your-stream-name>'
    start_timestamp = datetime(2023, 10, 5, 7, 9, 50)    #example values you can adjust this according to your stream
    end_timestamp = datetime(2023, 10, 5, 7, 10, 59)     #example values you can adjust this according to your stream
    chunk_size = 85 * 1024 * 1024  # 85 MB chunks    #using this as the getClip API has limit of 100MB or 200 fragments

    # Initialize variables
    current_timestamp = start_timestamp
    clip_data = b''
    clip_number = 1
    reached_end = False 

    total_frames = 0
    total_fragments = 0

    while current_timestamp < end_timestamp:
        # Calculate the end timestamp for the current chunk
        chunk_end_timestamp = current_timestamp + timedelta(minutes=5)
        if chunk_end_timestamp > end_timestamp:
            chunk_end_timestamp = end_timestamp

        try:

            # Call the get_clip API to retrieve the video clip for the current chunk
            response = client.get_clip(
                StreamName=stream_name,
                ClipFragmentSelector={
                    'FragmentSelectorType': 'SERVER_TIMESTAMP',
                    'TimestampRange': {
                        'StartTimestamp': current_timestamp,
                        'EndTimestamp': chunk_end_timestamp
                    }
                }
            )

            # Read the current chunk of data
            chunk_data = response['Payload'].read()
            clip_data += chunk_data

            # Analyze the chunk for frames and fragments
            fragment_count = chunk_data.count(b'\x00\x00\x00\x01')
            total_frames += fragment_count
            total_fragments += 1
            

            # Check if the chunk is less than 100 MB or if we've reached the end timestamp
            if len(chunk_data) < chunk_size:
                # Upload the current chunk to S3
                s3_bucket_name = '<Your-s3-bucket-name>'
                s3_object_key = f'video-{stream_name}/{stream_name}-{clip_number}-{start_timestamp}-{end_timestamp}.mp4'
                s3_client = session.client('s3')
                s3_client.put_object(Bucket=s3_bucket_name, Key=s3_object_key, Body=chunk_data)

                # Reset clip_data for the next chunk
                clip_data = b''
                clip_number += 1

            # Move to the next chunk
            current_timestamp = chunk_end_timestamp

            # Check if we've reached the end timestamp
            if current_timestamp >= end_timestamp:
                reached_end = True
                break

        except client.exceptions.ResourceNotFoundException:
            # If no fragments are found, sleep for a while and retry
            time.sleep(2)
            continue

    if reached_end:
        print(f"Total frames: {total_frames}")
        print(f"Total fragments: {total_fragments}")
        return f"Video clip parts have been stored in S3. Total frames: {total_frames}, Total fragments: {total_fragments}"
    else:
        return "Video processing completed, but the end timestamp was not reached."
© www.soinside.com 2019 - 2024. All rights reserved.