mirror of
https://github.com/samsonjs/media.git
synced 2026-04-19 13:35:47 +00:00
Add demo app for WebM Native Extensions
Add a demo app that can be used as a reference for how to use the native VP9 and Opus Extensions.
This commit is contained in:
parent
7113d2ab6f
commit
10070a2d93
22 changed files with 1066 additions and 0 deletions
5
demo_misc/webm_sw_decoder/README.md
Normal file
5
demo_misc/webm_sw_decoder/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# WebM (VP9/Opus) Software Decoder Demo #
|
||||
|
||||
A demo app that shows how to use the ExoPlayer [VP9](../../extensions/vp9) and [Opus](../../extensions/opus) Extensions to enable VP9 and Opus playback in your app by bundling native libraries along with it.
|
||||
|
||||
The demo app depends on the VP9 and Opus Extensions being configured built correctly.
|
||||
40
demo_misc/webm_sw_decoder/build.gradle
Normal file
40
demo_misc/webm_sw_decoder/build.gradle
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2014 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 plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 21
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':library')
|
||||
compile project(':opus-extension')
|
||||
compile project(':vp9-extension')
|
||||
}
|
||||
9
demo_misc/webm_sw_decoder/src/main/.classpath
Normal file
9
demo_misc/webm_sw_decoder/src/main/.classpath
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="src" path="java"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
33
demo_misc/webm_sw_decoder/src/main/.project
Normal file
33
demo_misc/webm_sw_decoder/src/main/.project
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ExoPlayerExtWebMDemo</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
55
demo_misc/webm_sw_decoder/src/main/AndroidManifest.xml
Normal file
55
demo_misc/webm_sw_decoder/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.exoplayer.demo.webm"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:theme="@style/RootTheme">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
||||
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher">
|
||||
|
||||
<activity android:name="com.google.android.exoplayer.demo.webm.SampleChooserActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboardHidden">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.google.android.exoplayer.demo.webm.VideoPlayer"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/PlayerTheme"/>
|
||||
|
||||
<activity android:name="com.google.android.exoplayer.demo.webm.FilePickerActivity"
|
||||
android:theme="@android:style/Theme.Dialog"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.exoplayer.demo.webm;
|
||||
|
||||
import com.google.android.exoplayer.DefaultLoadControl;
|
||||
import com.google.android.exoplayer.LoadControl;
|
||||
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.TrackRenderer;
|
||||
import com.google.android.exoplayer.chunk.ChunkSampleSource;
|
||||
import com.google.android.exoplayer.chunk.ChunkSource;
|
||||
import com.google.android.exoplayer.chunk.FormatEvaluator;
|
||||
import com.google.android.exoplayer.chunk.FormatEvaluator.AdaptiveEvaluator;
|
||||
import com.google.android.exoplayer.chunk.MultiTrackChunkSource;
|
||||
import com.google.android.exoplayer.dash.DashChunkSource;
|
||||
import com.google.android.exoplayer.dash.mpd.AdaptationSet;
|
||||
import com.google.android.exoplayer.dash.mpd.MediaPresentationDescription;
|
||||
import com.google.android.exoplayer.dash.mpd.MediaPresentationDescriptionParser;
|
||||
import com.google.android.exoplayer.dash.mpd.Period;
|
||||
import com.google.android.exoplayer.dash.mpd.Representation;
|
||||
import com.google.android.exoplayer.ext.opus.LibopusAudioTrackRenderer;
|
||||
import com.google.android.exoplayer.ext.vp9.LibvpxVideoTrackRenderer;
|
||||
import com.google.android.exoplayer.upstream.BufferPool;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DefaultBandwidthMeter;
|
||||
import com.google.android.exoplayer.upstream.UriDataSource;
|
||||
import com.google.android.exoplayer.util.ManifestFetcher;
|
||||
import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Helper class that parses the manifest and builds the track renderers.
|
||||
*/
|
||||
public class DashRendererBuilder implements ManifestCallback<MediaPresentationDescription> {
|
||||
|
||||
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
|
||||
private static final int VIDEO_BUFFER_SEGMENTS = 200;
|
||||
private static final int AUDIO_BUFFER_SEGMENTS = 60;
|
||||
|
||||
private String manifestUrl;
|
||||
private String userAgent;
|
||||
private VideoPlayer player;
|
||||
|
||||
public DashRendererBuilder(String manifestUrl, String userAgent, VideoPlayer player) {
|
||||
this.manifestUrl = manifestUrl;
|
||||
this.userAgent = userAgent;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void build() {
|
||||
MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
|
||||
ManifestFetcher<MediaPresentationDescription> manifestFetcher =
|
||||
new ManifestFetcher<MediaPresentationDescription>(parser, null, manifestUrl, userAgent);
|
||||
manifestFetcher.singleLoad(player.getMainHandler().getLooper(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onManifestError(String contentId, IOException e) {
|
||||
// TODO: do something meaningful here.
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onManifest(String contentId, MediaPresentationDescription manifest) {
|
||||
LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE));
|
||||
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(null, null);
|
||||
|
||||
// Obtain Representations for playback.
|
||||
ArrayList<Representation> audioRepresentationsList = new ArrayList<Representation>();
|
||||
ArrayList<Representation> videoRepresentationsList = new ArrayList<Representation>();
|
||||
Period period = manifest.periods.get(0);
|
||||
for (int i = 0; i < period.adaptationSets.size(); i++) {
|
||||
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
||||
int adaptationSetType = adaptationSet.type;
|
||||
for (int j = 0; j < adaptationSet.representations.size(); j++) {
|
||||
Representation representation = adaptationSet.representations.get(j);
|
||||
if (adaptationSetType == AdaptationSet.TYPE_AUDIO) {
|
||||
audioRepresentationsList.add(representation);
|
||||
} else if (adaptationSetType == AdaptationSet.TYPE_VIDEO) {
|
||||
videoRepresentationsList.add(representation);
|
||||
}
|
||||
}
|
||||
}
|
||||
Representation[] videoRepresentations = new Representation[videoRepresentationsList.size()];
|
||||
videoRepresentationsList.toArray(videoRepresentations);
|
||||
|
||||
// Build the video renderer.
|
||||
LibvpxVideoTrackRenderer videoRenderer = null;
|
||||
if (!videoRepresentationsList.isEmpty()) {
|
||||
DataSource videoDataSource = new UriDataSource(userAgent, bandwidthMeter);
|
||||
ChunkSource videoChunkSource;
|
||||
String mimeType = videoRepresentations[0].format.mimeType;
|
||||
if (mimeType.equals(MimeTypes.VIDEO_WEBM)) {
|
||||
videoChunkSource = new DashChunkSource(videoDataSource,
|
||||
new AdaptiveEvaluator(bandwidthMeter), videoRepresentations);
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected mime type: " + mimeType);
|
||||
}
|
||||
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
|
||||
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
|
||||
videoRenderer = new LibvpxVideoTrackRenderer(videoSampleSource,
|
||||
true, player.getMainHandler(), player, 50);
|
||||
}
|
||||
|
||||
// Build the audio renderer.
|
||||
MultiTrackChunkSource audioChunkSource = null;
|
||||
TrackRenderer audioRenderer = null;
|
||||
if (!audioRepresentationsList.isEmpty()) {
|
||||
DataSource audioDataSource = new UriDataSource(userAgent, bandwidthMeter);
|
||||
ChunkSource[] audioChunkSources = new ChunkSource[audioRepresentationsList.size()];
|
||||
FormatEvaluator audioEvaluator = new FormatEvaluator.FixedEvaluator();
|
||||
for (int i = 0; i < audioRepresentationsList.size(); i++) {
|
||||
Representation representation = audioRepresentationsList.get(i);
|
||||
audioChunkSources[i] = new DashChunkSource(audioDataSource,
|
||||
audioEvaluator, representation);
|
||||
}
|
||||
audioChunkSource = new MultiTrackChunkSource(audioChunkSources);
|
||||
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
|
||||
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true);
|
||||
if (manifestUrl.contains("opus")) { // TODO: Need a better logic here.
|
||||
audioRenderer = new LibopusAudioTrackRenderer(audioSampleSource);
|
||||
} else {
|
||||
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource);
|
||||
}
|
||||
}
|
||||
|
||||
TrackRenderer[] renderers = new TrackRenderer[(audioRenderer == null) ? 1 : 2];
|
||||
renderers[0] = videoRenderer;
|
||||
if (audioRenderer != null) {
|
||||
renderers[1] = audioRenderer;
|
||||
}
|
||||
player.onRenderersBuilt(renderers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.exoplayer.demo.webm;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple file picker.
|
||||
*/
|
||||
public class FilePickerActivity extends ListActivity {
|
||||
|
||||
public static final String FILENAME_EXTRA_ID = "filename";
|
||||
|
||||
private List<String> listItems;
|
||||
private List<File> itemPaths;
|
||||
private TextView currentPathView;
|
||||
private File root;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.file_picker_activity);
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
currentPathView = (TextView) findViewById(R.id.path);
|
||||
root = new File(Environment.getExternalStorageDirectory().getPath());
|
||||
setDirectory(root);
|
||||
}
|
||||
|
||||
private void setDirectory(File directory) {
|
||||
currentPathView.setText(getString(R.string.current_path, directory.getAbsolutePath()));
|
||||
listItems = new ArrayList<String>();
|
||||
itemPaths = new ArrayList<File>();
|
||||
File[] files = directory.listFiles();
|
||||
|
||||
if (!directory.getAbsolutePath().equals(root.getAbsolutePath())) {
|
||||
listItems.add(root.getAbsolutePath());
|
||||
itemPaths.add(root);
|
||||
listItems.add("../");
|
||||
itemPaths.add(new File(directory.getParent()));
|
||||
}
|
||||
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isHidden() && file.canRead()) {
|
||||
itemPaths.add(file);
|
||||
if (file.isDirectory()) {
|
||||
listItems.add(file.getName() + File.separator);
|
||||
} else {
|
||||
listItems.add(file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setListAdapter(new ArrayAdapter<String>(this, R.layout.rows, listItems));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
File file = itemPaths.get(position);
|
||||
if (file.isDirectory() && file.canRead()) {
|
||||
setDirectory(itemPaths.get(position));
|
||||
} else {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(FILENAME_EXTRA_ID, file.getAbsolutePath());
|
||||
setResult(Activity.RESULT_OK, intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.exoplayer.demo.webm;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* An activity for selecting from a number of samples.
|
||||
*/
|
||||
public class SampleChooserActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.sample_chooser_activity);
|
||||
|
||||
ListView sampleList = (ListView) findViewById(R.id.sample_list);
|
||||
final SampleAdapter sampleAdapter = new SampleAdapter(this);
|
||||
|
||||
sampleAdapter.add(new Header("Local VP9 Video only"));
|
||||
sampleAdapter.add(new Sample("S/W Color Conversion - upto 720p", false));
|
||||
sampleAdapter.add(new Sample("OpenGL", true));
|
||||
sampleAdapter.add(new Header("DASH - VP9 Only"));
|
||||
sampleAdapter.add(new Sample("Google Glass",
|
||||
"http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9.mpd"));
|
||||
sampleAdapter.add(new Header("DASH - VP9 and Opus"));
|
||||
sampleAdapter.add(new Sample("Google Glass",
|
||||
"http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9_opus.mpd"));
|
||||
sampleAdapter.add(new Header("DASH - VP9 and Vorbis"));
|
||||
sampleAdapter.add(new Sample("Google Glass",
|
||||
"http://demos.webmproject.org/dash/201410/vp9_glass/manifest_vp9_vorbis.mpd"));
|
||||
|
||||
sampleList.setAdapter(sampleAdapter);
|
||||
sampleList.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Object item = sampleAdapter.getItem(position);
|
||||
if (item instanceof Sample) {
|
||||
onSampleSelected((Sample) item);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onSampleSelected(Sample sample) {
|
||||
Intent playerIntent = new Intent(this, VideoPlayer.class)
|
||||
.putExtra(VideoPlayer.DASH_MANIFEST_URL_ID_EXTRA, sample.uri)
|
||||
.putExtra(VideoPlayer.USE_OPENGL_ID_EXTRA, sample.useOpenGL);
|
||||
startActivity(playerIntent);
|
||||
}
|
||||
|
||||
private static class SampleAdapter extends ArrayAdapter<Object> {
|
||||
|
||||
public SampleAdapter(Context context) {
|
||||
super(context, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view = convertView;
|
||||
if (view == null) {
|
||||
int layoutId = getItemViewType(position) == 1 ? android.R.layout.simple_list_item_1
|
||||
: R.layout.sample_chooser_inline_header;
|
||||
view = LayoutInflater.from(getContext()).inflate(layoutId, null, false);
|
||||
}
|
||||
Object item = getItem(position);
|
||||
String name = null;
|
||||
if (item instanceof Sample) {
|
||||
name = ((Sample) item).description;
|
||||
} else if (item instanceof Header) {
|
||||
name = ((Header) item).name;
|
||||
}
|
||||
((TextView) view).setText(name);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (getItem(position) instanceof Sample) ? 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Sample {
|
||||
|
||||
public final String description;
|
||||
public final String uri;
|
||||
public final boolean useOpenGL;
|
||||
|
||||
public Sample(String description, boolean useOpenGL) {
|
||||
this(description, null, useOpenGL);
|
||||
}
|
||||
|
||||
public Sample(String description, String uri) {
|
||||
this(description, uri, true); // always use OpenGL for DASH playbacks.
|
||||
}
|
||||
|
||||
public Sample(String description, String uri, boolean useOpenGL) {
|
||||
this.description = description;
|
||||
this.uri = uri;
|
||||
this.useOpenGL = useOpenGL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class Header {
|
||||
|
||||
public final String name;
|
||||
|
||||
public Header(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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.exoplayer.demo.webm;
|
||||
|
||||
import com.google.android.exoplayer.ExoPlaybackException;
|
||||
import com.google.android.exoplayer.ExoPlayer;
|
||||
import com.google.android.exoplayer.TrackRenderer;
|
||||
import com.google.android.exoplayer.VideoSurfaceView;
|
||||
import com.google.android.exoplayer.ext.vp9.LibvpxVideoTrackRenderer;
|
||||
import com.google.android.exoplayer.ext.vp9.VpxDecoderException;
|
||||
import com.google.android.exoplayer.ext.vp9.VpxVideoSurfaceView;
|
||||
import com.google.android.exoplayer.source.DefaultSampleSource;
|
||||
import com.google.android.exoplayer.source.FrameworkSampleExtractor;
|
||||
import com.google.android.exoplayer.util.PlayerControl;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.MediaController;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Sample player that shows how to use ExoPlayer Extensions to playback VP9 Video and Opus Audio.
|
||||
*/
|
||||
public class VideoPlayer extends Activity implements OnClickListener,
|
||||
LibvpxVideoTrackRenderer.EventListener, ExoPlayer.Listener {
|
||||
|
||||
public static final String DASH_MANIFEST_URL_ID_EXTRA = "manifest_url";
|
||||
public static final String USE_OPENGL_ID_EXTRA = "use_opengl";
|
||||
|
||||
private static final int FILE_PICKER_REQUEST = 1;
|
||||
|
||||
private boolean isDash;
|
||||
private String manifestUrl;
|
||||
private boolean useOpenGL;
|
||||
private String filename;
|
||||
|
||||
private ExoPlayer player;
|
||||
private Handler handler;
|
||||
private MediaController mediaController;
|
||||
private VideoSurfaceView videoSurfaceView;
|
||||
private VpxVideoSurfaceView vpxVideoSurfaceView;
|
||||
private TextView debugInfoView;
|
||||
private TextView playerStateView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Intent intent = getIntent();
|
||||
manifestUrl = intent.getStringExtra(DASH_MANIFEST_URL_ID_EXTRA);
|
||||
isDash = manifestUrl != null;
|
||||
useOpenGL = intent.getBooleanExtra(USE_OPENGL_ID_EXTRA, true);
|
||||
|
||||
handler = new Handler();
|
||||
|
||||
setContentView(R.layout.activity_video_player);
|
||||
View root = findViewById(R.id.root);
|
||||
root.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
toggleControlsVisibility();
|
||||
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
|
||||
view.performClick();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
mediaController = new MediaController(this);
|
||||
mediaController.setAnchorView(root);
|
||||
videoSurfaceView = (VideoSurfaceView) findViewById(R.id.surface_view);
|
||||
vpxVideoSurfaceView = (VpxVideoSurfaceView) findViewById(R.id.vpx_surface_view);
|
||||
debugInfoView = (TextView) findViewById(R.id.debug_info);
|
||||
playerStateView = (TextView) findViewById(R.id.player_state);
|
||||
|
||||
// Set the buttons' onclick listeners.
|
||||
((Button) findViewById(R.id.choose_file)).setOnClickListener(this);
|
||||
((Button) findViewById(R.id.play)).setOnClickListener(this);
|
||||
|
||||
// In case of DASH, start playback right away.
|
||||
if (isDash) {
|
||||
findViewById(R.id.buttons).setVisibility(View.GONE);
|
||||
((TextView) findViewById(R.id.filename)).setVisibility(View.GONE);
|
||||
startDashPlayback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
stopPlayback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()) {
|
||||
case R.id.choose_file:
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(this, FilePickerActivity.class);
|
||||
startActivityForResult(intent, FILE_PICKER_REQUEST);
|
||||
break;
|
||||
case R.id.play:
|
||||
startBasicPlayback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case FILE_PICKER_REQUEST:
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
filename = data.getStringExtra(FilePickerActivity.FILENAME_EXTRA_ID);
|
||||
((TextView) findViewById(R.id.filename)).setText(
|
||||
getString(R.string.current_path, filename));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void startBasicPlayback() {
|
||||
if (filename == null) {
|
||||
Toast.makeText(this, "Choose a file!", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
findViewById(R.id.buttons).setVisibility(View.GONE);
|
||||
player = ExoPlayer.Factory.newInstance(1);
|
||||
player.addListener(this);
|
||||
mediaController.setMediaPlayer(new PlayerControl(player));
|
||||
mediaController.setEnabled(true);
|
||||
Uri uri = Uri.fromFile(new File(filename));
|
||||
DefaultSampleSource sampleSource =
|
||||
new DefaultSampleSource(new FrameworkSampleExtractor(this, uri, null), 2);
|
||||
TrackRenderer videoRenderer =
|
||||
new LibvpxVideoTrackRenderer(sampleSource, true, handler, this, 50);
|
||||
if (useOpenGL) {
|
||||
player.sendMessage(videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_VPX_SURFACE_VIEW,
|
||||
vpxVideoSurfaceView);
|
||||
videoSurfaceView.setVisibility(View.GONE);
|
||||
} else {
|
||||
player.sendMessage(
|
||||
videoRenderer, LibvpxVideoTrackRenderer.MSG_SET_SURFACE,
|
||||
videoSurfaceView.getHolder().getSurface());
|
||||
vpxVideoSurfaceView.setVisibility(View.GONE);
|
||||
}
|
||||
player.prepare(videoRenderer);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
|
||||
private void startDashPlayback() {
|
||||
playerStateView.setText("Initializing");
|
||||
final String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like"
|
||||
+ " Gecko) Chrome/38.0.2125.104 Safari/537.36";
|
||||
DashRendererBuilder rendererBuilder = new DashRendererBuilder(manifestUrl, userAgent, this);
|
||||
rendererBuilder.build();
|
||||
}
|
||||
|
||||
public void onRenderersBuilt(TrackRenderer[] renderers) {
|
||||
videoSurfaceView.setVisibility(View.GONE);
|
||||
player = ExoPlayer.Factory.newInstance(renderers.length);
|
||||
player.addListener(this);
|
||||
mediaController.setMediaPlayer(new PlayerControl(player));
|
||||
mediaController.setEnabled(true);
|
||||
player.sendMessage(renderers[0], LibvpxVideoTrackRenderer.MSG_SET_VPX_SURFACE_VIEW,
|
||||
vpxVideoSurfaceView);
|
||||
player.prepare(renderers);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDroppedFrames(int count, long elapsed) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(int width, int height) {
|
||||
if (isDash || useOpenGL) {
|
||||
vpxVideoSurfaceView.setVideoWidthHeightRatio(height == 0 ? 1 : (width * 1.0f) / height);
|
||||
} else {
|
||||
videoSurfaceView.setVideoWidthHeightRatio(height == 0 ? 1 : (width * 1.0f) / height);
|
||||
}
|
||||
debugInfoView.setText("Video: " + width + " x " + height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawnToSurface(Surface surface) {
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDecoderError(VpxDecoderException e) {
|
||||
debugInfoView.setText("Libvpx decode failure. Giving up.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int state) {
|
||||
String playerState = "";
|
||||
switch (player.getPlaybackState()) {
|
||||
case ExoPlayer.STATE_BUFFERING:
|
||||
playerState = "buffering";
|
||||
break;
|
||||
case ExoPlayer.STATE_ENDED:
|
||||
playerState = "ended";
|
||||
break;
|
||||
case ExoPlayer.STATE_IDLE:
|
||||
playerState = "idle";
|
||||
break;
|
||||
case ExoPlayer.STATE_PREPARING:
|
||||
playerState = "preparing";
|
||||
break;
|
||||
case ExoPlayer.STATE_READY:
|
||||
playerState = "ready";
|
||||
break;
|
||||
}
|
||||
playerStateView.setText("Player State: " + playerState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException exception) {
|
||||
debugInfoView.setText("Exoplayer Playback error. Giving up.");
|
||||
// TODO: show a retry button here.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayWhenReadyCommitted() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
public Handler getMainHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
private void stopPlayback() {
|
||||
if (player != null) {
|
||||
player.stop();
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleControlsVisibility() {
|
||||
if (mediaController != null) {
|
||||
if (mediaController.isShowing()) {
|
||||
mediaController.hide();
|
||||
} else {
|
||||
mediaController.show(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
17
demo_misc/webm_sw_decoder/src/main/project.properties
Normal file
17
demo_misc/webm_sw_decoder/src/main/project.properties
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-19
|
||||
android.library.reference.1=../../../../library/src/main
|
||||
android.library.reference.2=../../../../extensions/opus/src/main
|
||||
android.library.reference.3=../../../../extensions/vp9/src/main
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:keepScreenOn="true">
|
||||
|
||||
<com.google.android.exoplayer.VideoSurfaceView
|
||||
android:id="@+id/surface_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center|center_vertical"/>
|
||||
|
||||
<com.google.android.exoplayer.ext.vp9.VpxVideoSurfaceView
|
||||
android:id="@+id/vpx_surface_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center|center_vertical"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="#88000000">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/choose_file"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/choose_file"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/play"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/play"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/filename"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/player_state"
|
||||
android:paddingRight="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/debug_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/path"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
20
demo_misc/webm_sw_decoder/src/main/res/layout/rows.xml
Normal file
20
demo_misc/webm_sw_decoder/src/main/res/layout/rows.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/rowtext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="25sp"/>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2014 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>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp"
|
||||
android:padding="8dp"
|
||||
android:focusable="true"
|
||||
android:background="#339999FF"/>
|
||||
26
demo_misc/webm_sw_decoder/src/main/res/values/strings.xml
Normal file
26
demo_misc/webm_sw_decoder/src/main/res/values/strings.xml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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="app_name">WebM ExoPlayer Demo</string>
|
||||
<string name="choose_file">Choose File</string>
|
||||
<string name="play">Play</string>
|
||||
<string name="current_path">
|
||||
Path: <xliff:g id="path" example="/sdcard/test.webm">%1$s</xliff:g>
|
||||
</string>
|
||||
|
||||
</resources>
|
||||
26
demo_misc/webm_sw_decoder/src/main/res/values/styles.xml
Normal file
26
demo_misc/webm_sw_decoder/src/main/res/values/styles.xml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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="RootTheme" parent="android:Theme.Holo"/>
|
||||
|
||||
<style name="PlayerTheme" parent="@style/RootTheme">
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
Loading…
Reference in a new issue