Запись (и остановка) уже запущенной веб-камеры / медиапотока

#javascript #webrtc #webcam #getusermedia

#javascript #webrtc #Вебкам #getusermedia

Вопрос:

Я создал минимальный тестовый сайт WebRTC, который может запрашивать веб-камеру пользователя / аудиопоток, записывать его и воспроизводить запись после ее остановки.

Демонстрация:https://output.jsbin.com/tabosipefo /

Редактировать1: https://jsbin.com/tabosipefo/edit?html ,консоль, вывод

Поскольку все это происходит в рамках одного обещания navigator.mediaDevices.getUserMedia() , мне было интересно, действительно ли возможно обнаружить и продолжить поток и (а) записать его, и (б) остановить и сохранить его.

1 WebRTC по какой-то причине не работает в jsbin в режиме редактирования…

Комментарии:

1. Поместить stream в глобальную переменную?

2. Да, я это сделал… Я думаю, что это мое единственное решение без какой-либо платформы / библиотеки JS

3. Я не совсем понимаю проблему из вашего вопроса. Что вы подразумеваете под «уже запущенным» потоком? Поток, который вы создали ранее в том же документе? Можете ли вы привести пример?

Ответ №1:

Если вы не используете фреймворк и хотите использовать vanilla JS, лучше всего прикрепить объект stream к глобальному окну.

Поток предварительного просмотра

 const showWebcamStream = () => {
  navigator.mediaDevices
    .getUserMedia({ audio: true, video: true })
    .then(stream => {
      window.localStream = stream; // ⭠ tack it to the window object

      // grab the <video> object
      const video = document.querySelector("#video-preview");
      video.srcObject = stream;

      // Display stream
      video.onloadedmetadata = () => video.play();
    })
    .catch(err => console.log(err.name, err.message));
};
  

Теперь видео будет отображаться внутри video элемента (id: #videp-preview ).

Остановить поток (ы)

 const hideWebcamStream = () => localStream.getTracks().forEach(track => track.stop());
  

Вы должны поместить MediaRecorder в объект window, чтобы остановить его позже.

Поток записи

 const startWebcamRecorder = () => {
  // check if localStream is in window and if it is active
  if ("localStream" in window amp;amp; localStream.active) {
    // save the mediaRecorder also to Window in order independently stop it
    window.mediaRecorder = new MediaRecorder(localStream);
    window.dataChunks = [];
    mediaRecorder.start();
    console.log(mediaRecorder.state);
    mediaRecorder.ondataavailable = e => dataChunks.push(e.data);
  }
};
  

Остановите запись и просмотрите запись

Вам нужен другой видеоэлемент для воспроизведения вашей записи #video-playback

 const stopWebcamRecorder = () => {
  if ("mediaRecorder" in window amp;amp; mediaRecorder.state === "recording") {
    mediaRecorder.stop();
    console.log(mediaRecorder.state);
    mediaRecorder.onstop = () => {
      let blob = new Blob(dataChunks, { type: "video/mp4;" });
      dataChunks = [];
      let videoURL = window.URL.createObjectURL(blob);
      const videoPlayback = document.getElementById("video-playback");
      videoPlayback.src = videoURL;
    };
  }
};