Kullanıcının Videosunu Kaydetme

Mat Ölçekler

Birçok tarayıcı artık kullanıcıdan video ve ses girişine erişebilmektedir. Ancak, tarayıcıya bağlı olarak tam dinamik ve satır içi bir deneyim olabilir veya kullanıcının cihazındaki başka bir uygulamaya devredilebilir.

Basit ve kademeli şekilde başlayın

Yapılacak en kolay şey kullanıcıdan önceden kaydedilmiş bir dosya istemektir. Bunu, basit bir dosya giriş öğesi oluşturup yalnızca video dosyalarını kabul edebileceğimizi belirten accept filtresi ve bunları doğrudan kameradan almak istediğimizi belirten capture özelliği ekleyerek yapın.

<input type="file" accept="video/*" capture />

Bu yöntem tüm platformlarda çalışır. Masaüstünde, kullanıcıdan dosya sisteminden dosya yüklemesi istenir (capture özelliği yok sayılır). iOS'ta Safari'de kamera uygulaması açılır ve böylece video kaydedip daha sonra web sayfasına gönderebilirsiniz. Android'de ise kullanıcıya videoyu web sayfasına geri göndermeden önce videoyu hangi uygulamada kaydedeceği konusunda seçenek sunulur.

Birçok mobil cihazın birden fazla kamerası vardır. Tercihiniz varsa capture özelliğini, kullanıcıya bakan kamera için user, kameranın dışarıya bakmasını istiyorsanız environment olarak ayarlayabilirsiniz.

<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />

Bunun yalnızca bir ipucu olduğunu unutmayın. Tarayıcı bu seçeneği desteklemiyorsa veya istediğiniz kamera türü kullanılamıyorsa tarayıcı başka bir kamera seçebilir.

Kullanıcı kaydı bitirdikten sonra ve tekrar web sitesine girdiğinde, bir şekilde dosya verilerine erişim sağlamanız gerekir. Giriş öğesine bir onchange etkinliği ekleyip ardından etkinlik nesnesinin files özelliğini okuyarak hızlı erişim elde edebilirsiniz.

<input type="file" accept="video/*" capture="camera" id="recorder" />
<video id="player" controls></video>
<script>
  var recorder = document.getElementById('recorder');
  var player = document.getElementById('player');

  recorder.addEventListener('change', function (e) {
    var file = e.target.files[0];
    // Do something with the video file.
    player.src = URL.createObjectURL(file);
  });
</script>

Dosyaya erişim elde ettikten sonra, onunla istediğiniz her şeyi yapabilirsiniz. Örneğin, şunları yapabilirsiniz:

  • Öğeyi oynatabilmek için doğrudan bir <video> öğesine ekleyin
  • Kullanıcının cihazına indirin
  • XMLHttpRequest öğesine ekleyerek sunucuya yükleyin
  • Çerçeveleri tuvale çizin ve tuvale filtre uygulayın

Video verilerine erişim sağlayan giriş öğesi yöntemi her yerde bulunsa da en az çekici olan seçenektir. Gerçekten kameraya erişip doğrudan sayfada güzel bir deneyim sağlamak istiyoruz.

Kameraya etkileşimli olarak erişin

Modern tarayıcılarda doğrudan kamera hattı bulunabilir. Böylece, web sayfasıyla tamamen entegre olan deneyimler oluşturabiliriz ve kullanıcı, tarayıcıdan hiçbir zaman ayrılmaz.

Kameraya erişim sağlama

WebRTC spesifikasyonundaki getUserMedia() adlı API'yi kullanarak kameraya doğrudan erişebiliriz. getUserMedia(), kullanıcıdan bağlı mikrofonlarına ve kameralarına erişim izni ister.

Başarılı olursa API, kameradan veya mikrofondan gelen verileri içeren bir Stream döndürecektir. Ardından bu veriyi <video> öğesine ekleyebilir, WebRTC akışına ekleyebilir veya MediaRecorder API'yi kullanarak kaydedebiliriz.

Kameradan veri almak için getUserMedia() API'ye aktarılan kısıtlama nesnesinde video: true ayarını yaptık

<video id="player" controls></video>
<script>
  var player = document.getElementById('player');

  var handleSuccess = function (stream) {
    player.srcObject = stream;
  };

  navigator.mediaDevices
    .getUserMedia({audio: true, video: true})
    .then(handleSuccess);
</script>

Belirli bir fotoğraf makinesi seçmek istiyorsanız, öncelikle mevcut kameraları sıralayabilirsiniz.

navigator.mediaDevices.enumerateDevices().then((devices) => {
  devices = devices.filter((d) => d.kind === 'videoinput');
});

Ardından, getUserMedia numaralı telefonu aradığınızda kullanmak istediğiniz deviceId bilgisini iletebilirsiniz.

navigator.mediaDevices.getUserMedia({
  audio: true,
  video: {
    deviceId: devices[0].deviceId,
  },
});

Bu yöntem tek başına çok da kullanışlı değildir. Yapabileceğimiz tek şey video verilerini alıp oynatmaktır.

