Дополненная и виртуальная реальность, хотя и остается относительно новой, быстро стала популярной для приложений, в том числе для игр и образования. Ранее я показал вам, как установить Картон с помощью Android SDK и как создать панорамный просмотрщик изображений. Этот пост покажет вам, как использовать 360-градусное видео в ваших приложениях.
Настроить
Прежде чем вы начнете создавать приложение для просмотра видео, вам нужно будет клонировать Android Cardboard Android на ваш компьютер через Git. Вы можете найти инструкции для этого в предыдущей статье этой серии .
Для нашего примера создайте новый проект Android с минимальным SDK API 19 (KitKat) и используйте шаблон Empty Activity .
После создания базового проекта вам нужно будет скопировать папки common , commonwidget и videowidget из Cardboard SDK в корневой каталог вашего проекта. После того, как эти каталоги будут перемещены, вам нужно будет включить их как модули в ваш проект, отредактировав файл settings.gradle, чтобы он выглядел как следующий фрагмент.
|
1
|
include ‘:app’, «:common», «commonwidget», «videowidget»
|
Наконец, включите эти и другие необходимые библиотеки в свой проект, добавив следующие строки в файл build.gradle модуля приложения под узлом зависимостей .
|
01
02
03
04
05
06
07
08
09
10
|
dependencies {
compile ‘com.android.support:appcompat-v7:25.0.0’
compile project(‘:common’)
compile project(‘:commonwidget’)
compile project(‘:videowidget’)
compile ‘com.google.android.exoplayer:exoplayer:r1.5.10’
compile ‘com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7’
}
|
Вы заметите, что мы добавили библиотеку Protocol Buffers от Google , которая помогает управлять ресурсами времени выполнения на устройстве, и ExoPlayer , которая является созданной Google библиотекой VrVideoView которой построен компонент VrVideoView . Обе эти библиотеки требуются для работы Cardboard SDK, и вы, возможно, заметили, что используемая версия ExoPlayer относится к первой версии, а не ко второй, поэтому может вызывать конфликты, если вы используете ExoPlayer v2 в своих собственных проектах.
Затем мы хотим обновить наш файл activity_main.xml для нашего примера проекта, чтобы он включал VrVideoView , SeekBar и Button которой мы будем работать позже.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout xmlns:android=»http://schemas.android.com/apk/res/android»
android:layout_width=»match_parent»
android:layout_height=»match_parent»
android:orientation=»vertical»>
<com.google.vr.sdk.widgets.video.VrVideoView
android:id=»@+id/video_view»
android:layout_width=»match_parent»
android:layout_height=»250dp»/>
<SeekBar
android:id=»@+id/seek_bar»
android:layout_height=»32dp»
android:layout_width=»match_parent»
style=»?android:attr/progressBarStyleHorizontal»/>
<Button
android:id=»@+id/btn_volume»
android:layout_width=»wrap_content»
android:layout_height=»wrap_content»
android:text=»Volume Toggle»/>
</LinearLayout>
|
Как только вы закончите настройку библиотек Cardboard и создадите макет, который мы будем использовать, пришло время перейти к Java-коду.
Работа с картоном и VR-видео
Прежде чем мы сможем начать писать весь код, который управляет состоянием воспроизведения, положением и загрузкой вашего видеофайла 360, нам необходимо определить источник нашего видео. Для этого урока мы просто создадим папку ресурсов в главном каталоге и разместим там видео 360. Хотя есть несколько источников для 360 видео онлайн, я включил короткое общедоступное видео из Sea World, возвращающего морскую черепаху в океан, в сопровождающий проект GitHub для этого урока.
Инициализация и структура
Теперь, когда у вас есть видеофайл для воспроизведения, откройте свой класс MainActivity .
Сначала вам нужно будет объявить и инициализировать элементы View , которые определены в файле макета, а также два boolean значения для отслеживания состояния приглушения и воспроизведения / паузы. Кроме того, мы OnClickListener на наш объект Button громкости.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public class MainActivity extends AppCompatActivity {
private VrVideoView mVrVideoView;
private SeekBar mSeekBar;
private Button mVolumeButton;
private boolean mIsPaused;
private boolean mIsMuted;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
mVrVideoView = (VrVideoView) findViewById(R.id.video_view);
mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
mVolumeButton = (Button) findViewById(R.id.btn_volume);
mVolumeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onVolumeToggleClicked();
}
});
}
public void playPause() {
}
public void onVolumeToggleClicked() {
}
}
|
Затем создайте новый внутренний класс, который расширяет VrVideoEventListener . Этот класс будет иметь пять методов, которые мы можем реализовать для нашего простого средства просмотра видео.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
private class ActivityEventListener extends VrVideoEventListener {
@Override
public void onLoadSuccess() {
super.onLoadSuccess();
}
@Override
public void onLoadError(String errorMessage) {
super.onLoadError(errorMessage);
}
@Override
public void onClick() {
super.onClick();
}
@Override
public void onNewFrame() {
super.onNewFrame();
}
@Override
public void onCompletion() {
super.onCompletion();
}
}
|
Вам также необходимо реализовать SeekBar.OnSeekBarChangeListener в вашем классе и создать заглушки методов для этого интерфейса.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
…
public void onPlayPausePressed() {
}
public void onVolumeToggleClicked() {
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
}
|
Как только вы создали этот новый внутренний класс и реализацию SeekBar , SeekBar их с вашими VrVideoView и SeekBar , соответственно, в конце метода initViews() который был определен выше.
|
1
2
|
mVrVideoView.setEventListener(new ActivityEventListener());
mSeekBar.setOnSeekBarChangeListener(this);
|
Есть еще один элемент настройки, о котором нужно позаботиться. Вам потребуется обработать жизненный цикл активности Android, поддерживая onPause() , onResume() и onDestroy() чтобы приостановить или возобновить рендеринг в VrVideoView или полностью его отключить. Вам также нужно будет отслеживать состояние паузы в этих методах.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
@Override
protected void onPause() {
super.onPause();
mVrVideoView.pauseRendering();
mIsPaused = true;
}
@Override
protected void onResume() {
super.onResume();
mVrVideoView.resumeRendering();
mIsPaused = false;
}
@Override
protected void onDestroy() {
mVrVideoView.shutdown();
super.onDestroy();
}
|
Теперь, когда начальная настройка нашего учебного класса завершена, мы можем перейти к более интересной теме: загрузка видео, управление воспроизведением и настройка пользовательского интерфейса.
Запуск и управление VrVideoView
Поскольку загрузка видео 360 может занять от доли секунды до нескольких секунд, вам нужно будет загрузить видео с помощью фоновой задачи. Давайте начнем с создания нового AsyncTask , который создаст новый объект VrVideoView.Options , установите тип ввода в соответствии с форматированием нашего видео (в случае с этим учебным TYPE_MONO , TYPE_MONO ), а затем загрузите наше видео из каталога активов .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
class VideoLoaderTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void… voids) {
try {
VrVideoView.Options options = new VrVideoView.Options();
options.inputType = VrVideoView.Options.TYPE_MONO;
mVrVideoView.loadVideoFromAsset(«seaturtle.mp4», options);
} catch( IOException e ) {
//Handle exception
}
return true;
}
}
|
Затем перейдите в метод onCreate() и создайте новый экземпляр этой задачи, а затем вызовите execute() для его запуска. Хотя для правильного выполнения этой задачи необходимо сделать еще кое-что, мы просто используем ее локально в этом методе для простоты и не беспокоимся о AsyncTask жизненного цикла AsyncTask .
|
1
2
|
VideoLoaderTask mBackgroundVideoLoaderTask = new VideoLoaderTask();
mBackgroundVideoLoaderTask.execute();
|
На этом этапе вы сможете запустить свое приложение и смотреть воспроизведение видео 360 в режиме просмотра видео с картона. Теперь, когда это работает, давайте добавим некоторую утилиту для нашего пользователя. Вернитесь к объекту ActivityEventListener который вы создали ранее в этом учебном пособии, так как мы захотим конкретизировать некоторые методы. Когда видео успешно загружено, нам нужно установить максимальное значение для нашего SeekBar , а также отслеживать состояние воспроизведения / паузы нашего видео.
|
1
2
3
4
5
6
7
|
@Override
public void onLoadSuccess() {
super.onLoadSuccess();
mSeekBar.setMax((int) mVrVideoView.getDuration());
mIsPaused = false;
}
|
По мере воспроизведения видео мы будем обновлять этот SeekBar через onNewFrame() и возвращать видео в исходное положение в onCompletion() . Наконец, в onClick() мы запустим наш метод переключения воспроизведения / паузы.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Override
public void onClick() {
playPause();
}
@Override
public void onNewFrame() {
super.onNewFrame();
mSeekBar.setProgress((int) mVrVideoView.getCurrentPosition());
}
@Override
public void onCompletion() {
//Restart the video, allowing it to loop
mVrVideoView.seekTo(0);
}
|
Несмотря на то, что обновление нашего SeekBar на основе воспроизведения важно, мы также хотим позволить пользователю изменять свое SeekBar в видео, взаимодействуя с SeekBar . Мы можем сделать это с SeekBar.OnSeekBarChangeListener интерфейса SeekBar.OnSeekBarChangeListener который мы реализовали ранее.
|
1
2
3
4
5
6
|
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if( fromUser ) {
mVrVideoView.seekTo(progress);
}
}
|
Чтобы округлить наши VrVideoView управления VrVideoView , нам нужно реализовать методы переключения воспроизведения / паузы и громкости.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public void playPause() {
if( mIsPaused ) {
mVrVideoView.playVideo();
} else {
mVrVideoView.pauseVideo();
}
mIsPaused = !mIsPaused;
}
public void onVolumeToggleClicked() {
mIsMuted = !mIsMuted;
mVrVideoView.setVolume(mIsMuted ? 0.0f : 1.0f);
}
|
На этом этапе у вас должен быть полностью работающий интерактивный видеоплеер 360, работающий в вашем приложении.

