I'm using recordRTC react package to record the screen and then every 1 minute, I'm trying to upload the blob returned by recordRTC to S3 using multi-part uploads. I'm using AWS SDK v3. I'm able to execute createMultipartUpload and get the UploadId, abort multi-part command using AbortMultipartUploadCommand, but when I execute UploadPartCommand, it throws the following error:
default-error-handler.js:5 Uncaught (in promise) SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
at throwDefaultError (http://localhost:3000/static/js/bundle.js:30691:20)
at http://localhost:3000/static/js/bundle.js:30704:5
at de_UploadPartCommandError (http://localhost:3000/static/js/bundle.js:19856:10)
at async http://localhost:3000/static/js/bundle.js:28426:20
at async http://localhost:3000/static/js/bundle.js:24100:18
at async http://localhost:3000/static/js/bundle.js:28311:13
at async http://localhost:3000/static/js/bundle.js:38590:18
at async http://localhost:3000/static/js/bundle.js:40650:20
at async http://localhost:3000/static/js/bundle.js:40688:14
at async http://localhost:3000/static/js/bundle.js:23830:22
I've tried everything, but non of the solutions available are working.
This is the relevant piece of code for reference:
export const getS3Client = () => {
return new S3Client({
region: process.env.REACT_APP_AWS_REGION,
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient({ region: ML_SERVICES_REGION }),
identityPoolId: IDENTITY_POOL_ID,
}),
sslEnabled: false,
signatureVersion: 'v4',
logger: {
info: console.info,
warn: console.warn,
error: console.error,
}
});
};
const [isScreenRecording, setIsScreenRecording] = useState(false);
const [uploadInProgress, setUploadInProgress] = useState(false);
const chunks = useRef([]);
const S3Client = useRef(null);
const multipartUploadId = useRef(null);
const nextPartNumber = useRef(1);
const recorderRef = useRef(null);
const streamRef = useRef(null);
const uploadToS3 = async () => {
if (chunks.current.length === 0) {
setUploadInProgress(false);
return;
}
setUploadInProgress(true);
const chunk = chunks.current[0];
console.log(chunk);
if (!multipartUploadId.current) {
S3Client.current = getS3Client();
const { UploadId } = await S3Client.current.send(
new CreateMultipartUploadCommand({
Bucket: S3_BUCKET,
Key: 'screen-recording/recording.webm',
ContentType: "video/webm;codecs=vp8",
})
);
multipartUploadId.current = UploadId;
console.log("UploadId: ", UploadId)
}
const command = new UploadPartCommand({
Bucket: S3_BUCKET,
Key: 'screen-recording/recording.webm',
PartNumber: String(chunk.partNumber),
Body: chunk.blob,
UploadId: multipartUploadId.current
});
const response = await S3Client.current.send(command);
console.log(response);
chunks.current.shift();
uploadToS3();
};
const startScreenRecording = async () => {
const hasScreenAccess = await getScreenAccess();
if (!hasScreenAccess) {
console.log("Couldn't get access to the screen.");
cleanup();
return;
}
recorderRef.current = RecordRTC(streamRef.current, {
type: 'video',
timeSlice: 60 * 1000, // 1 minute in milliseconds
ondataavailable: (blob) => {
chunks.current.push({
blob,
partNumber: nextPartNumber.current,
});
console.log(nextPartNumber.current);
nextPartNumber.current += 1;
if (chunks.current.length === 1) {
uploadToS3();
}
},
});
setIsScreenRecording(true);
recorderRef.current.startRecording();
};
Note: I'm also using AWS Transcribe and Polly somewhere else in the codebase and they're running in a different region, so I've two regions. I've also tried this without Cognito, by replacing credentials with this, but still same issue:
credentials: {
accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
},
I'm completely blocked now. Any help is much appreciated. Thanks in advance.