Nagrywanie Video

Podczas nagrywania, potrzebny nam będzie podgląd na nagrywany obraz. W tym celu w pliku layoutu aktywności wstawiam komponent SurfaceView. Będzie robił za mini ekran kamery. Wielkość i szerokość tego podglądu ustawiłem na na tyle małe aby zmieściło się na większości ekranów telefonów z Androidem (parametry layout_width i layout_height). Nie daję fill_parent, ponieważ chcę obok jeszcze umieścić guzik służący do rozpoczynania i przerywania nagrywania.

xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<LinearLayout

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<SurfaceView

android:id="@+id/videoview"

android:layout_width="360px"

android:layout_height="240px"/>

<Button

android:id="@+id/mybutton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Nagrywaj"

/>

LinearLayout>

LinearLayout>

Trzeba też zadbać o niezbędne uprawnienia aplikacji. Moja kamera będzie rejestrowała nie tylko obraz, ale i dźwięk – stąd też uprawnienia do nagrywania audio. Sam plik z nagraniem zostanie zapisany na zewnętrznej karcie pamięci – stąd uprawnienie WRITE_EXTERNAL_STORAGE. Jeśli zamierzasz zapisywać nagrany film w pamięci wbudowanej, tego uprawnienia nie potrzebujesz.

<uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Przejdźmy teraz do kodu który będzie całość obsługiwać. Aby nasza aktywność mogła otrzymywać informacje o tym że powierzchnia podglądu została przygotowana (a będzie trzeba ją przygotować przed rozpoczęciem nagrywania), nasza aktywność musi implementować interfejs SurfaceHolder.CallBack. W związku z implementacją tego interfejsu musimy też posiadać zaimplementowaną metodę onSurfaceChanged (ale nie będziemy jej tutaj rozwijać). W linii 20 definiuję obiekt którego użyję do obsługi przycisku (dalej podpinam pod niego referencję do buttona zdefiniowanego w layoucie). W linii 21 tworzę obiekt klasy MediaRecorder. To klasa służąca do rejestracji obrazu i dźwięku. W linii 22 tworzę obiekt klasy SurfaceHolder. Z użyciem obiektu tej klasy możemy np. konfigurować wielkość i format nagrania, ale ogólnie służy do „obserwacji” tego co się dzieje z obiektem surfaceView – czyli ekranem podglądu.

W linii 23 tworzę obiekt który będzie reprezentował ekran podglądu nagrania. Na ekranie będę miał też guzik, początkowo będzie na nim napis „Nagrywaj”. Kiedy nacisnę go pierwszy raz, ma się rozpocząć nagrywanie a napis na nim ma się zmienić na „Koniec”. Kiedy kliknę po raz drugi, ma zostać przerwane nagranie i zapisany plik. Potrzebuję więc zmiennej (linia 24), tutaj typu boolean której stan będzie informował o tym czy trwa nagranie czy nie. Zdefiniowana w linii 25 zmienna sciezkaPliku ma wskazywać nazwę i ścieżkę do pliku z nagraniem który ma zostać utworzony. Linie 27-43 to metoda która ma obsługiwać naciscięnia przycisku. Za pierwszym kliknięciem wykonywany jest kod z linii 39-41, rozpoczyna się nagrywanie a napis na przycisku zmienia się na „Koniec”. Przy drugim kliknięciu, wykonywany jest kod z linii 28-38. Przerywane jest nagrywanie, a dodatkowo sprawdziam czy utworzył się plik z nagraniem. Jeśli zostanie faktycznie stworzony, dostanę na konsoli LogCata informację o tym.

Przechodzimy teraz do metody onCreate, a więc uruchamianej w momencie startu aktywności.

Podpinam tutaj referencje do komponentów którymi będziemy się posługiwać, ustawiam nagrywanie tylko w poziomie (linia 51), rejestruję obiekt aktywności jako odbiornik dla zdarzeń związanych z nagrywaniem i przygotowywaniem ekranu podglądu (linie 54-56), a jako obsługę kliknięcia przycisku ustawiam wywołanie wcześniej omawianej metody klikniecie() (linia 61). W linii 52 wywołuję też metodę initMediaRecorder(), której zawartość wygląda tak:

Służy ona ustawieniu źródeł dźwięku i obrazu, jakości obrazu, maksymalnego czasu nagrania i maksymalnej wielkości pliku.

Przy uruchomieniu aktywności, tworzony jest też podgląd nagrania. Musimy go przy tej okazji przygotować. W metodzie surfaceCreated (wymaganej w związku z implementacją interfejsu Callback) wywołuję więc własna metodę prepareMediaRecorder, której jedynym zadaniem jest wykonanie wyżej wspomnianej czynności.

Aplikacja po uruchomieniu na emulatorze: