Add VR player demo
PiperOrigin-RevId: 251460113
This commit is contained in:
parent
be88499615
commit
e4feaa68f2
@ -16,6 +16,7 @@
|
||||
for the underlying track was changing (e.g., at some period transitions).
|
||||
* Add a workaround for broken raw audio decoding on Oppo R9
|
||||
([#5782](https://github.com/google/ExoPlayer/issues/5782)).
|
||||
* Add VR player demo.
|
||||
|
||||
### 2.10.2 ###
|
||||
|
||||
|
4
demos/gvr/README.md
Normal file
4
demos/gvr/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# ExoPlayer VR player demo #
|
||||
|
||||
This folder contains a demo application that showcases 360 video playback using
|
||||
ExoPlayer GVR extension.
|
59
demos/gvr/build.gradle
Normal file
59
demos/gvr/build.gradle
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
apply from: '../../constants.gradle'
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName project.ext.releaseVersion
|
||||
versionCode project.ext.releaseVersionCode
|
||||
minSdkVersion 19
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
shrinkResources true
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt')
|
||||
}
|
||||
debug {
|
||||
jniDebuggable = true
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
// The demo app isn't indexed and doesn't have translations.
|
||||
disable 'GoogleAppIndexingWarning','MissingTranslation'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(modulePrefix + 'library-core')
|
||||
implementation project(modulePrefix + 'library-ui')
|
||||
implementation project(modulePrefix + 'library-dash')
|
||||
implementation project(modulePrefix + 'library-hls')
|
||||
implementation project(modulePrefix + 'library-smoothstreaming')
|
||||
implementation project(modulePrefix + 'extension-gvr')
|
||||
implementation 'androidx.annotation:annotation:1.0.2'
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.android.gms.strict-version-matcher-plugin'
|
74
demos/gvr/src/main/AndroidManifest.xml
Normal file
74
demos/gvr/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2019 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.exoplayer2.gvrdemo">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
|
||||
<uses-sdk/>
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/application_name"
|
||||
android:largeHeap="true">
|
||||
|
||||
<activity
|
||||
android:name="com.google.android.exoplayer2.gvrdemo.SampleChooserActivity"
|
||||
android:configChanges="keyboardHidden"
|
||||
android:exported="true"
|
||||
android:label="@string/application_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="asset"/>
|
||||
<data android:scheme="file"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.exolist\\.json"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.google.android.exoplayer2.gvrdemo.PlayerActivity"
|
||||
android:configChanges="density|keyboardHidden|navigation|orientation|screenSize|uiMode"
|
||||
android:enableVrMode="@string/gvr_vr_mode_component"
|
||||
android:exported="false"
|
||||
android:label="@string/application_name"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="false"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/VrActivityTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="com.google.intent.category.CARDBOARD"/> <!-- copybara:strip(development-only) -->
|
||||
<category android:name="com.google.intent.category.DAYDREAM"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.gvrdemo;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.widget.Toast;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.C.ContentType;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.PlaybackPreparer;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.ext.gvr.GvrPlayerActivity;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||
import com.google.android.exoplayer2.util.EventLogger;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/** An activity that plays media using {@link SimpleExoPlayer}. */
|
||||
public class PlayerActivity extends GvrPlayerActivity implements PlaybackPreparer {
|
||||
|
||||
public static final String EXTENSION_EXTRA = "extension";
|
||||
|
||||
public static final String SPHERICAL_STEREO_MODE_EXTRA = "spherical_stereo_mode";
|
||||
public static final String SPHERICAL_STEREO_MODE_MONO = "mono";
|
||||
public static final String SPHERICAL_STEREO_MODE_TOP_BOTTOM = "top_bottom";
|
||||
public static final String SPHERICAL_STEREO_MODE_LEFT_RIGHT = "left_right";
|
||||
|
||||
private DataSource.Factory dataSourceFactory;
|
||||
private SimpleExoPlayer player;
|
||||
private MediaSource mediaSource;
|
||||
private DefaultTrackSelector trackSelector;
|
||||
private TrackGroupArray lastSeenTrackGroupArray;
|
||||
|
||||
private boolean startAutoPlay;
|
||||
private int startWindow;
|
||||
private long startPosition;
|
||||
|
||||
// Activity lifecycle
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
String userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
|
||||
dataSourceFactory =
|
||||
new DefaultDataSourceFactory(this, new DefaultHttpDataSourceFactory(userAgent));
|
||||
|
||||
String sphericalStereoMode = getIntent().getStringExtra(SPHERICAL_STEREO_MODE_EXTRA);
|
||||
if (sphericalStereoMode != null) {
|
||||
int stereoMode;
|
||||
if (SPHERICAL_STEREO_MODE_MONO.equals(sphericalStereoMode)) {
|
||||
stereoMode = C.STEREO_MODE_MONO;
|
||||
} else if (SPHERICAL_STEREO_MODE_TOP_BOTTOM.equals(sphericalStereoMode)) {
|
||||
stereoMode = C.STEREO_MODE_TOP_BOTTOM;
|
||||
} else if (SPHERICAL_STEREO_MODE_LEFT_RIGHT.equals(sphericalStereoMode)) {
|
||||
stereoMode = C.STEREO_MODE_LEFT_RIGHT;
|
||||
} else {
|
||||
showToast(R.string.error_unrecognized_stereo_mode);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
setDefaultStereoMode(stereoMode);
|
||||
}
|
||||
|
||||
clearStartPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (Util.SDK_INT <= 23 || player == null) {
|
||||
initializePlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (Util.SDK_INT <= 23) {
|
||||
releasePlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
// PlaybackControlView.PlaybackPreparer implementation
|
||||
|
||||
@Override
|
||||
public void preparePlayback() {
|
||||
initializePlayer();
|
||||
}
|
||||
|
||||
// Internal methods
|
||||
|
||||
private void initializePlayer() {
|
||||
if (player == null) {
|
||||
Intent intent = getIntent();
|
||||
Uri uri = intent.getData();
|
||||
if (!Util.checkCleartextTrafficPermitted(uri)) {
|
||||
showToast(R.string.error_cleartext_not_permitted);
|
||||
return;
|
||||
}
|
||||
|
||||
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this);
|
||||
|
||||
trackSelector = new DefaultTrackSelector(new AdaptiveTrackSelection.Factory());
|
||||
lastSeenTrackGroupArray = null;
|
||||
|
||||
player =
|
||||
ExoPlayerFactory.newSimpleInstance(/* context= */ this, renderersFactory, trackSelector);
|
||||
player.addListener(new PlayerEventListener());
|
||||
player.setPlayWhenReady(startAutoPlay);
|
||||
player.addAnalyticsListener(new EventLogger(trackSelector));
|
||||
setPlayer(player);
|
||||
|
||||
mediaSource = buildMediaSource(uri, intent.getStringExtra(EXTENSION_EXTRA));
|
||||
}
|
||||
boolean haveStartPosition = startWindow != C.INDEX_UNSET;
|
||||
if (haveStartPosition) {
|
||||
player.seekTo(startWindow, startPosition);
|
||||
}
|
||||
player.prepare(mediaSource, !haveStartPosition, false);
|
||||
}
|
||||
|
||||
private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {
|
||||
@ContentType int type = Util.inferContentType(uri, overrideExtension);
|
||||
switch (type) {
|
||||
case C.TYPE_DASH:
|
||||
return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
|
||||
case C.TYPE_SS:
|
||||
return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
|
||||
case C.TYPE_HLS:
|
||||
return new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
|
||||
case C.TYPE_OTHER:
|
||||
return new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void releasePlayer() {
|
||||
if (player != null) {
|
||||
updateStartPosition();
|
||||
player.release();
|
||||
player = null;
|
||||
mediaSource = null;
|
||||
trackSelector = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStartPosition() {
|
||||
if (player != null) {
|
||||
startAutoPlay = player.getPlayWhenReady();
|
||||
startWindow = player.getCurrentWindowIndex();
|
||||
startPosition = Math.max(0, player.getContentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void clearStartPosition() {
|
||||
startAutoPlay = true;
|
||||
startWindow = C.INDEX_UNSET;
|
||||
startPosition = C.TIME_UNSET;
|
||||
}
|
||||
|
||||
private void showToast(int messageId) {
|
||||
showToast(getString(messageId));
|
||||
}
|
||||
|
||||
private void showToast(String message) {
|
||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private class PlayerEventListener implements Player.EventListener {
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {}
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
|
||||
if (player.getPlaybackError() != null) {
|
||||
// The user has performed a seek whilst in the error state. Update the resume position so
|
||||
// that if the user then retries, playback resumes from the position to which they seeked.
|
||||
updateStartPosition();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException e) {
|
||||
updateStartPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
||||
if (trackGroups != lastSeenTrackGroupArray) {
|
||||
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
|
||||
if (mappedTrackInfo != null) {
|
||||
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
|
||||
== MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
|
||||
showToast(R.string.error_unsupported_video);
|
||||
}
|
||||
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
|
||||
== MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
|
||||
showToast(R.string.error_unsupported_audio);
|
||||
}
|
||||
}
|
||||
lastSeenTrackGroupArray = trackGroups;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.gvrdemo;
|
||||
|
||||
import static com.google.android.exoplayer2.gvrdemo.PlayerActivity.SPHERICAL_STEREO_MODE_LEFT_RIGHT;
|
||||
import static com.google.android.exoplayer2.gvrdemo.PlayerActivity.SPHERICAL_STEREO_MODE_MONO;
|
||||
import static com.google.android.exoplayer2.gvrdemo.PlayerActivity.SPHERICAL_STEREO_MODE_TOP_BOTTOM;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
/** An activity for selecting from a list of media samples. */
|
||||
public class SampleChooserActivity extends Activity {
|
||||
|
||||
private final Sample[] samples =
|
||||
new Sample[] {
|
||||
new Sample(
|
||||
"Congo (360 top-bottom stereo)",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-1/360/congo.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"Sphericalv2 (180 top-bottom stereo)",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-1/360/sphericalv2.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"Iceland (360 top-bottom stereo ts)",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-1/360/iceland0.ts",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"Camera motion metadata test",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/synthetic_with_camm.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"actual_camera_cat",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/actual_camera_cat.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"johnny_stitched",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/johnny_stitched.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"lenovo_birds.vr",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/lenovo_birds.vr.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"mono_v1_sample",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/mono_v1_sample.mp4",
|
||||
SPHERICAL_STEREO_MODE_MONO),
|
||||
new Sample(
|
||||
"not_vr180_actually_shot_with_moto_mod",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/"
|
||||
+ "not_vr180_actually_shot_with_moto_mod.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"stereo_v1_sample",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/stereo_v1_sample.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
new Sample(
|
||||
"yi_giraffes.vr",
|
||||
"https://storage.googleapis.com/exoplayer-test-media-internal-"
|
||||
+ "63834241aced7884c2544af1a3452e01/vr180/yi_giraffes.vr.mp4",
|
||||
SPHERICAL_STEREO_MODE_TOP_BOTTOM),
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.sample_chooser_activity);
|
||||
ListView sampleListView = findViewById(R.id.sample_list);
|
||||
sampleListView.setAdapter(
|
||||
new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, samples));
|
||||
sampleListView.setOnItemClickListener(
|
||||
(parent, view, position, id) ->
|
||||
startActivity(
|
||||
samples[position].buildIntent(/* context= */ SampleChooserActivity.this)));
|
||||
}
|
||||
|
||||
private static final class Sample {
|
||||
public final String name;
|
||||
public final String uri;
|
||||
public final String extension;
|
||||
public final String sphericalStereoMode;
|
||||
|
||||
public Sample(String name, String uri, String sphericalStereoMode) {
|
||||
this(name, uri, sphericalStereoMode, null);
|
||||
}
|
||||
|
||||
public Sample(String name, String uri, String sphericalStereoMode, String extension) {
|
||||
this.name = name;
|
||||
this.uri = uri;
|
||||
this.extension = extension;
|
||||
this.sphericalStereoMode = sphericalStereoMode;
|
||||
}
|
||||
|
||||
public Intent buildIntent(Context context) {
|
||||
Intent intent = new Intent(context, PlayerActivity.class);
|
||||
return intent
|
||||
.setData(Uri.parse(uri))
|
||||
.putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
|
||||
.putExtra(PlayerActivity.SPHERICAL_STEREO_MODE_EXTRA, sphericalStereoMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
25
demos/gvr/src/main/res/layout/sample_chooser_activity.xml
Normal file
25
demos/gvr/src/main/res/layout/sample_chooser_activity.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ListView android:id="@+id/sample_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
BIN
demos/gvr/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
demos/gvr/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
demos/gvr/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
demos/gvr/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
demos/gvr/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
demos/gvr/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
demos/gvr/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
demos/gvr/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
demos/gvr/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
demos/gvr/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
28
demos/gvr/src/main/res/values/strings.xml
Normal file
28
demos/gvr/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2019 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<string name="application_name">ExoPlayer VR Demo</string>
|
||||
|
||||
<string name="error_cleartext_not_permitted">Cleartext traffic not permitted</string>
|
||||
|
||||
<string name="error_unrecognized_stereo_mode">Unrecognized stereo mode</string>
|
||||
|
||||
<string name="error_unsupported_video">Media includes video tracks, but none are playable by this device</string>
|
||||
|
||||
<string name="error_unsupported_audio">Media includes audio tracks, but none are playable by this device</string>
|
||||
|
||||
</resources>
|
@ -50,7 +50,10 @@ import com.google.vr.sdk.controller.ControllerManager;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/** Base activity for VR 360 video playback. */
|
||||
/**
|
||||
* Base activity for VR 360 video playback. Before starting the video playback a player needs to be
|
||||
* set using {@link #setPlayer(Player)}.
|
||||
*/
|
||||
public abstract class GvrPlayerActivity extends GvrActivity {
|
||||
|
||||
private static final int EXIT_FROM_VR_REQUEST_CODE = 42;
|
||||
|
@ -21,10 +21,12 @@ if (gradle.ext.has('exoplayerModulePrefix')) {
|
||||
include modulePrefix + 'demo'
|
||||
include modulePrefix + 'demo-cast'
|
||||
include modulePrefix + 'demo-ima'
|
||||
include modulePrefix + 'demo-gvr'
|
||||
include modulePrefix + 'playbacktests'
|
||||
project(modulePrefix + 'demo').projectDir = new File(rootDir, 'demos/main')
|
||||
project(modulePrefix + 'demo-cast').projectDir = new File(rootDir, 'demos/cast')
|
||||
project(modulePrefix + 'demo-ima').projectDir = new File(rootDir, 'demos/ima')
|
||||
project(modulePrefix + 'demo-gvr').projectDir = new File(rootDir, 'demos/gvr')
|
||||
project(modulePrefix + 'playbacktests').projectDir = new File(rootDir, 'playbacktests')
|
||||
|
||||
apply from: 'core_settings.gradle'
|
||||
|
Loading…
x
Reference in New Issue
Block a user