我使用下面的代码来下载该剪辑。我已成功收到回复,我正在尝试下载视频,但无法下载。
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);
我通过在请求中添加
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
});
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.
});
}
对于那些一直坚持这个问题并想要一个使用 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."