amazon-chime-sdk-js icon indicating copy to clipboard operation
amazon-chime-sdk-js copied to clipboard

Cannot find concatenated result video from chimeSDKMediaPipelines.createMediaConcatenationPipeline

Open jaeho0522 opened this issue 2 years ago • 11 comments

I was able capture chime meeting screen using

  1. 'chimeSDKMediaPipelines.createMediaCapturePipeline' to create pipeline and start recording
  2. 'chimeSDKMediaPipelines.deleteMediaCapturePipeline' to stop recording
  3. 'chimeSDKMediaPipelines.createMediaConcatenationPipeline' to concatenate captured junk files.

When I looked at S3 bucket, I can only find chunked files and not the concatenated file.

I read following references to implement concatenation.

  1. https://docs.aws.amazon.com/chime-sdk/latest/dg/concat-architecture.html
  2. https://docs.aws.amazon.com/chime-sdk/latest/dg/create-concat-pipe-steps.html

I double checked below information to make sure I did not make any mistakes

  1. Capture bucket policy and Concatenation bucket policy
  2. Concatenation bucket arn

And now I don't know what to look for.

I am currently using 'ap-southeast-1' region for the S3 buckets. And I am including source code and information that might help someone to help me solve this problem.

Thanks in advance

Jaeho Lee

  1. Bucket directories
  1. Amazon S3 > Bucket > mk-recording-text (Capture bucket)
  2. Amazon S3 > Bucket > mk-media-concatenation-bucket (Concatenation bucket)

  1. Bucket arn information
  1. Capture bucket arn: arn:aws:s3:::mk-recording-test
  2. Concatenation bucket arn: arn:aws:s3:::mk-media-concatenation-bucket

  1. Lambda handler code const AWS = require('aws-sdk'); const ddb = new AWS.DynamoDB(); const chimeSDKMediaPipelines = new AWS.ChimeSDKMediaPipelines({ region: 'us-east-1' }); const sts = new AWS.STS({ region: 'us-east-1' });

const meetingTable = {}; const { MEETINGS_TABLE_NAME, CAPTURE_S3_DESTINATION, CONCAT_BUCKET_ARN, } = process.env;

exports.handler = async(event) => { if (!CAPTURE_S3_DESTINATION) { console.warn("Cloud media capture not available"); return response(500, 'application/json', JSON.stringify({})); } const query = event.queryStringParameters; let action; if(query && query.action) { console.log("action: " + query.action); action = query.action; }

// 화상 녹화 시작 if (action == 'start'){ const pipelineInfo = await startCapture(query); return response(201, 'application/json', JSON.stringify(pipelineInfo)); } // 화상 녹화 끝내기 else if (action == 'end') { await endCapture(query); return response(200, 'application/json', JSON.stringify({}));
} // 화상 녹화 청크 연결하기 (온전한 영상파일로 변환) else if (action == 'concat') { const pipelineInfo = await concatCapture(query); return response(201, 'application/json', JSON.stringify(pipelineInfo)); } else { return response(404, 'text/html', '404 Not Found'); } };

async function endCapture(query) { const pipelineInfo = meetingTable[query.title]; console.log(JSON.stringify(pipelineInfo)); await chimeSDKMediaPipelines.deleteMediaCapturePipeline({ MediaPipelineId: pipelineInfo.MediaPipelineId }).promise(); // meetingTable[query.title] = undefined; return; }

async function startCapture(query) { let meeting = await getMeeting(query.title); if (!meeting) { return response(404, 'application/json', JSON.stringify({message: 'Meeting not found.'})); }

const callerInfo = await sts.getCallerIdentity().promise(); // @ts-ignore const pipelineInfo = await chimeSDKMediaPipelines.createMediaCapturePipeline({ SourceType: "ChimeSdkMeeting", SourceArn: arn:aws:chime::${callerInfo.Account}:meeting:${meeting.Meeting.MeetingId}, SinkType: "S3Bucket", SinkArn: CAPTURE_S3_DESTINATION, ChimeSdkMeetingConfiguration: { ArtifactsConfiguration: { Audio: { MuxType: "AudioWithCompositedVideo" //"AudioWithActiveSpeakerVideo" }, Video: { State: "Disabled", MuxType: "VideoOnly" }, Content: { State: "Disabled", MuxType: "ContentOnly" }, CompositedVideo: { Layout: "GridView", Resolution: "FHD", GridViewConfiguration: { ContentShareLayout: "PresenterOnly", PresenterOnlyConfiguration: { PresenterPosition: "BottomRight" } } } } } }).promise(); console.log(JSON.stringify(pipelineInfo)); meetingTable[query.title] = pipelineInfo.MediaCapturePipeline; return pipelineInfo; }

async function concatCapture(query) { let meeting = await getMeeting(query.title); if (!meeting) { return response(404, 'application/json', JSON.stringify({message: 'Meeting not found.'})); } // @ts-ignore const pipelineInfo = await chimeSDKMediaPipelines.createMediaConcatenationPipeline({ Sinks: [ { S3BucketSinkConfiguration: { Destination: CONCAT_BUCKET_ARN }, Type: 'S3Bucket', }, ], Sources: [ { MediaCapturePipelineSourceConfiguration: { ChimeSdkMeetingConfiguration: { ArtifactsConfiguration: { Audio: { State: 'Enabled' }, CompositedVideo: { State: 'Enabled' }, Content: { State: 'Disabled' }, DataChannel: { State: 'Enabled' }, MeetingEvents: { State: 'Enabled' }, TranscriptionMessages: { State: 'Enabled' }, Video: { State: 'Disabled' }, }, }, MediaPipelineArn: meetingTable[query.title].MediaPipelineArn, }, Type: 'MediaCapturePipeline', }, ], }).promise(); console.log(JSON.stringify(pipelineInfo)); return pipelineInfo; }

// Retrieves the meeting from the table by the meeting title async function getMeeting(title) { // @ts-ignore const result = await ddb.getItem({
TableName: MEETINGS_TABLE_NAME, Key: { 'Title': { S: title }, }, }).promise(); // @ts-ignore return result.Item ? JSON.parse(result.Item.Data.S) : null; }

function response(statusCode, contentType, body) { return { statusCode: statusCode, headers: { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' }, body: body }; }

  1. Capture bucket policy { "Version": "2012-10-17", "Id": "AWSChimeMediaCaptureBucketPolicy", "Statement": [ { "Sid": "AWSChimeMediaCaptureBucketPolicy", "Effect": "Allow", "Principal": { "Service": "mediapipelines.chime.amazonaws.com" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::mk-recording-test/*", "arn:aws:s3:::mk-recording-test" ] } ] }

  1. Concatenation bucket policy { "Version": "2012-10-17", "Id": "AWSChimeMediaConcatenationBucketPolicy", "Statement": [ { "Sid": " AWSChimeMediaConcatenationBucketPolicy ", "Effect": "Allow", "Principal": { "Service": "mediapipelines.chime.amazonaws.com" }, "Action": [ "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::mk-media-concatenation-bucket/*" } ] }

jaeho0522 avatar Dec 22 '22 10:12 jaeho0522