Новый поток MediaRecorder (поток [, параметры]) может жить изменить? - PullRequest
0 голосов
/ 15 марта 2020

new MediaRecorder (stream [, options]);

Я хочу записать пользовательскую камеру и аудио

Мне нужно смешать song.mp3 с аудиодорожкой при записи.

и в результате экспортируйте видеофайл для загрузки по ссылке.

Но первый поток параметров MediaRecorder может измениться?

Но когда я использую recoder.stop ()

Ошибка подсказок: не удалось выполнить «останов» на «MediaRecorder»: состояние MediaRecorder «неактивно».

Мой код:

function getFileBuffer(filepath) {
  return fetch(filepath, {method: 'GET'}).then(response => response.arrayBuffer())
}

function mp3play() {
  getFileBuffer('song.mp3')
  .then(buffer => context.decodeAudioData(buffer))
  .then(buffer => {
    console.log(buffer)
    const source = context.createBufferSource()
    source.buffer = buffer
    let volume = context.createGain()
    volume.gain.value = 1
    source.connect(volume)
    dest = context.createMediaStreamDestination()
    volume.connect(dest)
    // volume.connect(context.destination)
    source.start(0)

    const _audioTrack = stream.getAudioTracks();
    if (_audioTrack.length > 0) {
      _audioTrack[0].stop();
      stream.removeTrack(_audioTrack[0]);
    }
    //
    // console.log(dest.stream)
    // console.log(dest.stream.getAudioTracks()[0])
    // stream.addTrack(dest.stream.getAudioTracks()[0])
  })
}

function startRecording() {
  recorder = new MediaRecorder(stream, {
    mimeType: 'video/webm'
  })
  recorder.start()
  stopBtn.removeAttribute('disabled')
  startBtn.disabled = true
}

1 Ответ

0 голосов
/ 26 марта 2020

Нет, мы все еще не можем записать MediaStream, треки которого изменены после начала записи, при этом stop() будет MediaRecorder. Вот очень связанная с этим Q / A , которая больше касалась записи видео.

Что можно сделать, так это создать своего рода слияние MediaStream.
С аудио гораздо проще, более того, поскольку вы уже используете API WebAudio: все, что вам нужно сделать, - это создать другой узел MediaStreamDestination и подключить / отключить различные источники.

const base = "https://upload.wikimedia.org/wikipedia/en/d/";
const urls = [
  "d3/Beach_Boys_-_Good_Vibrations.ogg",
  "dc/Strawberry_Fields_Forever_%28Beatles_song_-_sample%29.ogg"
].map( url => base + url );
const context = new AudioContext();
const button = document.querySelector( 'button' );

button.onclick = async () => {
  button.disabled = true;
  context.resume();
  const audiobuffers = await Promise.all( urls.map( fetchAsAudioBuffer ) );
  button.remove();
  const streamNode = context.createMediaStreamDestination();
  const stream = streamNode.stream;
  
  const recorder = new MediaRecorder( stream );
  const chunks = [];
  recorder.ondataavailable = evt => chunks.push( evt.data );
  recorder.onstop = evt => exportAudio( new Blob( chunks ) );
  document.getElementById( 'record-stopper' ).onclick = evt => {
    recorder.stop();
    current_source.stop( 0 );
  };

  let current_index = 0;
  let current_source = null;
  
  document.getElementById( 'switcher' ).onclick = switchAudioSource;
  
  switchAudioSource();
  recorder.start();

  function switchAudioSource() {
    if( current_source ) {
      current_source.stop( 0 );
    }
    current_index = (current_index + 1) % audiobuffers.length;
    current_source = context.createBufferSource();
    current_source.buffer = audiobuffers[ current_index ];
    current_source.loop = true;
    current_source.connect( streamNode );
    current_source.connect( context.destination );
    current_source.start( 0 );
  }

};

function exportAudio( blob ) {
  const aud = new Audio( URL.createObjectURL( blob ) );
  aud.controls = true;
  document.body.prepend( aud );
}

async function fetchAsAudioBuffer( url ) {
  const buf = await fetchAsBuffer( url );
  return context.decodeAudioData( buf );
}
async function fetchAsBuffer( url ) {
  const resp = await fetch( url );
  return resp.arrayBuffer();
}
button+.recording-controls,
  audio+.recording-controls {
    display: none;
  }
<button>begin</button>
<div class="recording-controls">
  <label>Recording...</label>
  <button id="switcher">Switch Audio Sources</button>
  <button id="record-stopper">Stop Recording</button>
</div>

Для видео, которое подразумевает запись CanvasMediaStreamTrack и рисование различных видеопотоков на источнике <canvas>, но мы обычно теряем много качества при этом ...

...