Дополненная и виртуальная реальность, хотя и остается относительно новой, быстро стала популярной для приложений, в том числе для игр и образования. Ранее я показал вам, как установить Картон с помощью 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 и дополненной реальности!