Skip to content

Instantly share code, notes, and snippets.

@nvolungis
Created March 14, 2018 15:15
Show Gist options
  • Save nvolungis/9d14c45ab78a2f361ee1c333c0d89e70 to your computer and use it in GitHub Desktop.
Save nvolungis/9d14c45ab78a2f361ee1c333c0d89e70 to your computer and use it in GitHub Desktop.
streaming webcam upload
const s3 = new AWS.S3();
const BUCKET = 'multipart-upload-test';
const FILENAME = `test-${Math.random()}.webm`;
const logSize = size => {
console.log(`current size: ${totalSize / (1024*1024)}mb`);
};
const createUpload = () => new Promise((resolve, reject) => {
const options = { Bucket: BUCKET, Key: FILENAME };
const cb = (mpErr, multipart) => {
if (mpErr) { return reject(mpErr) }
resolve(multipart);
};
s3.createMultipartUpload(options, cb);
});
const uploadPart = (blob, partNumber, multipart) => new Promise(resolve => {
s3.uploadPart({
Body: blob,
Bucket: BUCKET,
Key: FILENAME,
PartNumber: String(partNumber),
UploadId: multipart.UploadId
}, (err, data) => {
resolve(data);
});
});
const completeUpload = (multipart, multipartMap) => new Promise(resolve => {
s3.completeMultipartUpload({
Bucket: BUCKET,
Key: FILENAME,
MultipartUpload: multipartMap,
UploadId: multipart.UploadId
}, resolve);
});
const createRecorder = stream => {
const recorder = new MediaRecorder(stream);
const readableStream = new ReadableStream({
start(controller) {
recorder.ondataavailable = ({data}) => controller.enqueue(data);
recorder.onstop = () => controller.close();
},
cancel() {
recorder.stop();
}
});
return {recorder, readableStream}
};
const processStream = async (readableStream, multipart) => {
let partNumber = 1;
let totalSize = 0;
let multipartMap = { Parts: [] };
for await (const data of streamAsyncIterator(readableStream)) {
const {ETag} = await uploadPart(data, partNumber, multipart);
multipartMap.Parts[partNumber-1] = {ETag, PartNumber: partNumber};
totalSize += data.size;
partNumber += 1;
logSize(totalSize);
}
const result = await completeUpload(multipart, multipartMap);
console.log('done', result)
};
const run = async () => {
const {recorder, readableStream} = await getWebcamStream().then(createRecorder);
const multipart = await createUpload();
processStream(readableStream, multipart);
recorder.start(1000);
setTimeout(() => recorder.stop(), 30000);
};
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment