HTML5 ile ses ve video yakalama

Giriş

Ses/Görüntü yakalama "Kutsal Kase" oldu uzun süre boyunca devam etti. Uzun yıllar boyunca tarayıcı eklentilerine (Flash veya Silverlight) teşvik etmek sizin görevinizdir. Haydi!

HTML5 yardıma hazır. Bu çok fark etmese de HTML5'in yükselişi cihaz donanımına erişimde ani artış. Coğrafi konum (GPS), Orientation API (ivme ölçer), WebGL (GPU), ve Web Audio API (ses donanımı) mükemmel örneklerdir. Bu özellikler son derece güçlüdür. Bu da, kullanıcılar açısından faydalı olabilecek üst düzey JavaScript API'lerini ortaya çıkarıyor. üzerine düşünmesi gerekir.

Bu eğiticide, API'yi kullanmanıza olanak tanıyan yeni bir API olan GetUserMedia Kullanıcının kamerasına ve mikrofonuna erişmek için web uygulamaları.

getUserMedia() yolu

API'nin geçmişinden haberdar değilseniz getUserMedia() API'ye geliş şeklimiz ilginç bir öykü.

"Medya Yakalama API'leri"nin çeşitli varyantları son birkaç yılda gelişti. Çoğu kişi web'deki yerel cihazlara erişme ihtiyacının farkındaydı, ancak yeni bir spesifikasyon hazırlamasını sağladı. İşlem tamamlandı o kadar karmaşık ki W3C nihayet bir çalışma grubu oluşturmaya karar verdi. Tek amacı nedir? Bu çılgınlığı anlayın! Cihaz API'leri Politikası (DAP) Çalışma Grubu , çok sayıda teklifi birleştirmek + standart hale getirmekle görevlendirildi.

2011'de olanları özetlemeye çalışacağım...

1. Tur: HTML Medya Yakalama

HTML Medya Yakalama, DAP'nin düzenlediği ilk standart bir hale getirmemize yardımcı olacak. Cihaz, <input type="file"> API'sinin aşırı yüklü olduğu accept parametresi için yeni değerler eklemeniz gerekir.

Kullanıcıların web kamerasıyla kendilerinin enstantanelerini çekmelerini istiyorsanız Bunu capture=camera ile yapabilirsiniz:

<input type="file" accept="image/*;capture=camera">

Video veya ses kaydı aşağıdaki gibidir:

<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">

Güzel değil mi? Özellikle de bir dosya girişini yeniden kullanması hoşuma gidiyor. Semantik olarak, çok mantıklı. Söz konusu "API"nin gerçek zamanlı efektler oluşturabilme, (örneğin, canlı web kamerası verilerini bir <canvas> ile oluşturma ve WebGL filtreleri uygulama). HTML Media Capture, yalnızca bir medya dosyasını kaydetmenize veya anlık görüntü almanıza izin verir.

Destek:

  • Android 3.0 tarayıcı - ilk uygulamalardan biridir. Bu özelliğin nasıl uygulandığını görmek için bu videoya göz atın.
  • Android için Chrome (0.16)
  • Firefox Mobil 10.0
  • iOS6 Safari ve Chrome (kısmi destek)

2. Tur: cihaz öğesi

Birçok kişi HTML Media Capture'ın çok sınırlayıcı olduğunu düşünüyordu, bu yüzden (gelecekteki) her tür cihazı desteklediğini ortaya koyduk. Beklendiği üzere, bu tasarımın <device> öğesi için Bu, getUserMedia()'in öncüsü oldu.

Opera, ilk uygulamaları geliştiren ilk tarayıcılardan biridir <device> öğesine göre video yakalamanın özellikleri. Kısa süre sonra (tam olarak belirtmek gerekirse aynı gün), WhatWG, <device> etiketini başka bir takipçinin lehine kopyalamaya karar verdi. Bu sefer bir JavaScript API'si navigator.getUserMedia(). Bir hafta sonra Opera, 800'den bu yana Güncellenmiş getUserMedia() spesifikasyonu için destek. Aynı yıl içinde, Microsoft, IE9 için Laboratuvar yayınlayarak partiye katıldı. destekleyici araçlar da mevcut.

<device> şu şekilde görünecekti:

<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
  function update(stream) {
    document.querySelector('video').src = stream.url;
  }
</script>

Destek:

Maalesef, yayınlanan hiçbir tarayıcıda <device> bulunamadı. Artık endişelenmenize gerek yok :) <device> ile birlikte çalışmaya devam eden iki harika şey oldu sanırım 1.) anlamsaldı ve 2.) destekleyerek kolayca genişletilebiliyordu. ses ve görüntü cihazlarından çok daha fazlası.

Derin bir nefes alın. Bu şeyler çok hızlı hareket ediyor!

3. Tur: WebRTC

<device> öğesi sonunda Dodo'nun yerini aldı.

Uygun bir yakalama API'si bulma hızı, daha büyük olan WebRTC (Web Gerçek Zamanlı İletişim) çalışması sayesinde hızlandı. Bu spesifikasyon, W3C WebRTC Çalışma Grubu tarafından denetlenir. Google, Opera, Mozilla ve diğer birkaçının uygulamaları vardır.

getUserMedia(), WebRTC ile ilişkilidir çünkü söz konusu API kümesine erişim sağlar. Kullanıcının yerel kamera/mikrofon akışına erişim olanağı sağlar.

