Работа с аудио и видеоинформацией в приложениях для смартфона, использование Intel Perceptual Computing SDK
Запись аудио- и видео-данных
Следующий вопрос, который будет интересовать нас в данной лекции, связан с возможностью разработки приложений, позволяющих записывать аудио- и видео-контент.
Самый простой способ записи видео заключается в использовании intent-объектов для запуска стандартного приложения, управляющего камерой. Для запуска записи видео необходимо создать новый intent-объект, используя константу ACTION_VIDEO_CAPTURE класса MediaStore:
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Можно (но не обязательно) настроить пару свойств intent-объекта:
- место сохранения видеозаписи, если есть необходимость сохранить ее в месте, отличном от используемого по умолчанию, применяют константу EXTRA_OUTPUT класса MediaStore:
outputpath – указывает альтернативный путь URI;
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputpath);
- качество видеозаписи, если есть необходимость сохранить картинку в качестве, отличном от используемого по умолчанию, применяют константу EXTRA_VIDEO_QUALITY класса MediaStore:
VIDEO_QUALITY — указывает качество видеозаписи, может принимать всего два значения 0 и 1, значение 0 задает низкое качество (подходит для MMS), значение 1 задает высокое качество. По умолчанию используется 1.
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, VIDEO_QUALITY);
После создания и настройки intent-объекта необходимо вызвать метод startActivityForResult() и передать ему полученный Intent в качестве параметра:
startActivityForResult(intent, RECORD_VIDEO);
Этот код запускает стандартную активность, управляющую видеокамерой и позволяющую начать, остановить, просмотреть и повторить запись видео. При этом нет необходимости создавать собственное приложение для этих нужд.
Другой способ записи мультимедийных файлов состоит в использовании класса MediaRecorder, который позволяет указать источник для аудио и видео, формат итогового файла, а также кодировщики, использующиеся для записи. Чтобы иметь возможность записывать мультимедийные файлы в Android, приложение должно получить полномочия RECORD_AUDIO и/или RECORD_VIDEO. Для этого необходимо добавить в манифест приложения следующие строки:
<uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.RECORD_VIDEO"/>
Для управления записью медиа-контента с помощью класса MediaRecorder необходимо выполнить следующие действия в заданной последовательности:
-
создать экземпляр класса MediaRecorder:
MediaRecorder mediaRecorder = new MediaRecorder();
-
определить источник записи с помощью методов setAudioSource() и setVideoSource(), которым в качестве параметра передаются статические константы классов MediaRecorder.AudioSource и MediaRecorder.VideoSource, определяющие источники для аудио и видеоданных соответственно:
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-
задать итоговый формат с помощью метода setOutputFormat(), передав ему одну из констант класса MediaRecorder.OutputFormat:
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
-
определить кодировщики для аудио и видео с помощью методов setAudioEncoder() и setVideoEncoder(), используя константы класса MediaRecorder.AudioEncoder и MediaRecorder.VideoEncoder, соответственно.
При желании можно установить частоту кадров и размер итогового видео.
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
-
выбрать итоговый файл с помощью метода setOutputFile():
После выполнения вышеперечисленных действий, получим экземпляр класса MediaRecorder, настроенный для записи аудио- и видеоданных с микрофона и камеры, соответственно, при этом использованы итоговый формат и кодировщики по умолчанию, а запись будет сохранена на карту SD.
mediaRecorder.setOutputFile("/sdcard/myoutputfile.mp4");
-
подготовить к записи с помощью метода prepare():
mediaRecorder.prepare();
-
начать запись с помощью метода start():
mediaRecorder.start();
-
завершить запись с помощью метода stop() – завершение записи, и метода release() – освобождение ресурсов объекта MediaRecorder:
mediaRecorder.stop(); mediaRecorder.release();
Подробно жизненный цикл класса MediaRecorder рассмотрен в лекции 9 курса "Введение в разработку приложений для ОС Android" на Интуит (http://www.intuit.ru/studies/courses/12643/1191/lecture/21992?page=2#sect7).
Метод setOutputFile() нужно вызвать до метода prepare() и после метода setOutputFormat(), иначе произойдет выброс исключения IllegalStateException.
В процессе записи видео, как правило, предполагается предварительный просмотр записываемой картинки. Метод setPreviewDisplay() позволяет задать объект Surface для показа видеопотока во время записи. Работает данный подход так же, как воспроизведение видео с помощью медиаплеера, описанное ранее.
mediaRecorder.setPreviewDisplay((SurfaceView)findViewById (R.id.surface).getHolder().getSurface()); mediaRecorder.prepare();
После настройки предварительного просмотра необходимо вызвать метод prepare(), после этого на экране в режиме реального времени начнет отображаться записываемый видеопоток.
Добавление мультимедийных файлов в MediaStore
По умолчанию мультимедийные файлы, созданные любым приложением, недоступны для других программ, чтобы предоставить доступ к таким файлам необходимо добавить их в MediaStore.
Android предоставляет два способа добавления данных в MediaStore:
-
Первый способ предполагает использование сервиса MediaScannerConnection, который автоматически распознает и внесет ваш файл в MediaStore.
Для установки связи с сервисом MediaScannerConnection необходимо вызвать метод connect(), чтобы получить уведомление об успешной установке связи необходимо реализовать интерфейс MediaScannerConnectionClient. В реализации необходимо прописать методы onMediaScannerConnected() и onScanCompleted(), первый вызывается системой, когда связь с сервисом установлена, второй — когда завершен процесс сканирования. В первом методе вызываем метод scanFile(), чтобы начать сканирование, во втором — вызываем метод disconnect(), чтобы разорвать связь с сервисом. В пример 11.4 показан каркас для создания нового класса MediaScannerConnectionClient.
MediaScannerConnectionClient mediaScannerClient = new MediaScannerConnectionClient() { private MediaScannerConnection msc = null; msc = new MediaScannerConnection(getApplicationContext(), this); msc.connect(); public void onMediaScannerConnected() { msc.scanFile("/sdcard/test1.jpg", null); } public void onScanCompleted(String path, Uri uri) { msc.disconnect(); } };
Пример 11.4. -
Второй способ предполагает создание нового объекта ContentValues и добавление его в соответствующий источник данных.
В качестве метаданных для нового медиафайла нужно указывать название, временную отметку (timestamp) и географическую информацию, как показано в
пример
11.5.
ContentValues content = new ContentValues(3); content.put(Audio.AudioColumns.TITLE, "TheSoundandtheFury"); content.put(Audio.AudioColumns.DATE_ADDED, System.currentTimeMillis()/1000); content.put(Audio.Media.MIME_TYPE, "audio/amr"); //указание абсолютного пути к добавляемому файлу content.put(MediaStore.Audio.Media.DATA, "/sdcard/myoutputfile.mp4"); //доступ к объекту ContentResolver приложения ContentResolver resolver = getContentResolver(); //вставка новой строки в MediaStore Uri uri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, content); //объявление о доступности добавленного файла sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
Пример 11.5.