Publish SurfaceControl demo
Issue: #677 Issue: #5428 PiperOrigin-RevId: 270466031
This commit is contained in:
parent
18b9304f25
commit
258fff422a
@ -13,7 +13,7 @@
|
||||
* Bypass sniffing in `ProgressiveMediaPeriod` in case a single extractor is
|
||||
provided ([#6325](https://github.com/google/ExoPlayer/issues/6325)).
|
||||
* Surface information provided by methods `isHardwareAccelerated`,
|
||||
`isSoftwareOnly` and `isVendor` added in Android Q in `MediaCodecInfo` class
|
||||
`isSoftwareOnly` and `isVendor` added in Android 10 in `MediaCodecInfo` class
|
||||
([#5839](https://github.com/google/ExoPlayer/issues/5839)).
|
||||
* Update `DefaultTrackSelector` to apply a viewport constraint for the default
|
||||
display by default.
|
||||
@ -33,7 +33,7 @@
|
||||
`SourceInfoRefreshListener` anymore. Instead make it accessible through
|
||||
`Player.getCurrentManifest()` and `Timeline.Window.manifest`. Also rename
|
||||
`SourceInfoRefreshListener` to `MediaSourceCaller`.
|
||||
* Set `compileSdkVersion` to 29 to use Android Q APIs.
|
||||
* Set `compileSdkVersion` to 29 to use Android 10 APIs.
|
||||
* Add `enable` and `disable` methods to `MediaSource` to improve resource
|
||||
management in playlists.
|
||||
* Text selection logic:
|
||||
@ -59,6 +59,8 @@
|
||||
* Fix Dolby Vision fallback to AVC and HEVC.
|
||||
* Add top-level playlist API
|
||||
([#6161](https://github.com/google/ExoPlayer/issues/6161)).
|
||||
* Add demo app to show how to use the Android 10 `SurfaceControl` API with
|
||||
ExoPlayer ([#677](https://github.com/google/ExoPlayer/issues/677)).
|
||||
|
||||
### 2.10.5 (2019-09-20) ###
|
||||
|
||||
|
21
demos/surface/README.md
Normal file
21
demos/surface/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# ExoPlayer SurfaceControl demo
|
||||
|
||||
This app demonstrates how to use the [SurfaceControl][] API to redirect video
|
||||
output from ExoPlayer between different views or off-screen. `SurfaceControl`
|
||||
is new in Android 10, so the app requires `minSdkVersion` 29.
|
||||
|
||||
The app layout has a grid of `SurfaceViews`. Initially video is output to one
|
||||
of the views. Tap a `SurfaceView` to move video output to it. You can also tap
|
||||
the buttons at the top of the activity to move video output off-screen, to a
|
||||
full-screen `SurfaceView` or to a new activity.
|
||||
|
||||
When using `SurfaceControl`, the `MediaCodec` always has the same surface
|
||||
attached to it, which can be freely 'reparented' to any `SurfaceView` (or
|
||||
off-screen) without any interruptions to playback. This works better than
|
||||
calling `MediaCodec.setOutputSurface` to change the output surface of the codec
|
||||
because `MediaCodec` does not re-render its last frame when that method is
|
||||
called, and because you can move output off-screen easily (`setOutputSurface`
|
||||
can't take a `null` surface, so the player has to use a `DummySurface`, which
|
||||
doesn't handle protected output on all devices).
|
||||
|
||||
[SurfaceControl]: https://developer.android.com/reference/android/view/SurfaceControl
|
51
demos/surface/build.gradle
Normal file
51
demos/surface/build.gradle
Normal file
@ -0,0 +1,51 @@
|
||||
// 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 29
|
||||
targetSdkVersion 29
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
shrinkResources true
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt')
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
// This demo app does not have translations.
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(modulePrefix + 'library-core')
|
||||
implementation project(modulePrefix + 'library-ui')
|
||||
implementation project(modulePrefix + 'library-dash')
|
||||
implementation 'androidx.annotation:annotation:' + androidxAnnotationVersion
|
||||
}
|
41
demos/surface/src/main/AndroidManifest.xml
Normal file
41
demos/surface/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?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.surfacedemo">
|
||||
<uses-sdk/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/application_name">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.exoplayer.surfacedemo.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:scheme="http"/>
|
||||
<data android:scheme="https"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="asset"/>
|
||||
<data android:scheme="file"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.google.android.exoplayer2.surfacedemo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.GridLayout;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
|
||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
||||
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||
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.upstream.HttpDataSource;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.UUID;
|
||||
|
||||
/** Activity that demonstrates use of {@link SurfaceControl} with ExoPlayer. */
|
||||
public final class MainActivity extends Activity {
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
private static final String DEFAULT_MEDIA_URI =
|
||||
"https://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv";
|
||||
private static final String SURFACE_CONTROL_NAME = "surfacedemo";
|
||||
|
||||
private static final String ACTION_VIEW = "com.google.android.exoplayer.surfacedemo.action.VIEW";
|
||||
private static final String EXTENSION_EXTRA = "extension";
|
||||
private static final String DRM_SCHEME_EXTRA = "drm_scheme";
|
||||
private static final String DRM_LICENSE_URL_EXTRA = "drm_license_url";
|
||||
private static final String OWNER_EXTRA = "owner";
|
||||
|
||||
private boolean isOwner;
|
||||
private PlayerControlView playerControlView;
|
||||
private SurfaceView fullScreenView;
|
||||
private SurfaceView nonFullScreenView;
|
||||
@Nullable private SurfaceView currentOutputView;
|
||||
|
||||
private static SimpleExoPlayer player;
|
||||
private static FrameworkMediaDrm mediaDrm;
|
||||
private static SurfaceControl surfaceControl;
|
||||
private static Surface videoSurface;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_activity);
|
||||
playerControlView = findViewById(R.id.player_control_view);
|
||||
fullScreenView = findViewById(R.id.full_screen_view);
|
||||
fullScreenView.setOnClickListener(
|
||||
v -> {
|
||||
setCurrentOutputView(nonFullScreenView);
|
||||
fullScreenView.setVisibility(View.GONE);
|
||||
});
|
||||
attachSurfaceListener(fullScreenView);
|
||||
isOwner = getIntent().getBooleanExtra(OWNER_EXTRA, /* defaultValue= */ true);
|
||||
GridLayout gridLayout = findViewById(R.id.grid_layout);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
View view;
|
||||
if (i == 0) {
|
||||
Button button = new Button(/* context= */ this);
|
||||
view = button;
|
||||
button.setText(getString(R.string.no_output_label));
|
||||
button.setOnClickListener(v -> reparent(null));
|
||||
} else if (i == 1) {
|
||||
Button button = new Button(/* context= */ this);
|
||||
view = button;
|
||||
button.setText(getString(R.string.full_screen_label));
|
||||
button.setOnClickListener(
|
||||
v -> {
|
||||
setCurrentOutputView(fullScreenView);
|
||||
fullScreenView.setVisibility(View.VISIBLE);
|
||||
});
|
||||
} else if (i == 2) {
|
||||
Button button = new Button(/* context= */ this);
|
||||
view = button;
|
||||
button.setText(getString(R.string.new_activity_label));
|
||||
button.setOnClickListener(
|
||||
v -> {
|
||||
startActivity(
|
||||
new Intent(MainActivity.this, MainActivity.class)
|
||||
.putExtra(OWNER_EXTRA, /* value= */ false));
|
||||
});
|
||||
} else {
|
||||
SurfaceView surfaceView = new SurfaceView(this);
|
||||
view = surfaceView;
|
||||
attachSurfaceListener(surfaceView);
|
||||
surfaceView.setOnClickListener(
|
||||
v -> {
|
||||
setCurrentOutputView(surfaceView);
|
||||
nonFullScreenView = surfaceView;
|
||||
});
|
||||
if (nonFullScreenView == null) {
|
||||
nonFullScreenView = surfaceView;
|
||||
}
|
||||
}
|
||||
gridLayout.addView(view);
|
||||
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
|
||||
layoutParams.width = 400;
|
||||
layoutParams.height = 400;
|
||||
layoutParams.columnSpec = GridLayout.spec(i % 3);
|
||||
layoutParams.rowSpec = GridLayout.spec(i / 3);
|
||||
layoutParams.bottomMargin = 10;
|
||||
layoutParams.leftMargin = 10;
|
||||
layoutParams.topMargin = 10;
|
||||
layoutParams.rightMargin = 10;
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (isOwner && player == null) {
|
||||
initializePlayer();
|
||||
}
|
||||
|
||||
setCurrentOutputView(nonFullScreenView);
|
||||
playerControlView.setPlayer(player);
|
||||
playerControlView.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
playerControlView.setPlayer(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (isOwner && isFinishing()) {
|
||||
if (surfaceControl != null) {
|
||||
surfaceControl.release();
|
||||
surfaceControl = null;
|
||||
videoSurface.release();
|
||||
}
|
||||
if (player != null) {
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
if (mediaDrm != null) {
|
||||
mediaDrm.release();
|
||||
mediaDrm = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initializePlayer() {
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri uri = ACTION_VIEW.equals(action) ? intent.getData() : Uri.parse(DEFAULT_MEDIA_URI);
|
||||
String userAgent = Util.getUserAgent(this, getString(R.string.application_name));
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
||||
DrmSessionManager.getDummyDrmSessionManager();
|
||||
if (intent.hasExtra(DRM_SCHEME_EXTRA)) {
|
||||
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL_EXTRA);
|
||||
try {
|
||||
UUID drmSchemeUuid = Util.getDrmUuid(intent.getStringExtra(DRM_SCHEME_EXTRA));
|
||||
HttpDataSource.Factory licenseDataSourceFactory =
|
||||
new DefaultHttpDataSourceFactory(userAgent);
|
||||
HttpMediaDrmCallback drmCallback =
|
||||
new HttpMediaDrmCallback(drmLicenseUrl, licenseDataSourceFactory);
|
||||
mediaDrm = FrameworkMediaDrm.newInstance(drmSchemeUuid);
|
||||
drmSessionManager =
|
||||
new DefaultDrmSessionManager<>(
|
||||
drmSchemeUuid, mediaDrm, drmCallback, /* optionalKeyRequestParameters= */ null);
|
||||
} catch (UnsupportedDrmException e) {
|
||||
Log.e(TAG, "Unsupported DRM scheme", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DataSource.Factory dataSourceFactory =
|
||||
new DefaultDataSourceFactory(
|
||||
this, Util.getUserAgent(this, getString(R.string.application_name)));
|
||||
MediaSource mediaSource;
|
||||
@C.ContentType int type = Util.inferContentType(uri, intent.getStringExtra(EXTENSION_EXTRA));
|
||||
if (type == C.TYPE_DASH) {
|
||||
mediaSource =
|
||||
new DashMediaSource.Factory(dataSourceFactory)
|
||||
.setDrmSessionManager(drmSessionManager)
|
||||
.createMediaSource(uri);
|
||||
} else if (type == C.TYPE_OTHER) {
|
||||
mediaSource =
|
||||
new ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||
.setDrmSessionManager(drmSessionManager)
|
||||
.createMediaSource(uri);
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
player = new SimpleExoPlayer.Builder(getApplicationContext()).build();
|
||||
player.setMediaItem(mediaSource);
|
||||
player.prepare();
|
||||
player.setPlayWhenReady(true);
|
||||
player.setRepeatMode(Player.REPEAT_MODE_ALL);
|
||||
|
||||
surfaceControl =
|
||||
new SurfaceControl.Builder()
|
||||
.setName(SURFACE_CONTROL_NAME)
|
||||
.setBufferSize(/* width= */ 0, /* height= */ 0)
|
||||
.build();
|
||||
videoSurface = new Surface(surfaceControl);
|
||||
player.setVideoSurface(videoSurface);
|
||||
}
|
||||
|
||||
private void setCurrentOutputView(@Nullable SurfaceView surfaceView) {
|
||||
currentOutputView = surfaceView;
|
||||
if (surfaceView != null && surfaceView.getHolder().getSurface() != null) {
|
||||
reparent(surfaceView);
|
||||
}
|
||||
}
|
||||
|
||||
private void attachSurfaceListener(SurfaceView surfaceView) {
|
||||
surfaceView
|
||||
.getHolder()
|
||||
.addCallback(
|
||||
new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||
if (surfaceView == currentOutputView) {
|
||||
reparent(surfaceView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(
|
||||
SurfaceHolder surfaceHolder, int format, int width, int height) {}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {}
|
||||
});
|
||||
}
|
||||
|
||||
private void reparent(@Nullable SurfaceView surfaceView) {
|
||||
if (surfaceView == null) {
|
||||
new SurfaceControl.Transaction()
|
||||
.reparent(surfaceControl, /* newParent= */ null)
|
||||
.setBufferSize(surfaceControl, /* w= */ 0, /* h= */ 0)
|
||||
.setVisibility(surfaceControl, /* visible= */ false)
|
||||
.apply();
|
||||
} else {
|
||||
SurfaceControl newParentSurfaceControl = surfaceView.getSurfaceControl();
|
||||
new SurfaceControl.Transaction()
|
||||
.reparent(surfaceControl, newParentSurfaceControl)
|
||||
.setBufferSize(surfaceControl, surfaceView.getWidth(), surfaceView.getHeight())
|
||||
.setVisibility(surfaceControl, /* visible= */ true)
|
||||
.apply();
|
||||
}
|
||||
}
|
||||
}
|
43
demos/surface/src/main/res/layout/main_activity.xml
Normal file
43
demos/surface/src/main/res/layout/main_activity.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?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.
|
||||
-->
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true">
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/grid_layout"
|
||||
android:columnCount="3" />
|
||||
|
||||
<SurfaceView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/full_screen_view"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.google.android.exoplayer2.ui.PlayerControlView
|
||||
android:id="@+id/player_control_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:show_timeout="0" />
|
||||
|
||||
</FrameLayout>
|
||||
|
BIN
demos/surface/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
demos/surface/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
demos/surface/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
demos/surface/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
demos/surface/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
demos/surface/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
demos/surface/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
demos/surface/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
demos/surface/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
demos/surface/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
23
demos/surface/src/main/res/values/strings.xml
Normal file
23
demos/surface/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?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>
|
||||
|
||||
<string name="application_name">ExoPlayer SurfaceControl demo</string>
|
||||
<string name="no_output_label">No output</string>
|
||||
<string name="full_screen_label">Full screen</string>
|
||||
<string name="new_activity_label">New activity</string>
|
||||
|
||||
</resources>
|
23
demos/surface/src/main/res/values/styles.xml
Normal file
23
demos/surface/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?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:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="PlayerTheme" parent="android:Theme.Holo">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -22,11 +22,13 @@ include modulePrefix + 'demo'
|
||||
include modulePrefix + 'demo-cast'
|
||||
include modulePrefix + 'demo-ima'
|
||||
include modulePrefix + 'demo-gvr'
|
||||
include modulePrefix + 'demo-surface'
|
||||
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 + 'demo-surface').projectDir = new File(rootDir, 'demos/surface')
|
||||
project(modulePrefix + 'playbacktests').projectDir = new File(rootDir, 'playbacktests')
|
||||
|
||||
apply from: 'core_settings.gradle'
|
||||
|
Loading…
x
Reference in New Issue
Block a user