Destek:

getUserMedia(); Chrome 21, Opera 18 ve Firefox 17'den beri destekleniyor.

Başlarken

navigator.mediaDevices.getUserMedia() sayesinde artık eklenti olmadan web kamerası ve mikrofon girişine erişebiliyoruz. Kamera erişimi artık bir çağrı kadar uzağınızda, yüklemeniz yeterli değil. Doğrudan tarayıcının içine eklenir. Heyecanlı mısınız?

Özellik algılama

Özellik algılama, navigator.mediaDevices.getUserMedia varlığına ilişkin basit bir kontroldür:

if (navigator.mediaDevices?.getUserMedia) {
  // Good to go!
} else {
  alert("navigator.mediaDevices.getUserMedia() is not supported");
}

Bir giriş cihazına erişim kazanma

Web kamerasını veya mikrofonu kullanmak için izin istememiz gerekir. navigator.mediaDevices.getUserMedia() öğesinin ilk parametresi, ayrıntıları belirten bir nesnedir ve gereksinimleri bulunuyor. Örneğin, web kamerasına erişmek istiyorsanız ilk parametre {video: true} olmalıdır. Hem mikrofonu hem de kamerayı kullanmak için {video: true, audio: true} kartı:

<video autoplay></video>

<script>
  navigator.mediaDevices
    .getUserMedia({ video: true, audio: true })
    .then((localMediaStream) => {
      const video = document.querySelector("video");
      video.srcObject = localMediaStream;
    })
    .catch((error) => {
      console.log("Rejected!", error);
    });
</script>

Tamam. Burada ne oluyor? Medya yakalama, yeni HTML5 API'lerine mükemmel bir örnektir pek çok yolu vardır. Diğer HTML5 arkadaşlarımız olan <audio> ve <video> ile birlikte çalışır. Bir src özelliği ayarlamadığımıza veya <source> öğeleri eklemediğimize dikkat edin öğesini (<video>) ekler. Videoyu, bir medya dosyasına URL'si ile yayınlamak yerine, Web kamerasını temsil eden LocalMediaStream nesnesine srcObject.

Ayrıca <video> cihazına autoplay talimatını veriyorum. Aksi takdirde kareyi takip edin. controls ekleme işlemi de beklediğiniz gibi çalışıyor.

Medya kısıtlamaları ayarlama (çözünürlük, yükseklik, genişlik)

getUserMedia() işlevinin ilk parametresi, döndürülen medya akışıyla ilgili daha fazla gereksinim (veya kısıtlama) belirtmek için de kullanılabilir. Örneğin, yalnızca videoya temel erişim izni istediğinizi (ör.{video: true}) belirtmek yerine akışı zorunlu kılmayı da tercih edebilirsiniz. HD olarak:

const hdConstraints = {
  video: { width: { exact:  1280} , height: { exact: 720 } },
};

const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);
const vgaConstraints = {
  video: { width: { exact:  640} , height: { exact: 360 } },
};

const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);

Diğer yapılandırmalar için restrictedts API'sini inceleyin.

Medya kaynağı seçme

MediaDevices arayüzünün enumerateDevices() yöntemi; mikrofonlar, kameralar, mikrofonlu kulaklıklar gibi kullanılabilir medya giriş ve çıkış cihazlarının bir listesini ister. Döndürülen Promise, cihazları tanımlayan bir MediaDeviceInfo nesne dizisiyle çözümlenir.

Bu örnekte, bulunan son mikrofon ve kamera medya akışı kaynağı:

if (!navigator.mediaDevices?.enumerateDevices) {
  console.log("enumerateDevices() not supported.");
} else {
  // List cameras and microphones.
  navigator.mediaDevices
    .enumerateDevices()
    .then((devices) => {
      let audioSource = null;
      let videoSource = null;

      devices.forEach((device) => {
        if (device.kind === "audioinput") {
          audioSource = device.deviceId;
        } else if (device.kind === "videoinput") {
          videoSource = device.deviceId;
        }
      });
      sourceSelected(audioSource, videoSource);
    })
    .catch((err) => {
      console.error(`${err.name}: ${err.message}`);
    });
}

async function sourceSelected(audioSource, videoSource) {
  const constraints = {
    audio: { deviceId: audioSource },
    video: { deviceId: videoSource },
  };
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
}

Sam Dutton'ın oyunun nasıl işlediğiyle ilgili harika demoya göz atın kullanıcıların medya kaynağını seçmesine olanak tanımak için.

Güvenlik

Tarayıcılar navigator.mediaDevices.getUserMedia() çağrısı yapıldığında bir izin iletişim kutusu gösteriyor Bu sayede kullanıcılar kameralarına/mikrofonlarına erişim izni verebilir veya erişimi reddedebilir. Örneğin, burada Chrome'un izin iletişim kutusu:

Chrome&#39;daki izin iletişim kutusu
Chrome'daki izin iletişim kutusu

Yedek sağlama

navigator.mediaDevices.getUserMedia() desteği olmayan kullanıcılar için seçeneklerden biri, API desteklenmiyorsa ve/veya çağrı herhangi bir nedenden dolayı başarısız olursa mevcut bir video dosyasına ekleyin:

if (!navigator.mediaDevices?.getUserMedia) {
  video.src = "fallbackvideo.webm";
} else {
  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
  video.srcObject = stream;
}