javascript - Hogyan lehet stream adatot kapni a (web) MediaRecorder-ből méret alapján az idő helyett?
Jelenleg a MediaRecorder-t használom, hogy a felhasználó webkamerájából/mikrofonjából video stream darabokat kapjak így:
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then((stream) => {
var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(5000);
mediaRecorder.ondataavailable = (blobEvent) => {
console.log('got 5 seconds of stream', blobEvent);
}
})
Ez a videó minden 5 másodpercében kibocsát egy darabot a folyamból, azonban én olyan darabokat szeretnék, amelyek meghatározott méretűek, nem pedig hosszúságúak. Úgy tűnik, erre nincs egyértelmű mód, mivel nem tudom ellenőrizni az aktuális darab méretét anélkül, hogy új darabot indítanék, és nem tudom azokat utólag összeilleszteni. Ez a megoldás, amit kitaláltam, két médiare korder használatával:
const MIN_BLOB_SIZE = 5000000;
var partSize = 0;
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then((stream) => {
var mediaRecorder = new MediaRecorder(stream);
var mediaRecorder2 = new MediaRecorder(stream)
mediaRecorder.start();
mediaRecorder2.start(5000)
mediaRecorder2.ondataavailable = (blobEvent) => {
console.log('got 5 seconds of data', blobEvent)
const blob = blobEvent.data
partSize += blob.size;
if (partSize >= MIN_BLOB_SIZE) {
partSize = 0;
mediaRecorder.requestData();
}
}
mediaRecorder.ondataavailable = (blobEvent) => {
console.log('got a chunk at least 5mb', blobEvent);
};
});
de ez hacky-nek érződik, pontatlan darabokat ad, megköveteli, hogy biztosítsam, hogy ez a két felvevő tökéletesen szinkronban legyen, bonyolítja a hibakezelést/szélsőséges eseteket, és aggódom a teljesítményre gyakorolt hatások miatt, ha 2 médiafelvevőt használok. Elfogadnék egy választ, ami egy médiafelvevővel oldja meg ezt, vagy, ha ez egyszerűen nem lehetséges, ha valaki meggyőzne arról, hogy a 2 médiafelvevő teljesítmény szempontjából rendben van, azt is elfogadnám, és kezelem a felmerülő komplikációkat.
Válasz #1
Részek kombinálása
Utólag össze tudod fűzni a darabokat a new Blob(blobArray) segítségével. Ha feltétlenül szükséged van arra, hogy bizonyos méretű blobokkal dolgozz, használhatod a Blob.slice-t. Valahogy így nézhet ki:
const MIN_BLOB_SIZE = 5000000;
var partSize = 0, parts = [];
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then((stream) => {
var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(5000);
mediaRecorder.ondataavailable = (blobEvent) => {
console.log('got 5 seconds of data', blobEvent);
const blob = blobEvent.data;
partSize += blob.size;
parts.push(blob);
if (partSize >= MIN_BLOB_SIZE) {
let bigBlob = new Blob(parts, { type: blob.type });
// if the blob size doesn't need to be precise:
partSize = 0;
parts = [];
// do something with bigBlob
// or if the blob size needs to be precise:
// let sizedBlob = bigBlob.slice(0, MIN_BLOB_SIZE, blob.type);
// parts = [ bigBlob.slice(MIN_BLOB_SIZE, bigBlob.size, blob.type) ];
// partSize = parts[0].size;
// do something with sizedBlob
}
};
mediaRecorder.onstop = (blobEvent) => {
console.log('Recording Stopped');
const blob = blobEvent.data;
partSize += blob.size;
parts.push(blob);
let bigBlob = new Blob(parts, { type: blob.type });
// do something with bigBlob, which may be smaller than MIN_BLOB_SIZE
};
});
A blob méretének hangolása a bitrátával
Érdekelhet még a MediaRecorder API bitsPerSecond (valamint a audioBitsPerSecond és a videoBitsPerSecond) opciója, amely adott rögzített időtartam esetén kiszámíthatóbb blob méreteket biztosíthat. Ez azonban hatással lehet a videó és az audió minőségére.
