Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

217
Visualizações
How can I add silent audio channel/AAC codec to an MP4 file for Safari?

Wondering if anyone can help me out here!

I'm currently saving a HTML5 Canvas as an MP4 file via the MediaRecorder API. Now my canvas doesn't contain any audio but I need an audio channel built in as the file with just h.264 and no audio codec isn't compatible with a piece of software I am using.

Is there anyway to force Safari to bake in an audio codec into the stream even though there is no audio being used in the canvas?

Essentially I'm trying to achieve the following: AAC, H.264

Rather than what I have right now: H.264

Here is what I have so far (minus some other details):

  // 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();

I guess if there's no work around here I might just resort to adding a silent audio channel to the video via FFMPEG.

UPDATE: The accepted answer didn't actually work for me so I resorted to adding the audio channel through FFMPEG which worked. Accepted anyway as it does add an audio channel to the outputted file.

Thank you!

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

I'm not familiar with codecs and such but you can add a silent audio channel to a video stream as follows:

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);

Note that initialization of AudioContext should happen in response to a user action (e.g. within a click handler). Thank you @Nikola Lukic for noticing this!

about 4 years ago · Juan Pablo Isaza Relatório

0

If anybody have The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

Here is adapted example used @ziz Yokubjonov code:

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>

about 4 years ago · Juan Pablo Isaza Relatório

0

Thanks, maybe this will help?

    ```a.href``` = 
    url:

    ````a.download``` = 
    fileName:

    ```a.click```(.264):
    ():
    ```c.AAC```

    ```H.264```
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda