12

Ich bin dabei, RecordRTC durch den integrierten MediaRecorder für die Aufnahme von Audio in Chrome zu ersetzen. Der aufgenommene Ton wird dann im Programm mit Audio-API abgespielt. Ich habe Probleme, die audio.duration-Eigenschaft zu aktivieren. Er sagtWie kann ich Audiodateien, die von MediaRecorder in Chrome aufgenommen wurden, eine vordefinierte Länge hinzufügen?

Wenn das Video (Audio) gestreamt wird und keine vordefinierte Länge hat, wird "Inf" (Infinity) zurückgegeben.

Mit RecordRTC musste ich ffmpeg_asm.js verwenden, um das Audio von wav zu ogg zu konvertieren. Meine Vermutung ist irgendwo im Prozess RecordRTC setzt die vordefinierte Audio-Länge. Gibt es eine Möglichkeit, die vordefinierte Länge mit MediaRecorder einzustellen?

+1

genau das gleiche Problem, das ich habe. Hast du eine Lösung gefunden? –

+0

Was meinst du mit vordefinierte Länge? Kannst du einfach einen Timer haben, der beim Start der Aufnahme gestartet wird und ihn dann zum richtigen Zeitpunkt stoppt? –

+0

@Tom Chen, wenn ich meine aufgenommenen Audiodateien nach einer Aufnahme überprüfe (mit der Kommandozeile '$ ffmpeg -i test.webm' sehe ich die Definition als N/A. Haben Sie eine Möglichkeit gefunden, die Länge einzustellen? –

Antwort

17

Dies ist ein chrome bug.

FF hat die Dauer der aufgezeichneten Medien aussetzen, und wenn Sie die currentTime der aufgenommenen Medien zu mehr als seine tatsächlichen duration gesetzt haben, dann ist die Eigenschaft ist in Chrom ...

var recorder, 
 
    chunks = [], 
 
    ctx = new AudioContext(), 
 
    aud = document.getElementById('aud'); 
 

 
function exportAudio() { 
 
    var blob = new Blob(chunks, { 
 
    type: 'audio/ogg' 
 
    }); 
 
    aud.src = URL.createObjectURL(new Blob(chunks)); 
 

 
    aud.onloadedmetadata = function() { 
 
    // it should already be available here 
 
    log.textContent = ' duration: ' + aud.duration; 
 
    // handle chrome's bug 
 
    if(aud.duration === Infinity){ 
 
     // set it to bigger than the actual duration 
 
     aud.currentTime = 1e101; 
 
     aud.ontimeupdate = function(){ 
 
     \t this.ontimeupdate =()=>{return;} 
 
\t  log.textContent += ' after workaround: ' + aud.duration; 
 
    \t aud.currentTime = 0; 
 
    \t } 
 
     } 
 
    } 
 
} 
 

 
function getData() { 
 
    var request = new XMLHttpRequest(); 
 
    request.open('GET', 'https://upload.wikimedia.org/wikipedia/commons/4/4b/011229beowulf_grendel.ogg', true); 
 
    request.responseType = 'arraybuffer'; 
 
    request.onload = decodeAudio; 
 
    request.send(); 
 
} 
 

 

 
function decodeAudio(evt) { 
 
    var audioData = this.response; 
 
    ctx.decodeAudioData(audioData, startRecording); 
 
} 
 

 
function startRecording(buffer) { 
 

 
    var source = ctx.createBufferSource(); 
 
    source.buffer = buffer; 
 
    var dest = ctx.createMediaStreamDestination(); 
 
    source.connect(dest); 
 

 
    recorder = new MediaRecorder(dest.stream); 
 
    recorder.ondataavailable = saveChunks; 
 
    recorder.onstop = exportAudio; 
 
    source.start(0); 
 
    recorder.start(); 
 
    log.innerHTML = 'recording...' 
 
    // record only 5 seconds 
 
    setTimeout(function() { 
 
    recorder.stop(); 
 
    }, 5000); 
 
} 
 

 
function saveChunks(evt) { 
 
    if (evt.data.size > 0) { 
 
    chunks.push(evt.data); 
 
    } 
 

 
} 
 

 

 

 
getData();
<audio id="aud" controls></audio><span id="log"></span>

so ist die Beratung hier wäre Stern die bug report so dass Chrom-Team einige Zeit dauert, es zu beheben, auch wenn diese Problemumgehung den Trick tun kann ...

+0

Dort ist ein Fehler: https://crbug.com/642012. Ich schlage vor, wir "Stern" es, so dass die Entwickler entsprechend priorisieren können. – miguelao

+0

@miguelao, yep ich feilte [diese] (https://bugs.chromium.org/ p/chrom/issues/detail? id = 656426) welches mit dem von Ihnen erwähnten verschmolzen wurde – Kaiido

+0

Wow, das hat wirklich funktioniert. –

0

Danke an @Kaiido für die Identifizierung des Fehlers und die Bereitstellung des Working Fixes.

Ich bereitete ein npm-Paket namens get-blob-duration vor, das Sie installieren können, um eine nette Promise-Wrapped-Funktion für die Drecksarbeit zu erhalten.

Verwendung ist wie folgt:

// Returns Promise<Number> 
getBlobDuration(blob).then(function(duration) { 
    console.log(duration + ' seconds'); 
}); 

oder ECMAScript 6:

// yada yada async 
const duration = await getBlobDuration(blob) 
console.log(duration + ' seconds') 
Verwandte Themen