Reputation: 79
I am using the below code, in order to download the clip. I have successfully received the response and I am trying to download the video but I cannot be able.
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);
Upvotes: 1
Views: 940
Reputation: 1
For Anyone who has been stuck on this and want's a simple end to end solution using python. What the code is doing:
Below is the code:
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, 5, 2, 7, 9, 50) #example values you can adjust this according to your stream
end_timestamp = datetime(2023, 5, 2, 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
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
# 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:
return f"Video clip parts have been stored in S3."
else:
return "Video processing completed, but the end timestamp was not reached."
Upvotes: 0
Reputation: 61
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.
});
}
Upvotes: 0
Reputation: 79
I have found the solution by just adding the responseType: "blob"
in the request
const res = await client.post(completeUrl, params, {
headers: {
"Content-Type": "video/mp4",
"X-Amz-Target": "CodeBuild_20161006.StartBuild",
},
responseType: "blob", // added this line
});
Upvotes: 0