chevron-left chevron-right

[JS] Jak wyświetlić obraz z kamery za pomocą Javascript?

W dzisiejszych czasach można korzystać z wielu różnych komunikatorów, które pozwalają na przesył obrazu wideo między użytkownikami, m.in. Skype czy Google Hangouts. W tym artykule przedstawię sposób na dobranie się do kamery użytkownika za pomocą kodu Javscript.

Korzystamy z navigator.getUserMedia()

Aby móc korzystać z dobrodziejstw kamery (zainstalowanej w większości laptopów czy też innych) należy użyć metody navigator.getUserMedia(). Ze względu na fakt, że nie posiada ona w pełni ukończonej specyfikacji, musimy pamiętać o tym, aby korzystać z wersji z prefixami (co będzie można zobaczyć w kodzie poniżej).

Funkcja navigator.getUserMedia() przyjmuje 3 parametry:

  1. Obiekt z danymi o typie urządzenia z którego chcemy skorzystać (kamera lub mikrofon, albo obydwa naraz),
  2. Funkcję sukcesu (success callback),
  3. Funkcję z obsługą błędu (error callback).

Ostatni parametr nie jest wymagany, ale dobrym zwyczajem jest zadbanie o obsługę błędów w swoim kodzie Javascript.

Przykładowy kod Javascript zapewniający obsługę kamery

Poniższy przykład będzie prosty. Celem kodu poniżej będzie wyświetlenie obrazu z kamery w oknie przeglądarki. Najpierw kod HTML:

1
2
<input type="button" id="share" value="Wyświetl obraz z kamery"/>
<video id="video" autoplay/>

Jak widać, nic szczególnego. Przycisk oraz tag >video< gdzie będziemy zamieszczać strumień wideo z naszej kamery. Kod JS obsługujący taki kod HTML wygląda następująco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// pobieramy odpowiednią wersję metody getUserMedia w zależności od przeglądarki
// i przypisujemy ją do zmiennej globalnej
navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
 
// jeśli funkcjonalność jest dostępna w przeglądarce
if (navigator.getUserMedia) {
  // pobierz referencję do przycisku
  var screenShareButton = document.getElementById('share');
 
  // przypisz funkcję do wywołania gdy będzie miało miejce kliknięcie w przycisk
  screenShareButton.addEventListener('click', function () {
    // definiujemy dane jakich potrzebujemy oraz określamy co z nimi zrobimy
    navigator.getUserMedia({
      audio : false, // nie chcemy mieć dźwięku z mikrofonu
      video : { // chcemy mieć wideo o określonych maksymalnych wymiarach
        optional  : [],
        mandatory : {
          maxWidth  : 1280,
          maxHeight : 720
        }
      }
    }, function (stream) { // funkcja sukcesu (success callback)
      // zmieniamy źródło danych w tagu video
      document.getElementById('video').src = window.URL.createObjectURL(stream);
      // ukrywamy przycisk
      screenShareButton.classList.add('hidden');
    }, function () { // funkcja z obsługą błędu
      alert('Niemożliwe jest pokazanie obrazu z kamery. Prawdopodobnie korzystasz z przeglądarki, która nie posiada tej funkcjonalności');
    });
  });
}

Wydaje mi się że kod został dobrze opisany za pomocą komentarzy. Pokrótce tylko powiem, że powyższy kod sprawdza czy funkcjonalność udostępniania obrazu z kamery istnieje w przeglądarce i jeśli istnieje, to następuje udostępnienie streamingu z obrazu kamery i wyświetlenie go w oknie przeglądarki.

Podsumowanie

Powyższy kod jest tylko wstępem do bardzo wielu możliwości wykorzystania kamery w aplikacjach internetowych. Za pomocą tego kodu, można spróbować utworzyć własny komunikator a'la Google Hangouts albo aplikację do obserwowania swojego domu, gdy jest się poza nim. Jak to się mówi: "Sky is the limit" 🙂

Mam nadzieję, że ten artykuł zaciekawił Ciebie i zainspirował do działania. Warto dodać, że powyższy kod będzie działał tylko w przeglądarkach: Firefox, Google Chrome oraz Opera.

  • Nie sądzisz, że callback błędu w getUserMedia nie odpaliłby się gdyby przeglądarka nie miała tej funkcjonalności? 😉

    Cieszy mnie, że ktoś w Polsce w końcu zauważył istnienie tego API – ma już dobre 2 lata a dotąd w naszym kraju jakoś cicho o tym.

    Szkoda tylko, że obecnie można tego użyć aż do dwóch rzeczy: do wsadzenia w tag video i do wysłania do „klienta WebRTC”. Streaming przez serwer? Można zapomnieć. Nagrywanie? Wciąż in flux i w żadnym browserze nie działa (a specka MediaRecorder też ma z 2 lata…).

    Paradoksalnie więcej możliwości daje obecnie wsadzanie streamu do obiektu video. Filtry SVG – FTW!

  • Co do callback’a błędu. Masz rację, niefortunnie dobrałem komunikat (była już późna pora, gdy to pisałem).

    W Polsce zauważono to API, ale jest o tym cicho bo … nie znam powodu. Może po prostu spowodowane brakiem zaciekawienia i faktem, że jednak wiele osób jednak pracuje na komputerach stacjonarnych bez kamer gdzie można by to przetestować?

    Jeszcze nie zdążyłem się przekonać, że nie można tak streamować wideo. A jak to mówią: „Dopóki nie wiesz, że jest to nieosiągalne to jest to możliwe” 🙂

  • >Może po prostu spowodowane brakiem zaciekawienia i faktem, że jednak wiele osób jednak pracuje na komputerach stacjonarnych bez kamer gdzie można by to przetestować?
    W sumie to może być to – trudno testować kamerkę bez kamerki 😀 z drugiej strony – wszyscy mają smartphone’y a tam to chyba też już działa.

    >A jak to mówią: „Dopóki nie wiesz, że jest to nieosiągalne to jest to możliwe” 🙂
    Miałem to samo podejście jakiś rok temu. Specyfikacja WebRTC pokonała mnie jeszcze szybciej niż ta od ES 5.1. Cóż, od tamtego czasu czekam aż ktoś się zlituje i zrobi dla node.js odpowiednie bindingi 😀