web-dev-qa-db-ja.com

Webカメラでキャプチャしたjpg画像/ビデオをHTML5でローカルハードドライブに保存する方法

問題は単純に見えますが、HTMLとJavascriptに関する知識がないため、適切な解決策を見つけることができません。

タスクは、ボタンがWebカメラをアクティブにし、静止画像またはビデオ(推奨)をローカルハードドライブに保存するWebページを設計することです。当面はアップロード/ダウンロードは必要ありません。

何度か試した後、getusermedia()APIを使用してWebカメラをアクティブにし、ブラウザーウィンドウでビデオをレンダリングできますが、保存できません。これは私のコードがどのように見えるかです。

if (navigator.getUserMedia) {       
    navigator.getUserMedia({video: true}, handleVideo, videoError);
}

function handleVideo(stream) {
    video.src = window.URL.createObjectURL(stream);
}

では、同じ方法でキャプチャした静止画像またはビデオをハードドライブに保存する方法についてのアイデアはありますか?

6
Della

まず、 navigator.getUserMedia APIは非推奨になりました。 navigator.mediaDevices.getUserMedia メソッド。

次に、静止画像を取得するために、実際には draw ビデオ要素を使用できるキャンバスを使用できます。

const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
  vid.srcObject = stream; // don't use createObjectURL(MediaStream)
  return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
  const btn = document.querySelector('button');
  btn.disabled = false;
  btn.onclick = e => {
    takeASnap()
    .then(download);
  };
})
.catch(e=>console.log('please use the fiddle instead'));

function takeASnap(){
  const canvas = document.createElement('canvas'); // create a canvas
  const ctx = canvas.getContext('2d'); // get its context
  canvas.width = vid.videoWidth; // set its size to the one of the video
  canvas.height = vid.videoHeight;
  ctx.drawImage(vid, 0,0); // the video
  return new Promise((res, rej)=>{
    canvas.toBlob(res, 'image/jpeg'); // request a Blob from the canvas
  });
}
function download(blob){
  // uses the <a download> to download a Blob
  let a = document.createElement('a'); 
  a.href = URL.createObjectURL(blob);
  a.download = 'screenshot.jpg';
  document.body.appendChild(a);
  a.click();
}
<button>take a snapshot</button>
<video id="vid"></video>

フィドルとして StacksnippetsがgUMリクエストをブロックする可能性があるため...

また、動画として保存するには、[MediaRecorder API]( https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorderà を使用できます。これにより、 MediaStreamをwebmとして保存します。

const vid = document.querySelector('video');
navigator.mediaDevices.getUserMedia({video: true}) // request cam
.then(stream => {
  vid.srcObject = stream; // don't use createObjectURL(MediaStream)
  return vid.play(); // returns a Promise
})
.then(()=>{ // enable the button
  const btn = document.querySelector('button');
  btn.disabled = false;
  btn.onclick = startRecording;
})
.catch(e=>console.log('please use the fiddle instead'));

function startRecording(){
  // switch button's behavior
  const btn = this;
  btn.textContent = 'stop recording';
  btn.onclick = stopRecording;
  
  const chunks = []; // here we will save all video data
  const rec = new MediaRecorder(vid.srcObject);
  // this event contains our data
  rec.ondataavailable = e => chunks.Push(e.data);
  // when done, concatenate our chunks in a single Blob
  rec.onstop = e => download(new Blob(chunks));
  rec.start();
  function stopRecording(){
    rec.stop();
    // switch button's behavior
    btn.textContent = 'start recording';
    btn.onclick = startRecording;
  }
}
function download(blob){
  // uses the <a download> to download a Blob
  let a = document.createElement('a'); 
  a.href = URL.createObjectURL(blob);
  a.download = 'recorded.webm';
  document.body.appendChild(a);
  a.click();
}
<button disabled>start recording</button>
<video></video>

そして フィドル


ノート:

MediaRecorder APIはまだかなり新しいAPIであり、[ブラウザ実装の小さなセット]にはまだいくつかのバグがあります。

13
Kaiido

あなたがしたことは良いスタートです。 ウェブカメラの画像をキャンバスにペイントする そして キャンバス情報から画像を作成する ができます。次に、いくつかのトリックを使用して、ブラウザに画像が表示されないようにし、それを 代わりにダウンロードする にすることができます。

1
Marc Dix