Ham verilere kameradan erişin

Kameradan ham video verilerine erişmek için her bir kareyi bir <canvas> şekline çizebilir ve pikselleri doğrudan manipüle edebilirsiniz.

2D kanvas için, bir <video> öğesinin geçerli karesini zemine çizmek için bağlamın drawImage yöntemini kullanabilirsiniz.

context.drawImage(myVideoElement, 0, 0);

WebGL tuvaliyle, bir doku için kaynak olarak <video> öğesi kullanabilirsiniz.

gl.texImage2D(
  gl.TEXTURE_2D,
  0,
  gl.RGBA,
  gl.RGBA,
  gl.UNSIGNED_BYTE,
  myVideoElement,
);

Her iki durumda da, bunun oynatılan videonun geçerli karesini kullanacağını unutmayın. Birden fazla kareyi işlemek için her defasında videoyu tuvale yeniden çizmeniz gerekir.

Resimlere ve videolara gerçek zamanlı efektler uygulama konulu makalemizde bu konuyla ilgili daha fazla bilgi edinebilirsiniz.

Kameradaki verileri kaydedin

Kameradaki verileri kaydetmenin en kolay yolu MediaRecorder API'sini kullanmaktır.

MediaRecorder API, getUserMedia tarafından oluşturulan akışı alır ve ardından verileri kademeli olarak tercih ettiğiniz hedefe kaydeder.

<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
  let shouldStop = false;
  let stopped = false;
  const downloadLink = document.getElementById('download');
  const stopButton = document.getElementById('stop');

  stopButton.addEventListener('click', function() {
    shouldStop = true;
  })

  var handleSuccess = function(stream) {
    const options = {mimeType: 'video/webm'};
    const recordedChunks = [];
    const mediaRecorder = new MediaRecorder(stream, options);

    mediaRecorder.addEventListener('dataavailable', function(e) {
      if (e.data.size > 0) {
        recordedChunks.push(e.data);
      }

      if(shouldStop === true && stopped === false) {
        mediaRecorder.stop();
        stopped = true;
      }
    });

    mediaRecorder.addEventListener('stop', function() {
      downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
      downloadLink.download = 'acetest.webm';
    });

    mediaRecorder.start();
  };

  navigator.mediaDevices.getUserMedia({ audio: true, video: true })
      .then(handleSuccess);
</script>

Örneğimizde, verileri doğrudan bir diziye kaydediyoruz. Bu diziyi daha sonra web sunucumuza veya doğrudan kullanıcının cihazındaki depolama alanına kaydetmek için kullanılabilecek bir Blob'ye dönüştürüyoruz.

Kamerayı sorumlu bir şekilde kullanmak için izin isteyin

Kullanıcı daha önce sitenizin kameraya erişmesine izin vermemişse, getUserMedia çağrısı yaptığınızda tarayıcı kullanıcıdan sitenize kamera izni vermesini ister.

Kullanıcılar makinelerindeki güçlü cihazlara erişmek için istem almaktan nefret ederler ve isteği sık sık engellerler veya istemin oluşturulduğu bağlamı anlamadıklarında göz ardı ederler. Yalnızca ilk gerektiğinde kameraya erişim izni istemek en iyi uygulamadır. Kullanıcı erişim verdikten sonra kullanıcıya tekrar sorulmaz ancak kullanıcı erişimi reddederse kullanıcıdan izin istemek için tekrar erişim elde edemezsiniz.

Erişiminiz olup olmadığını kontrol etmek için izinler API'sini kullanın

getUserMedia API, kameraya erişiminiz olup olmadığı hakkında size bilgi vermez. Bu durum sizin için bir sorun teşkil eder. Kullanıcının size kameraya erişim izni vermesini sağlayacak güzel bir kullanıcı arayüzü sunmak için kameraya erişim izni istemeniz gerekir.

Bu sorun, bazı tarayıcılarda Permission API kullanılarak çözülebilir. navigator.permission API, tekrar sormadan belirli API'lere erişim durumunu sorgulamanıza olanak tanır.

Kullanıcının kamerasına erişiminiz olup olmadığını sorgulamak için sorgu yöntemine {name: 'camera'} geçirebilirsiniz. Bu durumda yöntem şunlardan birini döndürür:

  • granted — kullanıcı daha önce size kameraya erişim izni verdi;
  • prompt — kullanıcı size erişim izni vermedi ve getUserMedia numaralı telefonu aradığınızda bundan sonra sorulacak;
  • denied — Sistem veya kullanıcı, kameraya erişimi açıkça engellediği için kameraya erişemezsiniz.

Ayrıca, kullanıcının yapması gereken işlemleri karşılamak için kullanıcı arayüzünüzü değiştirmeniz gerekip gerekmediğini hızlı bir şekilde kontrol edebilirsiniz.

navigator.permissions.query({name: 'camera'}).then(function (result) {
  if (result.state == 'granted') {
  } else if (result.state == 'prompt') {
  } else if (result.state == 'denied') {
  }
  result.onchange = function () {};
});

Geri bildirim