Praca z kamerami
Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje
Źródłem danych wideo, które wyświetla i na których operuje kod ActionScript, może być kamera podłączona do komputera użytkownika. Klasa
Camera
stanowi mechanizm wbudowany w kod ActionScript przeznaczony do pracy z kamerą komputera lub urządzenia.
Na urządzeniach przenośnych można również używać klasy
CameraUI
. Klasa CameraUI powoduje uruchomienie oddzielnej aplikacji kamery, przy użyciu której użytkownik może rejestrować obrazy nieruchome lub wideo. Po zakończeniu pracy przez użytkownika aplikacja może uzyskać dostęp do obrazów lub filmów wideo za pośrednictwem obiektu
MediaPromise
.
Omówienie klasy Camera
Obiekt Camera umożliwia nawiązanie połączenia z lokalną kamerą użytkownika i rozgłaszanie wideo z kamery lokalnie (na komputerze użytkownika) lub zdalnie do serwera (np. Flash Media Server).
Korzystając z klasy Camera, można uzyskać dostęp do następujących rodzajów informacji o kamerze użytkownika:
-
które z kamer zainstalowanych na komputerze lub na urządzeniu użytkownika są dostępne;
-
czy w ogóle jest zainstalowana kamera;
-
czy program Flash Player ma zezwolenie na dostęp do kamery użytkownika;
-
która kamera jest obecnie aktywna;
-
szerokość i wysokość przechwytywanego wideo.
Klasa Camera zawiera kilka użytecznych metod i właściwości służących do pracy z obiektami kamer. Na przykład statyczna właściwość
Camera.names
zawiera tablicę nazw kamer zainstalowanych obecnie w komputerze użytkownika. Można również skorzystać z właściwości
name
w celu wyświetlenia nazwy kamery, która jest obecnie aktywna.
Uwaga:
Podczas przesyłania strumieniowego w sieci wideo z aparatu należy zawsze obsługiwać przerwy w działaniu sieci. Przerwy w działaniu sieci mogą być spowodowane szeregiem czynników, szczególnie na urządzeniach przenośnych.
Wyświetlanie obrazu z kamery na ekranie
Połączenie z kamerą można zrealizować w prostszy sposób niż ładowanie wideo przy użyciu klas NetConnection i NetStream. Z drugiej strony, sposób użycia klasy Camera nie zawsze jest oczywisty, ponieważ w programie Flash Player dostęp do kamery jest możliwy dopiero po udzieleniu przez użytkownika zgody na taki dostęp.
Poniższy kod ilustruje sposób użycia klasy Camera do nawiązania połączenia z lokalną kamerą użytkownika:
var cam:Camera = Camera.getCamera();
var vid:Video = new Video();
vid.attachCamera(cam);
addChild(vid);
Uwaga:
Klasa Camera nie ma konstruktora. Do tworzenia nowych instancji klasy Camera służy statyczna metoda
Camera.getCamera()
.
Projektowanie aplikacji współpracującej z kamerą
Pisząc aplikację nawiązującą połączenie z kamerą użytkownika, należy uwzględnić następujące uwarunkowania:
-
Należy sprawdzić, czy użytkownik ma zainstalowaną kamerę. Należy obsłużyć sytuację, w której nie jest dostępny żadna kamera.
-
Tylko w przypadku programu Flash Player — należy sprawdzić, czy użytkownik jawnie zezwolił na dostęp do kamery. Ze względów bezpieczeństwa wyświetlane jest okno dialogowe ustawień programu Flash Player, w którym użytkownik może zezwolić na dostęp do kamery lub odmówić takiego dostępu. Uniemożliwia to programowi Flash Player nawiązanie połączenia z kamerą i rozgłaszanie strumienia wideo bez zgody użytkownika. Jeśli użytkownik kliknie opcję zezwolenia, aplikacja może nawiązać połączenie z kamerą użytkownika. Jeśli użytkownik kliknie opcję odmowy, aplikacja nie będzie miała dostępu do kamery. Aplikacja powinna zawsze prawidłowo reagować na obie decyzje użytkownika.
-
Tylko w środowisku AIR należy sprawdzić, czy klasa Camera jest obsługiwana dla profilów urządzeń obsługiwanych przez aplikację.
-
Klasa Camera nie jest obsługiwana w przeglądarkach na urządzeniach przenośnych.
-
Klasa Camera nie jest obsługiwana w aplikacjach AIR na urządzeniach przenośnych, w których jest używany tryb renderowania GPU.
-
W urządzeniach przenośnych może być aktywna tylko jedna kamera naraz.
Nawiązywanie połączenia z kamerą użytkownika
Pierwszym krokiem przy nawiązywaniu połączenia z kamerą użytkownika jest utworzenie nowej instancji kamery poprzez utworzenie zmiennej typu Camera i zainicjowanie jej wartością zwróconą ze statycznej metody
Camera.getCamera()
.
Następnym krokiem jest utworzenie obiektu wideo i przyłączenie do niego obiektu Camera.
Trzecim krokiem jest dodanie obiektu wideo do listy wyświetlania. Kroki 2 i 3 są konieczne, ponieważ klasa Camera nie rozszerza klasy DisplayObject i obiektów klasy Camera nie można dodawać bezpośrednio do listy wyświetlania. Aby wyświetlać obraz wideo przechwytywany z kamery, należy utworzyć nowy obiekt wideo i wywołać metodę
attachCamera()
.
Poniższy kod ilustruje wymienione trzy kroki:
var cam:Camera = Camera.getCamera();
var vid:Video = new Video();
vid.attachCamera(cam);
addChild(vid);
Należy zwrócić uwagę, że jeśli użytkownik nie ma zainstalowanej kamery, aplikacja nie wyświetla żadnych informacji.
W prawdziwej aplikacji konieczne jest wykonanie dodatkowych kroków. Więcej informacji zawierają sekcje
Sprawdzanie, czy kamera jest zainstalowania
oraz
Wykrywanie uprawnień dostępu do kamery
.
Sprawdzanie, czy kamera jest zainstalowania
Przed próbą użycia jakichkolwiek metod lub właściwości instancji kamery należy sprawdzić, czy w komputerze użytkownika jest zainstalowana kamera. Istnieją dwa sposoby sprawdzenia, czy użytkownik ma zainstalowaną kamerę:
-
Odczyt statycznej właściwości
Camera.names
, która zawiera listę nazw dostępnych kamer. Zwykle ta tablica będzie zawierała jeden ciąg znaków lub w ogóle nie będzie zawierała ciągów znaków, ponieważ użytkownicy rzadko mają zainstalowaną więcej niż jedną kamerę. Poniższy kod ilustruje sposób odczytywania właściwości
Camera.names
w celu sprawdzenia, czy w komputerze użytkownika są dostępne kamery:
if (Camera.names.length > 0)
{
trace("User has at least one camera installed.");
var cam:Camera = Camera.getCamera(); // Get default camera.
}
else
{
trace("User has no cameras installed.");
}
-
Sprawdzenie wartości zwracanej przez statyczną metodę
Camera.getCamera()
. Jeśli żadne kamery nie są dostępne lub zainstalowane, metoda ta zwraca
null
, w przeciwnym razie zwraca odwołanie do obiektu Camera. Poniższy kod ilustruje sposób odczytywania wyniku metody
Camera.getCamera()
w celu sprawdzenia, czy w komputerze użytkownika są dostępne kamery:
var cam:Camera = Camera.getCamera();
if (cam == null)
{
trace("User has no cameras installed.");
}
else
{
trace("User has at least 1 camera installed.");
}
Ponieważ klasa Camera nie rozszerza klasy DisplayObject, obiektów Camera nie można dodawać bezpośrednio do listy wyświetlania przy użyciu metody
addChild()
. Aby wyświetlać obraz wideo z kamery, należy utworzyć nowy obiekt Video i wywołać metodę
attachCamera()
w instancji obiektu Video.
Poniższy urywek kodu ilustruje sposób przyłączania kamery (jeśli kamera istnieje); w razie braku kamery aplikacja nie wyświetla żadnego obrazu:
var cam:Camera = Camera.getCamera();
if (cam != null)
{
var vid:Video = new Video();
vid.attachCamera(cam);
addChild(vid);
}
Kamery w urządzeniach przenośnych
Klasa Camera nie jest obsługiwana w środowisku wykonawczym Flash Player w przeglądarkach na urządzeniach przenośnych.
W aplikacjach AIR na urządzeniach przenośnych można uzyskiwać dostęp do kamer urządzeń. W urządzeniach przenośnych można używać kamery przedniej lub tylnej, ale w danej chwili może być wyświetlany obraz tylko z jednej kamery. (Podłączenie drugiej kamery spowoduje odłączenie pierwszej). W systemie iOS obraz z kamery przedniej jest poddawany odbiciu lustrzanemu w poziomie. Nie dzieje się tak w systemie Android.
Wykrywanie uprawnień dostępu do kamery
W obszarze izolowanym aplikacji środowiska AIR aplikacja ma dostęp do każdej kamery, bez pytania użytkownika o zgodę. W systemie Android w deskryptorze aplikacji musi być określone uprawnienie CAMERA systemu Android.
Jednak aby program Flash Player mógł wyświetlać obraz z kamery, użytkownik musi jawnie zezwolić mu na dostęp do kamery. Po wywołaniu przez aplikację metody
attachCamera()
program Flash Player wyświetla okno dialogowe Ustawienia Flash Player z monitem o zezwolenie lub odmowę dostępu do kamery i mikrofonu zainstalowanych w systemie. Jeśli użytkownik kliknie przycisk zezwolenia, program Flash Player wyświetli obraz z kamery w instancji Video na stole montażowym. Jeśli użytkownik kliknie przycisk odmowy, program Flash Player nie będzie mógł nawiązać połączenia z kamerą, a obiekt Video nie wyświetli żadnych informacji.
Aby sprawdzić, czy użytkownik zezwolił programowi Flash Player na dostęp do kamery, można wykrywać zdarzenia
status
kamery (
StatusEvent.STATUS
), co ilustruje poniższy kod:
var cam:Camera = Camera.getCamera();
if (cam != null)
{
cam.addEventListener(StatusEvent.STATUS, statusHandler);
var vid:Video = new Video();
vid.attachCamera(cam);
addChild(vid);
}
function statusHandler(event:StatusEvent):void
{
// This event gets dispatched when the user clicks the "Allow" or "Deny"
// button in the Flash Player Settings dialog box.
trace(event.code); // "Camera.Muted" or "Camera.Unmuted"
}
Funkcja
statusHandler()
jest wywoływana w momencie, gdy użytkownik kliknie przycisk zezwolenia albo odmowy. Aby sprawdzić, który przycisk został kliknięty, można skorzystać z jednej z dwóch metod:
-
Parametr
event
funkcji
statusHandler()
zawiera właściwość code, która z kolei zawiera ciąg znaków "Camera.Muted" albo "Camera.Unmuted". Wartość "Camera.Muted" oznacza, że użytkownik kliknął przycisk odmowy, a program Flash Player nie ma dostępu do kamery. Oto przykład zastosowania tej metody:
function statusHandler(event:StatusEvent):void
{
switch (event.code)
{
case "Camera.Muted":
trace("User clicked Deny.");
break;
case "Camera.Unmuted":
trace("User clicked Accept.");
break;
}
}
-
Klasa Camera zawiera właściwość
muted
przeznaczoną tylko do odczytu; właściwość ta określa, czy użytkownik odmówił dostępu do kamery (
true
), czy zezwolił na taki dostęp (
false
) w panelu Prywatność programu Flash Player. Oto przykład zastosowania tej metody:
function statusHandler(event:StatusEvent):void
{
if (cam.muted)
{
trace("User clicked Deny.");
}
else
{
trace("User clicked Accept.");
}
}
Wykrywając zdarzenie status, kod może odpowiednio reagować na zgodę lub odmowę użytkownika na dostęp do kamery i wykonać odpowiednie czynności porządkowe. Na przykład, jeśli użytkownik kliknie przycisk odmowy, może zostać wyświetlony komunikat informujący, że bez zgody na dostęp do kamery nie będzie możliwy udział użytkownika w wideoczacie. Kod może także usuwać obiekt Video z listy wyświetlania w celu zwolnienia zasobów systemowych.
W środowisku AIR obiekt Camera nie wywołuje zdarzeń stanu, ponieważ uprawnienie do używania kamery nie jest dynamiczne.
Uzyskiwanie jak najlepszej jakości wideo z kamery
Domyślnie nowe instancje klasy Video mają szerokość 320 pikseli i wysokość 240 pikseli. Aby uzyskać jak najlepszą jakość wideo, należy zawsze dbać o to, aby obiekt wideo aplikacji miał te same wymiary, co obraz wideo przesyłany z obiektu kamery. Szerokość i wysokość obrazu z obiektu kamery można uzyskać, odczytując właściwości
width
i
height
klasy Camera. Następnie można przypisać właściwościom
width
i
height
obiektu wideo wymiary obrazu lub przekazać szerokość i wysokość obrazu z kamery do konstruktora klasy Video, co ilustruje poniższy fragment:
var cam:Camera = Camera.getCamera();
if (cam != null)
{
var vid:Video = new Video(cam.width, cam.height);
vid.attachCamera(cam);
addChild(vid);
}
Ponieważ metoda
getCamera()
zwraca odwołanie do obiektu kamery (lub
null
, jeśli nie ma dostępnej kamery), możliwe jest uzyskiwanie dostępu do metod i właściwości kamery nawet wówczas, gdy użytkownik odmówi dostępu do swojej kamery. Dzięki temu możliwe jest dopasowanie rozmiaru instancji Video do natywnej wysokości i szerokości obrazu z kamery.
var vid:Video;
var cam:Camera = Camera.getCamera();
if (cam == null)
{
trace("Unable to locate available cameras.");
}
else
{
trace("Found camera: " + cam.name);
cam.addEventListener(StatusEvent.STATUS, statusHandler);
vid = new Video();
vid.attachCamera(cam);
}
function statusHandler(event:StatusEvent):void
{
if (cam.muted)
{
trace("Unable to connect to active camera.");
}
else
{
// Resize Video object to match camera settings and
// add the video to the display list.
vid.width = cam.width;
vid.height = cam.height;
addChild(vid);
}
// Remove the status event listener.
cam.removeEventListener(StatusEvent.STATUS, statusHandler);
}
Informacje na temat trybu pełnoekranowego zawiera punkt dotyczący tego trybu w sekcji
Ustawianie właściwości obiektu Stage
.
Monitorowanie stanu kamery
Klasa Camera zawiera kilka właściwości umożliwiających monitorowanie bieżącego statusu obiektu Camera. Na przykład poniższy kod wyświetla kilka właściwości kamery przy użyciu obiektu Timer i instancji pola tekstowego na liście wyświetlania:
var vid:Video;
var cam:Camera = Camera.getCamera();
var tf:TextField = new TextField();
tf.x = 300;
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
if (cam != null)
{
cam.addEventListener(StatusEvent.STATUS, statusHandler);
vid = new Video();
vid.attachCamera(cam);
}
function statusHandler(event:StatusEvent):void
{
if (!cam.muted)
{
vid.width = cam.width;
vid.height = cam.height;
addChild(vid);
t.start();
}
cam.removeEventListener(StatusEvent.STATUS, statusHandler);
}
var t:Timer = new Timer(100);
t.addEventListener(TimerEvent.TIMER, timerHandler);
function timerHandler(event:TimerEvent):void
{
tf.text = "";
tf.appendText("activityLevel: " + cam.activityLevel + "\n");
tf.appendText("bandwidth: " + cam.bandwidth + "\n");
tf.appendText("currentFPS: " + cam.currentFPS + "\n");
tf.appendText("fps: " + cam.fps + "\n");
tf.appendText("keyFrameInterval: " + cam.keyFrameInterval + "\n");
tf.appendText("loopback: " + cam.loopback + "\n");
tf.appendText("motionLevel: " + cam.motionLevel + "\n");
tf.appendText("motionTimeout: " + cam.motionTimeout + "\n");
tf.appendText("quality: " + cam.quality + "\n");
}
Co 1/10 sekundy (100 milisekund) wywoływane jest zdarzenie
timer
obiektu Timer, a funkcja
timerHandler()
aktualizuje pole tekstowe na liście wyświetlania.
|
|
|
|
|