<div class="container">
  <video width="500" playsinline autoplay></video>
  <div class="btn-group">
    <button id="record" class="success">record</button>
    <button id="stop" class="danger">stop</button>
  </div>
</div>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 30px;
}
video {
  transform: scaleX(-1);
  margin: 0 5px;
  background-color: rgb(200, 200, 200);
}
.btn-group {
  padding-top: 30px;
}
button {
  padding: 5px 20px;
  font-size: 18px;
  margin: 0 5px;
  color: white;
  width: 100px;
  border-radius: 7px;
}
.success {
  border: 2.5px solid #548235;
  background-color: #70AD47;
}
.danger {
  border: 2.5px solid #C00000;
  background-color: rgba(192, 0, 0, 0.6);
}
const video = document.querySelector('video');
const recordBtn = document.querySelector('#record');
const stopBtn = document.querySelector('#stop');
const recordedChunks = [];
let recorder = {};

const startRecord = async () => {
  const stream = await createStream();
  video.srcObject = stream;
  const options = {
    audioBitsPerSecond: 128000,
    videoBitsPerSecond: 2500000,
    mimeType: 'video/webm'
  };
  // 建立 MediaRecorder 物件
  recorder = new MediaRecorder(stream, options);
  // 開始錄製
  recorder.start(1000);
  // 監聽收到影音內容
  recorder.ondataavailable = (event) => {
    if (event.data.size > 0) {
      recordedChunks.push(event.data);
    }
  };
  // 監聽錄影停止
  recorder.onstop = () => {
    download();
  };
};

// 影音下載
const download = () => {
  const blob = new Blob(recordedChunks, { type: 'video/webm' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  document.body.appendChild(a);
  a.style = 'display: none';
  a.href = url;
  a.download = 'test.webm';
  a.click();
  window.URL.revokeObjectURL(url);
};

// 建立媒體串流
const createStream = async () => {
  const constraints = { audio: true, video: true };
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
  return stream;
};

// 停止錄影
const stopRecord = async () => {
  const videoStreams = video.srcObject.getTracks();
  videoStreams.forEach(stream => {
    stream.stop(); // 停止所有 media stream
  });
  video.srcObject = null; // 釋放資源
  recorder.stop();
};

recordBtn.addEventListener('click', startRecord);
stopBtn.addEventListener('click', stopRecord);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.