Me pregunto si alguien me puede ayudar aquí!
Actualmente estoy guardando un HTML5 Canvas como un archivo MP4 a través de la API de MediaRecorder. Ahora mi lienzo no contiene ningún audio, pero necesito un canal de audio integrado como archivo con solo h.264 y ningún códec de audio no es compatible con una pieza de software que estoy usando.
¿Hay alguna forma de obligar a Safari a hornear un códec de audio en la transmisión aunque no se use audio en el lienzo?
Esencialmente, estoy tratando de lograr lo siguiente: AAC, H.264
En lugar de lo que tengo ahora: H.264
Esto es lo que tengo hasta ahora (menos algunos otros detalles):
// setup media recording const recordedChunks = []; const stream = canvas.captureStream(60); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (e) => recordedChunks.push(e.data); mediaRecorder.onstop = async (e) => { const download = (fileName, url) => { const a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); }; // download video const videoData = new Blob(recordedChunks, { type: "video/mp4" }); download("1.mp4", URL.createObjectURL(videoData)); } // start recording mediaRecorder.start(); // do some canvas related operations // ... mediaRecorder.stop();Supongo que si no hay trabajo aquí, podría recurrir a agregar un canal de audio silencioso al video a través de FFMPEG.
ACTUALIZACIÓN: la respuesta aceptada en realidad no funcionó para mí, así que recurrí a agregar el canal de audio a través de FFMPEG que funcionó. Aceptado de todos modos, ya que agrega un canal de audio al archivo de salida.
¡Gracias!
No estoy familiarizado con los códecs y demás, pero puede agregar un canal de audio silencioso a una transmisión de video de la siguiente manera:
const stream = canvas.captureStream(60); const audioContext = new AudioContext(); const oscillator = audioContext.createOscillator(); oscillator.frequency.value = 0; const streamAudioDestination = audioContext.createMediaStreamDestination(); oscillator.connect(streamAudioDestination); oscillator.start(); // add audio track const audioStream = streamAudioDestination.stream; const audioTracks = audioStream.getAudioTracks(); const firstAudioTrack = audioTracks[0]; stream.addTrack(firstAudioTrack); const mediaRecorder = new MediaRecorder(stream);Tenga en cuenta que la inicialización de AudioContext debe ocurrir en respuesta a una acción del usuario (por ejemplo, dentro de un controlador de clic). ¡Gracias @ Nikola Lukic por notar esto!
Si alguien tiene The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
Aquí hay un ejemplo adaptado que usa el código @ziz Yokubjonov:
function LOAD() { var canvas = document.getElementById('canvas') var ctx = canvas.getContext("2d") // setup media recording const recordedChunks = []; const stream = canvas.captureStream(60); // let combined = new MediaStream([...videoStream.getTracks(), ...audioStream.getTracks()]); let options = { audio: true, audioBitsPerSecond: 64000, }; const audioContext = new AudioContext(); const oscillator = audioContext.createOscillator(); oscillator.frequency.value = 0; const streamAudioDestination = audioContext.createMediaStreamDestination(); oscillator.connect(streamAudioDestination); oscillator.start(); // add audio track const audioStream = streamAudioDestination.stream; const audioTracks = audioStream.getAudioTracks(); const firstAudioTrack = audioTracks[0]; stream.addTrack(firstAudioTrack); mediaRecorder = new MediaRecorder(stream, options); mediaRecorder.ondataavailable = (e) => recordedChunks.push(e.data); mediaRecorder.onstop = async (e) => { const download = (fileName, url) => { const a = document.createElement("a"); document.body.appendChild(a); a.style = "display: block"; a.innerHTML = 'LINK'; a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); }; // download video const videoData = new Blob(recordedChunks, {type: "video/mp4"}); download("1.mp4", URL.createObjectURL(videoData)); } // start recording mediaRecorder.start(); // do some canvas related operations var x = 10 setInterval(function() { x += 20 ctx.fillStyle = 'red' ctx.fillText("TEST TEST", x, 50, 200, 50); }, 1000) ctx.fillText("TEST TEST", 10, 50, 200, 50); setTimeout(function() { mediaRecorder.stop(); }, 10000) } function attachFunction() { LOAD(); window.removeEventListener("click", attachFunction) } window.addEventListener("click", attachFunction) <canvas id='canvas'></canvas> ```a.href``` = url: ````a.download``` = fileName: ```a.click```(.264): (): ```c.AAC``` ```H.264```