Однако, если вы поворачиваете свое устройство, вы можете заметить, что нежелательное поведение видео полностью перезапускается. Мы можем исправить это, работая с Android onSaveInstanceState() и onRestoreInstanceState() чтобы сохранить и сбросить состояние нашего VrVideoView .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
private static final String STATE_PROGRESS = «state_progress»;
private static final String STATE_DURATION = «state_duration»;
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putLong(STATE_PROGRESS, mVrVideoView.getCurrentPosition());
outState.putLong(STATE_DURATION, mVrVideoView.getDuration());
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
long progress = savedInstanceState.getLong(STATE_PROGRESS);
mVrVideoView.seekTo(progress);
mSeekBar.setMax((int) savedInstanceState.getLong(STATE_DURATION));
mSeekBar.setProgress((int) progress);
}
|
Теперь, когда устройство повернуто, ваше видео должно вернуться в исходное положение, и ваш пользователь сможет продолжить работу в непрерывном режиме.
Вывод
Несмотря на то, что для использования VrVideoView в Cardboard SDK необходимо обработать несколько мелких деталей, сложные компоненты, такие как фактическое воспроизведение и оптимизация, обрабатываются для вас компонентом, который легко реализовать.
Теперь вы сможете добавлять 360 видео в свои мультимедийные приложения, предоставляя своим пользователям интересную функцию, которая обогащает их опыт. В следующем уроке этой серии мы сосредоточимся на новом опыте Google VR под названием Daydream и на том, как использовать парный контроллер с вашими приложениями.
А пока посмотрите другие наши учебники по виртуальной реальности Android и дополненной реальности!




