12

मैं क्रोम में ऑडियो रिकॉर्ड करने के लिए MediaRecorder में निर्मित के साथ रिकॉर्डआरटीसी को बदलने की प्रक्रिया में हूं। रिकॉर्ड ऑडियो को तब ऑडियो एपीआई के साथ प्रोग्राम में खेला जाता है। मुझे ऑडियो.duration प्रॉपर्टी को काम करने में परेशानी हो रही है। यह कहता हैक्रोम में MediaRecorder से रिकॉर्ड किए गए ऑडियो में पूर्वनिर्धारित लंबाई कैसे जोड़ सकता हूं?

यदि वीडियो (ऑडियो) स्ट्रीम किया गया है और इसकी पूर्वनिर्धारित लंबाई नहीं है, तो "इन्फिन" (इन्फिनिटी) वापस आती है।

रिकॉर्डआरटीसी के साथ, मुझे favpeg_asm.js का उपयोग ऑडियो को wav से ogg में बदलने के लिए करना था। मेरा अनुमान प्रक्रिया में कहीं कहीं है रिकॉर्डआरटीसी पूर्वनिर्धारित ऑडियो लंबाई सेट करता है। MediaRecorder का उपयोग कर पूर्वनिर्धारित लंबाई निर्धारित करने का कोई तरीका है?

+1

मैं ठीक उसी समस्या आ रही है। क्या आपको एक समाधान मिला? –

+0

आपका पूर्व निर्धारित लंबाई क्या है? क्या आपके पास सिर्फ एक टाइमर हो सकता है जो रिकॉर्डिंग शुरू होने पर शुरू होता है और फिर इसे एप्रोपिएट समय पर रोक दिया जाता है? –

+0

@ टॉम चेन जब मैं रिकॉर्डिंग के बाद अपनी रिकॉर्ड की गई ऑडियो फ़ाइलों का निरीक्षण करता हूं (कमांड लाइन '$ ffmpeg -i test.webm' का उपयोग करके मुझे लगता है कि परिभाषा एन/ए के रूप में सेट की गई है। क्या आपको लंबाई निर्धारित करने का कोई तरीका मिला? –

उत्तर

17

यह chrome bug है।

एफएफ दर्ज की गई मीडिया की अवधि का पर्दाफाश करता है, और यदि आप अपने वास्तविक duration की तुलना में अधिक के लिए दर्ज मीडिया के currentTime सेट है, तो संपत्ति क्रोम में उपलब्ध है ...

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>

तो सलाह यहाँ bug report ताकि क्रोमियम की टीम कुछ समय लगता है इसे ठीक करने के अभिनय करने के लिए हो सकता है, इस समाधान का चाल कर सकते हैं, भले ही ...

+0

एक बग है: https://crbug.com/642012। मेरा सुझाव है कि हम इसे "स्टार" करें ताकि डेवलपर तदनुसार प्राथमिकता दे सकें। – miguelao

+0

@ मिगुएलओ, हाँ मैंने दायर किया [यह एक] (https://bugs.chromium.org/ पी/क्रोमियम/मुद्दों/विवरण? आईडी = 656426) जिसे आपने उल्लेख किया है उसमें विलय कर दिया गया है। – Kaiido

+0

वाह, यह वास्तव में काम करता है। सुंदर। –

0

बग की पहचान करने और कामकाजी फिक्स की पेशकश के लिए @ काइडो को धन्यवाद।

मैंने get-blob-duration नामक एक एनपीएम पैकेज तैयार किया है जिसे आप गंदे काम करने के लिए एक अच्छा वादा-लपेटा हुआ फ़ंक्शन प्राप्त करने के लिए इंस्टॉल कर सकते हैं।

प्रयोग इस प्रकार है:

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

या ECMAScript 6:

// yada yada async 
const duration = await getBlobDuration(blob) 
console.log(duration + ' seconds') 
संबंधित मुद्दे