Commit d9794696 by Oliver Woodman

Merge branch 'dev-v2' into release-v2

parents 65770131 b4fb8c3c
Showing with 543 additions and 214 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

......@@ -30,17 +30,39 @@ repositories {
}
```
Next, include the following in your module's `build.gradle` file:
Next add a gradle compile dependency to the `build.gradle` file of your app
module. The following will add a dependency to the full ExoPlayer library:
```gradle
compile 'com.google.android.exoplayer:exoplayer:rX.X.X'
compile 'com.google.android.exoplayer:exoplayer:r2.X.X'
```
where `rX.X.X` is the your preferred version. For the latest version, see the
project's [Releases][]. For more details, see the project on [Bintray][].
where `r2.X.X` is your preferred version. Alternatively, you can depend on only
the library modules that you actually need. For example the following will add
dependencies on the Core, DASH and UI library modules, as might be required for
an app that plays DASH content:
[Releases]: https://github.com/google/ExoPlayer/releases
[Bintray]: https://bintray.com/google/exoplayer/exoplayer/view
```gradle
compile 'com.google.android.exoplayer:exoplayer-core:r2.X.X'
compile 'com.google.android.exoplayer:exoplayer-dash:r2.X.X'
compile 'com.google.android.exoplayer:exoplayer-ui:r2.X.X'
```
The available modules are listed below. Adding a dependency to the full
ExoPlayer library is equivalent to adding dependencies on all of the modules
individually.
* `exoplayer-core`: Core functionality (required).
* `exoplayer-dash`: Support for DASH content.
* `exoplayer-hls`: Support for HLS content.
* `exoplayer-smoothstreaming`: Support for SmoothStreaming content.
* `exoplayer-ui`: UI components and resources for use with ExoPlayer.
For more details, see the project on [Bintray][]. For information about the
latest versions, see the [Release notes][].
[Bintray]: https://bintray.com/google/exoplayer
[Release notes]: https://github.com/google/ExoPlayer/blob/release-v2/RELEASENOTES.md
## Developing ExoPlayer ##
......
# Release notes #
### r2.4.0 ###
* New modular library structure. You can read more about depending on individual
library modules
[here](https://medium.com/google-exoplayer/exoplayers-new-modular-structure-a916c0874907).
* Variable speed playback support on API level 16+. You can read more about
changing the playback speed
[here](https://medium.com/google-exoplayer/variable-speed-playback-with-exoplayer-e6e6a71e0343)
([#26](https://github.com/google/ExoPlayer/issues/26)).
* New time bar view, including support for displaying ad break markers.
* Support DVB subtitles in MPEG-TS and MKV.
* Support adaptive playback for audio only DASH, HLS and SmoothStreaming
([#1975](https://github.com/google/ExoPlayer/issues/1975)).
* Support for setting extractor flags on DefaultExtractorsFactory
([#2657](https://github.com/google/ExoPlayer/issues/2657)).
* Support injecting custom renderers into SimpleExoPlayer using a new
RenderersFactory interface.
* Correctly set ExoPlayer's internal thread priority to `THREAD_PRIORITY_AUDIO`.
* TX3G: Support styling and positioning.
* FLV:
* Support MP3 in FLV.
* Skip unhandled metadata rather than failing
([#2634](https://github.com/google/ExoPlayer/issues/2634)).
* Fix potential OutOfMemory errors.
* ID3: Better handle malformed ID3 data
([#2604](https://github.com/google/ExoPlayer/issues/2604),
[#2663](https://github.com/google/ExoPlayer/issues/2663)).
* FFmpeg extension: Fixed build instructions
([#2561](https://github.com/google/ExoPlayer/issues/2561)).
* VP9 extension: Reduced binary size.
* FLAC extension: Enabled 64 bit targets.
* Misc bugfixes.
### r2.3.1 ###
* Fix NPE enabling WebVTT subtitles in DASH streams
......@@ -26,9 +59,8 @@
* HLS improvements:
* Respect initial track selection
([#2353](https://github.com/google/ExoPlayer/issues/2353)).
* Reduced frequency of media playlist requests when playback position is
close to the live edge
([#2548](https://github.com/google/ExoPlayer/issues/2548)).
* Reduced frequency of media playlist requests when playback position is close
to the live edge ([#2548](https://github.com/google/ExoPlayer/issues/2548)).
* Exposed the master playlist through ExoPlayer.getCurrentManifest()
([#2537](https://github.com/google/ExoPlayer/issues/2537)).
* Support CLOSED-CAPTIONS #EXT-X-MEDIA type
......@@ -237,25 +269,25 @@ some of the motivations behind ExoPlayer 2.x
structure and class names have also been sanitized. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-new-package-and-class-names-ef8e1d9ba96f#.lv8sd4nez).
* Key architectural changes:
* Late binding between rendering and media source components. Allows the
same rendering components to be re-used from one playback to another.
Enables features such as gapless playback through playlists and DASH
multi-period support.
* Late binding between rendering and media source components. Allows the same
rendering components to be re-used from one playback to another. Enables
features such as gapless playback through playlists and DASH multi-period
support.
* Improved track selection design. More details can be found
[here](https://medium.com/google-exoplayer/exoplayer-2-x-track-selection-2b62ff712cc9#.n00zo76b6).
* LoadControl now used to control buffering and loading across all playback
types.
* Media source components given additional structure. A new MediaSource
class has been introduced. MediaSources expose Timelines that describe the
media they expose, and can consist of multiple MediaPeriods. This enables
features such as seeking in live playbacks and DASH multi-period support.
* Responsibility for loading the initial DASH/SmoothStreaming/HLS manifest
is promoted to the corresponding MediaSource components and is no longer
the application's responsibility.
* Media source components given additional structure. A new MediaSource class
has been introduced. MediaSources expose Timelines that describe the media
they expose, and can consist of multiple MediaPeriods. This enables features
such as seeking in live playbacks and DASH multi-period support.
* Responsibility for loading the initial DASH/SmoothStreaming/HLS manifest is
promoted to the corresponding MediaSource components and is no longer the
application's responsibility.
* Higher level abstractions such as SimpleExoPlayer have been added to the
library. These make the library easier to use for common use cases. The
demo app is halved in size as a result, whilst at the same time gaining
more functionality. Read more
library. These make the library easier to use for common use cases. The demo
app is halved in size as a result, whilst at the same time gaining more
functionality. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-improved-demo-app-d97171aaaaa1).
* Enhanced library support for implementing audio extensions. Read more
[here](https://medium.com/google-exoplayer/exoplayer-2-x-new-audio-features-cfb26c2883a#.ua75vu4s3).
......@@ -274,20 +306,19 @@ some of the motivations behind ExoPlayer 2.x
[here](https://medium.com/google-exoplayer/exoplayer-2-x-mediasource-composition-6c285fcbca1f#.zfha8qupz).
* Looping support (see above)
([#490](https://github.com/google/ExoPlayer/issues/490)).
* Ability to query information about all tracks in a piece of media
(including those not supported by the device)
* Ability to query information about all tracks in a piece of media (including
those not supported by the device)
([#1121](https://github.com/google/ExoPlayer/issues/1121)).
* Improved player controls.
* Support for PSSH in fMP4 moof atoms
([#1143](https://github.com/google/ExoPlayer/issues/1143)).
* Support for Opus in Ogg
([#1447](https://github.com/google/ExoPlayer/issues/1447)).
* CacheDataSource support for standalone media file playbacks (mp3, mp4
etc).
* CacheDataSource support for standalone media file playbacks (mp3, mp4 etc).
* FFMPEG extension (for audio only).
* Key bug fixes:
* Removed unnecessary secondary requests when playing standalone media
files ([#1041](https://github.com/google/ExoPlayer/issues/1041)).
* Removed unnecessary secondary requests when playing standalone media files
([#1041](https://github.com/google/ExoPlayer/issues/1041)).
* Fixed playback of video only (i.e. no audio) live streams
([#758](https://github.com/google/ExoPlayer/issues/758)).
* Fixed silent failure when media buffer is too small
......@@ -304,6 +335,12 @@ in all V2 releases. This cannot be assumed for changes in r1.5.12 and later,
however it can be assumed that all such changes are included in the most recent
V2 release.
### r1.5.16 ###
* VP9 extension: Reduced binary size.
* FLAC extension: Enabled 64 bit targets and fixed proguard config.
* Misc bugfixes.
### r1.5.15 ###
* SmoothStreaming: Fixed handling of start_time placeholder
......
......@@ -19,8 +19,15 @@ buildscript {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.novoda:bintray-release:0.4.0'
}
// Workaround for the following test coverage issue. Remove when fixed:
// https://code.google.com/p/android/issues/detail?id=226070
configurations.all {
resolutionStrategy {
force 'org.jacoco:org.jacoco.report:0.7.4.201502262128'
force 'org.jacoco:org.jacoco.core:0.7.4.201502262128'
}
}
}
allprojects {
repositories {
jcenter()
......@@ -30,16 +37,26 @@ allprojects {
// components provided by the library may be of use on older devices.
// However, please note that the core media playback functionality
// provided by the library requires API level 16 or greater.
minSdkVersion=9
compileSdkVersion=25
targetSdkVersion=25
buildToolsVersion='25'
minSdkVersion = 9
compileSdkVersion = 25
targetSdkVersion = 25
buildToolsVersion = '25'
testSupportLibraryVersion = '0.5'
supportLibraryVersion = '25.3.1'
dexmakerVersion = '1.2'
mockitoVersion = '1.9.5'
releaseRepoName = getBintrayRepo()
releaseUserOrg = 'google'
releaseGroupId = 'com.google.android.exoplayer'
releaseVersion = 'r2.3.1'
releaseVersion = 'r2.4.0'
releaseWebsite = 'https://github.com/google/ExoPlayer'
}
if (it.hasProperty('externalBuildDir')) {
if (!new File(externalBuildDir).isAbsolute()) {
externalBuildDir = new File(rootDir, externalBuildDir)
}
buildDir = "${externalBuildDir}/${project.name}"
}
}
def getBintrayRepo() {
......@@ -47,3 +64,5 @@ def getBintrayRepo() {
property('publicRepo').toBoolean()
return publicRepo ? 'exoplayer' : 'exoplayer-test'
}
apply from: 'javadoc_combined.gradle'
......@@ -45,7 +45,11 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
compile project(':library-dash')
compile project(':library-hls')
compile project(':library-smoothstreaming')
compile project(':library-ui')
withExtensionsCompile project(path: ':extension-ffmpeg')
withExtensionsCompile project(path: ':extension-flac')
withExtensionsCompile project(path: ':extension-opus')
......
......@@ -16,8 +16,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.exoplayer2.demo"
android:versionCode="2301"
android:versionName="2.3.1">
android:versionCode="2400"
android:versionName="2.4.0">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
......
......@@ -416,13 +416,16 @@
]
},
{
"name": "Audio -> Video",
"name": "Audio -> Video -> Audio",
"playlist": [
{
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
},
{
"uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv"
},
{
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
}
]
},
......
/*
* Copyright (C) 2017 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.demo;
import android.text.TextUtils;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Locale;
/**
* Utility methods for demo application.
*/
/*package*/ final class DemoUtil {
/**
* Builds a track name for display.
*
* @param format {@link Format} of the track.
* @return a generated name specific to the track.
*/
public static String buildTrackName(Format format) {
String trackName;
if (MimeTypes.isVideo(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildResolutionString(format), buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else if (MimeTypes.isAudio(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildLanguageString(format), buildAudioPropertyString(format)),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(buildLanguageString(format),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
}
return trackName.length() == 0 ? "unknown" : trackName;
}
private static String buildResolutionString(Format format) {
return format.width == Format.NO_VALUE || format.height == Format.NO_VALUE
? "" : format.width + "x" + format.height;
}
private static String buildAudioPropertyString(Format format) {
return format.channelCount == Format.NO_VALUE || format.sampleRate == Format.NO_VALUE
? "" : format.channelCount + "ch, " + format.sampleRate + "Hz";
}
private static String buildLanguageString(Format format) {
return TextUtils.isEmpty(format.language) || "und".equals(format.language) ? ""
: format.language;
}
private static String buildBitrateString(Format format) {
return format.bitrate == Format.NO_VALUE ? ""
: String.format(Locale.US, "%.2fMbit", format.bitrate / 1000000f);
}
private static String joinWithSeparator(String first, String second) {
return first.length() == 0 ? second : (second.length() == 0 ? first : first + ", " + second);
}
private static String buildTrackIdString(Format format) {
return format.id == null ? "" : ("id:" + format.id);
}
private static String buildSampleMimeTypeString(Format format) {
return format.sampleMimeType == null ? "" : format.sampleMimeType;
}
private DemoUtil() {}
}
......@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
......@@ -100,6 +101,12 @@ import java.util.Locale;
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
Log.d(TAG, "playbackParameters " + String.format(
"[speed=%.2f, pitch=%.2f]", playbackParameters.speed, playbackParameters.pitch));
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
int periodCount = timeline.getPeriodCount();
int windowCount = timeline.getWindowCount();
......@@ -274,7 +281,7 @@ import java.util.Locale;
@Override
public void onRenderedFirstFrame(Surface surface) {
// Do nothing.
Log.d(TAG, "renderedFirstFrame [" + surface + "]");
}
// DefaultDrmSessionManager.EventListener
......
......@@ -21,6 +21,7 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
......@@ -30,10 +31,11 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
......@@ -111,6 +113,7 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
private TrackSelectionHelper trackSelectionHelper;
private DebugTextViewHelper debugViewHelper;
private boolean needRetrySource;
private TrackGroupArray lastSeenTrackGroupArray;
private boolean shouldAutoPlay;
private int resumeWindow;
......@@ -183,8 +186,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initializePlayer();
} else {
......@@ -250,17 +253,21 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
}
@SimpleExoPlayer.ExtensionRendererMode int extensionRendererMode =
@DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode =
((DemoApplication) getApplication()).useExtensionRenderers()
? (preferExtensionDecoders ? SimpleExoPlayer.EXTENSION_RENDERER_MODE_PREFER
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_ON)
: SimpleExoPlayer.EXTENSION_RENDERER_MODE_OFF;
? (preferExtensionDecoders ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
: DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(this,
drmSessionManager, extensionRendererMode);
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl(),
drmSessionManager, extensionRendererMode);
lastSeenTrackGroupArray = null;
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);
player.addListener(this);
eventLogger = new EventLogger(trackSelector);
......@@ -428,6 +435,11 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing.
}
......@@ -472,8 +484,10 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
}
@Override
@SuppressWarnings("ReferenceEquality")
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
updateButtonVisibilities();
if (trackGroups != lastSeenTrackGroupArray) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
if (mappedTrackInfo.getTrackTypeRendererSupport(C.TRACK_TYPE_VIDEO)
......@@ -485,6 +499,8 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
showToast(R.string.error_unsupported_audio);
}
}
lastSeenTrackGroupArray = trackGroups;
}
}
// User controls
......
......@@ -21,13 +21,11 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
......@@ -37,9 +35,7 @@ import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedT
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Arrays;
import java.util.Locale;
/**
* Helper class for displaying track selection dialogs.
......@@ -157,7 +153,7 @@ import java.util.Locale;
CheckedTextView trackView = (CheckedTextView) inflater.inflate(
trackViewLayoutId, root, false);
trackView.setBackgroundResource(selectableItemBackgroundResourceId);
trackView.setText(buildTrackName(group.getFormat(trackIndex)));
trackView.setText(DemoUtil.buildTrackName(group.getFormat(trackIndex)));
if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex)
== RendererCapabilities.FORMAT_HANDLED) {
trackView.setFocusable(true);
......@@ -296,57 +292,4 @@ import java.util.Locale;
return tracks;
}
// Track name construction.
private static String buildTrackName(Format format) {
String trackName;
if (MimeTypes.isVideo(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildResolutionString(format), buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else if (MimeTypes.isAudio(format.sampleMimeType)) {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(joinWithSeparator(
buildLanguageString(format), buildAudioPropertyString(format)),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
} else {
trackName = joinWithSeparator(joinWithSeparator(joinWithSeparator(buildLanguageString(format),
buildBitrateString(format)), buildTrackIdString(format)),
buildSampleMimeTypeString(format));
}
return trackName.length() == 0 ? "unknown" : trackName;
}
private static String buildResolutionString(Format format) {
return format.width == Format.NO_VALUE || format.height == Format.NO_VALUE
? "" : format.width + "x" + format.height;
}
private static String buildAudioPropertyString(Format format) {
return format.channelCount == Format.NO_VALUE || format.sampleRate == Format.NO_VALUE
? "" : format.channelCount + "ch, " + format.sampleRate + "Hz";
}
private static String buildLanguageString(Format format) {
return TextUtils.isEmpty(format.language) || "und".equals(format.language) ? ""
: format.language;
}
private static String buildBitrateString(Format format) {
return format.bitrate == Format.NO_VALUE ? ""
: String.format(Locale.US, "%.2fMbit", format.bitrate / 1000000f);
}
private static String joinWithSeparator(String first, String second) {
return first.length() == 0 ? second : (second.length() == 0 ? first : first + ", " + second);
}
private static String buildTrackIdString(Format format) {
return format.id == null ? "" : ("id:" + format.id);
}
private static String buildSampleMimeTypeString(Format format) {
return format.sampleMimeType == null ? "" : format.sampleMimeType;
}
}
......@@ -29,13 +29,18 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
compile files('libs/cronet_api.jar')
compile files('libs/cronet_impl_common_java.jar')
compile files('libs/cronet_impl_native_java.jar')
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
androidTestCompile project(':library')
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.google.dexmaker:dexmaker:' + dexmakerVersion
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
androidTestCompile 'org.mockito:mockito-core:' + mockitoVersion
androidTestCompile 'com.android.support.test:runner:' + testSupportLibraryVersion
}
ext {
javadocTitle = 'Cronet extension'
}
apply from: '../../javadoc_library.gradle'
......@@ -72,7 +72,7 @@ public final class CronetDataSourceFactory extends BaseFactory {
protected CronetDataSource createDataSourceInternal(HttpDataSource.RequestProperties
defaultRequestProperties) {
return new CronetDataSource(cronetEngine, executor, contentTypePredicate, transferListener,
connectTimeoutMs, readTimeoutMs, resetTimeoutOnRedirects, null, defaultRequestProperties);
connectTimeoutMs, readTimeoutMs, resetTimeoutOnRedirects, defaultRequestProperties);
}
}
......@@ -31,21 +31,18 @@ FFMPEG_EXT_PATH="${EXOPLAYER_ROOT}/extensions/ffmpeg/src/main"
NDK_PATH="<path to Android NDK>"
```
* Fetch and build FFmpeg. For example, to fetch and build for armv7a:
* Set up host platform ("darwin-x86_64" for Mac OS X):
```
cd "${FFMPEG_EXT_PATH}/jni" && \
git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \
./configure \
--libdir=android-libs/armeabi-v7a \
--arch=arm \
--cpu=armv7-a \
--cross-prefix="${NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-" \
HOST_PLATFORM="linux-x86_64"
```
* Fetch and build FFmpeg. For example, to fetch and build for armeabi-v7a,
arm64-v8a and x86 on Linux x86_64:
```
COMMON_OPTIONS="\
--target-os=android \
--sysroot="${NDK_PATH}/platforms/android-9/arch-arm/" \
--extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
--extra-ldexeflags=-pie \
--disable-static \
--enable-shared \
--disable-doc \
......@@ -57,22 +54,56 @@ git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \
--disable-postproc \
--disable-avfilter \
--disable-symver \
--disable-swresample \
--enable-avresample \
--enable-decoder=vorbis \
--enable-decoder=opus \
--enable-decoder=flac \
--enable-decoder=alac \
" && \
cd "${FFMPEG_EXT_PATH}/jni" && \
git clone git://source.ffmpeg.org/ffmpeg ffmpeg && cd ffmpeg && \
./configure \
--libdir=android-libs/armeabi-v7a \
--arch=arm \
--cpu=armv7-a \
--cross-prefix="${NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/${HOST_PLATFORM}/bin/arm-linux-androideabi-" \
--sysroot="${NDK_PATH}/platforms/android-9/arch-arm/" \
--extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
--extra-ldexeflags=-pie \
${COMMON_OPTIONS} \
&& \
make -j4 && make install-libs && \
make clean && ./configure \
--libdir=android-libs/arm64-v8a \
--arch=aarch64 \
--cpu=armv8-a \
--cross-prefix="${NDK_PATH}/toolchains/aarch64-linux-android-4.9/prebuilt/${HOST_PLATFORM}/bin/aarch64-linux-android-" \
--sysroot="${NDK_PATH}/platforms/android-21/arch-arm64/" \
--extra-ldexeflags=-pie \
${COMMON_OPTIONS} \
&& \
make -j4 && make install-libs && \
make clean && ./configure \
--libdir=android-libs/x86 \
--arch=x86 \
--cpu=i686 \
--cross-prefix="${NDK_PATH}/toolchains/x86-4.9/prebuilt/${HOST_PLATFORM}/bin/i686-linux-android-" \
--sysroot="${NDK_PATH}/platforms/android-9/arch-x86/" \
--extra-ldexeflags=-pie \
--disable-asm \
${COMMON_OPTIONS} \
&& \
make -j4 && \
make install-libs
make -j4 && make install-libs && \
make clean
```
* Build the JNI native libraries. Repeat this step for any other architectures
you need to support.
* Build the JNI native libraries, setting `APP_ABI` to include the architectures
built in the previous step. For example:
```
cd "${FFMPEG_EXT_PATH}"/jni && \
${NDK_PATH}/ndk-build APP_ABI=armeabi-v7a -j4
${NDK_PATH}/ndk-build APP_ABI="armeabi-v7a arm64-v8a x86" -j4
```
* In your project, you can add a dependency on the extension by using a rule
......
......@@ -30,5 +30,10 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
}
ext {
javadocTitle = 'FFmpeg extension'
}
apply from: '../../javadoc_library.gradle'
......@@ -32,14 +32,9 @@ LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := ffmpeg/android-libs/$(TARGET_ARCH_ABI)/$(LOCAL_MODULE).so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := ffmpeg_jni.cc
LOCAL_C_INCLUDES := ffmpeg
LOCAL_SHARED_LIBRARIES := libavcodec libavresample libavutil libswresample
LOCAL_SHARED_LIBRARIES := libavcodec libavresample libavutil
LOCAL_LDLIBS := -Lffmpeg/android-libs/$(TARGET_ARCH_ABI) -llog
include $(BUILD_SHARED_LIBRARY)
......@@ -30,7 +30,11 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
androidTestCompile project(':testutils')
}
ext {
javadocTitle = 'FLAC extension'
}
apply from: '../../javadoc_library.gradle'
......@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
......@@ -103,6 +104,11 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing.
}
......
......@@ -24,11 +24,16 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
compile 'com.google.vr:sdk-audio:1.30.0'
}
ext {
javadocTitle = 'GVR extension'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'extension-gvr'
releaseDescription = 'Google VR extension for ExoPlayer.'
}
......
......@@ -152,14 +152,19 @@ public final class GvrAudioProcessor implements AudioProcessor {
@Override
public void flush() {
if (gvrAudioSurround != null) {
gvrAudioSurround.flush();
}
inputEnded = false;
}
@Override
public synchronized void release() {
buffer = null;
public synchronized void reset() {
maybeReleaseGvrAudioSurround();
inputEnded = false;
buffer = null;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
}
private void maybeReleaseGvrAudioSurround() {
......
......@@ -29,13 +29,18 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
compile('com.squareup.okhttp3:okhttp:3.6.0') {
exclude group: 'org.json'
}
}
ext {
javadocTitle = 'OkHttp extension'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'extension-okhttp'
releaseDescription = 'OkHttp extension for ExoPlayer.'
}
......
......@@ -30,5 +30,10 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
}
ext {
javadocTitle = 'Opus extension'
}
apply from: '../../javadoc_library.gradle'
......@@ -22,6 +22,7 @@ import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
......@@ -103,6 +104,11 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing.
}
......
......@@ -161,7 +161,7 @@ import java.util.List;
cryptoInfo.key, cryptoInfo.iv, cryptoInfo.numSubSamples,
cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData)
: opusDecode(nativeDecoderContext, inputBuffer.timeUs, inputData, inputData.limit(),
outputBuffer, SAMPLE_RATE);
outputBuffer);
if (result < 0) {
if (result == DRM_ERROR) {
String message = "Drm error: " + opusGetErrorMessage(nativeDecoderContext);
......@@ -210,7 +210,7 @@ import java.util.List;
private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled,
int gain, byte[] streamMap);
private native int opusDecode(long decoder, long timeUs, ByteBuffer inputBuffer, int inputSize,
SimpleOutputBuffer outputBuffer, int sampleRate);
SimpleOutputBuffer outputBuffer);
private native int opusSecureDecode(long decoder, long timeUs, ByteBuffer inputBuffer,
int inputSize, SimpleOutputBuffer outputBuffer, int sampleRate,
ExoMediaCrypto mediaCrypto, int inputMode, byte[] key, byte[] iv,
......
......@@ -59,6 +59,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
}
static const int kBytesPerSample = 2; // opus fixed point uses 16 bit samples.
static const int kMaxOpusOutputPacketSizeSamples = 960 * 6;
static int channelCount;
static int errorCode;
......@@ -92,16 +93,14 @@ DECODER_FUNC(jlong, opusInit, jint sampleRate, jint channelCount,
}
DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs,
jobject jInputBuffer, jint inputSize, jobject jOutputBuffer,
jint sampleRate) {
jobject jInputBuffer, jint inputSize, jobject jOutputBuffer) {
OpusMSDecoder* decoder = reinterpret_cast<OpusMSDecoder*>(jDecoder);
const uint8_t* inputBuffer =
reinterpret_cast<const uint8_t*>(
env->GetDirectBufferAddress(jInputBuffer));
const int32_t inputSampleCount =
opus_packet_get_nb_samples(inputBuffer, inputSize, sampleRate);
const jint outputSize = inputSampleCount * kBytesPerSample * channelCount;
const jint outputSize =
kMaxOpusOutputPacketSizeSamples * kBytesPerSample * channelCount;
env->CallObjectMethod(jOutputBuffer, outputBufferInit, jTimeUs, outputSize);
const jobject jOutputBufferData = env->CallObjectMethod(jOutputBuffer,
......@@ -110,7 +109,7 @@ DECODER_FUNC(jint, opusDecode, jlong jDecoder, jlong jTimeUs,
int16_t* outputBufferData = reinterpret_cast<int16_t*>(
env->GetDirectBufferAddress(jOutputBufferData));
int sampleCount = opus_multistream_decode(decoder, inputBuffer, inputSize,
outputBufferData, outputSize, 0);
outputBufferData, kMaxOpusOutputPacketSizeSamples, 0);
// record error code
errorCode = (sampleCount < 0) ? sampleCount : 0;
return (sampleCount < 0) ? sampleCount
......
......@@ -49,7 +49,7 @@ git clone https://chromium.googlesource.com/libyuv/libyuv libyuv
cd "${VP9_EXT_PATH}/jni/libvpx" && \
git checkout tags/v1.6.1 -b v1.6.1 && \
cd "${VP9_EXT_PATH}/jni/libyuv" && \
git checkout e2611a73
git checkout 996a2bbd
```
* Run a script that generates necessary configuration files for libvpx:
......
......@@ -30,6 +30,10 @@ android {
}
dependencies {
compile project(':library')
compile project(':library-core')
}
ext {
javadocTitle = 'VP9 extension'
}
apply from: '../../javadoc_library.gradle'
......@@ -23,6 +23,7 @@ import android.util.Log;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
......@@ -135,6 +136,11 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
// Do nothing.
}
......
......@@ -21,6 +21,7 @@ LIBYUV_ROOT := $(WORKING_DIR)/libyuv
# build libyuv_static.a
LOCAL_PATH := $(WORKING_DIR)
LIBYUV_DISABLE_JPEG := "yes"
include $(LIBYUV_ROOT)/Android.mk
# build libvpx.so
......
......@@ -68,7 +68,7 @@ limit=$((${#arch[@]} - 1))
# everything else will be removed.
allowed_files="libvpx_srcs.txt vpx_config.c vpx_config.h vpx_scale_rtcd.h"
allowed_files+=" vp8_rtcd.h vp9_rtcd.h vpx_version.h vpx_config.asm"
allowed_files+=" vpx_dsp_rtcd.h"
allowed_files+=" vpx_dsp_rtcd.h libvpx.ver"
remove_trailing_whitespace() {
perl -pi -e 's/\s\+$//' "$@"
......
......@@ -37,9 +37,7 @@ LOCAL_SRC_FILES += $(addprefix libvpx/, $(filter-out vpx_config.c, \
# include assembly files if they exist
# "%.asm.[sS]" covers neon assembly and "%.asm" covers x86 assembly
LOCAL_SRC_FILES += $(addprefix libvpx/, \
$(filter %.asm.s %.asm, $(libvpx_codec_srcs)))
LOCAL_SRC_FILES += $(addprefix libvpx/, \
$(filter %.asm.S %.asm, $(libvpx_codec_srcs)))
$(filter %.asm.s %.asm.S %.asm, $(libvpx_codec_srcs)))
ifneq ($(findstring armeabi-v7a, $(TARGET_ARCH_ABI)),)
# append .neon to *_neon.c and *.[sS]
......@@ -48,10 +46,8 @@ LOCAL_SRC_FILES := $(subst .s,.s.neon,$(LOCAL_SRC_FILES))
LOCAL_SRC_FILES := $(subst .S,.S.neon,$(LOCAL_SRC_FILES))
endif
# remove duplicates
LOCAL_SRC_FILES := $(sort $(LOCAL_SRC_FILES))
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/libvpx \
$(LOCAL_PATH)/libvpx/vpx
LOCAL_LDFLAGS := -Wl,--version-script=$(CONFIG_DIR)/libvpx.ver
include $(BUILD_SHARED_LIBRARY)
......@@ -20,8 +20,9 @@
#include <android/log.h>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <new>
#include "libyuv.h" // NOLINT
......
// Copyright (C) 2017 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.
class CombinedJavadocPlugin implements Plugin<Project> {
static final String TASK_NAME = "generateCombinedJavadoc"
@Override
void apply(Project project) {
project.gradle.projectsEvaluated {
Set<Project> libraryModules = getLibraryModules(project)
if (!libraryModules.isEmpty()) {
String sdkDirectory = getSdkDirectory(libraryModules)
project.task(TASK_NAME, type: Javadoc) {
description = "Generates combined Javadoc."
title = "ExoPlayer library"
source = libraryModules.generateJavadoc.source
classpath = project.files(libraryModules.generateJavadoc.classpath)
destinationDir = project.file("$project.buildDir/docs/javadoc")
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference",
"${sdkDirectory}/docs/reference"
encoding = "UTF-8"
}
exclude "**/BuildConfig.java"
exclude "**/R.java"
destinationDir project.file("$project.buildDir/docs/javadoc")
doLast {
libraryModules.each { libraryModule ->
project.copy {
from "${libraryModule.projectDir}/src/main/javadoc"
into "${project.buildDir}/docs/javadoc"
}
}
}
}
}
}
}
// Returns Android library modules that declare a generateJavadoc task.
private Set<Project> getLibraryModules(Project project) {
project.subprojects.findAll {
it.plugins.findPlugin("com.android.library") &&
it.tasks.findByName("generateJavadoc")
}
}
// Returns the Android SDK directory given a set of Android library modules.
private String getSdkDirectory(Set<Project> libraryModules) {
// We can retrieve the Android SDK directory from any module.
return libraryModules.iterator().next().android.sdkDirectory
}
}
apply plugin: CombinedJavadocPlugin
// Copyright (C) 2017 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.
android.libraryVariants.all { variant ->
def name = variant.buildType.name
if (!name.equals("release")) {
return; // Skip non-release builds.
}
task("generateJavadoc", type: Javadoc) {
description = "Generates Javadoc for the ${javadocTitle}."
title = "ExoPlayer ${javadocTitle}"
source = variant.javaCompile.source
classpath = files(variant.javaCompile.classpath.files,
project.android.getBootClasspath())
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference",
"${android.sdkDirectory}/docs/reference"
encoding = "UTF-8"
}
exclude "**/BuildConfig.java"
exclude "**/R.java"
doLast {
copy {
from "src/main/javadoc"
into "$buildDir/docs/javadoc"
}
}
}
}
// 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.
apply plugin: 'com.android.library'
android {
compileSdkVersion project.ext.compileSdkVersion
buildToolsVersion project.ext.buildToolsVersion
defaultConfig {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
}
}
dependencies {
compile project(':library-core')
compile project(':library-dash')
compile project(':library-hls')
compile project(':library-smoothstreaming')
compile project(':library-ui')
}
ext {
releaseArtifact = 'exoplayer'
releaseDescription = 'The ExoPlayer library (all modules).'
}
apply from: '../../publish.gradle'
......@@ -11,8 +11,6 @@
// 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.
import com.android.builder.core.BuilderConstants
apply plugin: 'com.android.library'
android {
......@@ -22,66 +20,35 @@ android {
defaultConfig {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
}
buildTypes {
// Re-enable test coverage when the following issue is fixed:
// https://code.google.com/p/android/issues/detail?id=226070
// debug {
// testCoverageEnabled = true
// }
}
sourceSets {
androidTest {
java.srcDirs += "../testutils/src/main/java/"
java.srcDirs += "../../testutils/src/main/java/"
}
}
}
dependencies {
compile 'com.android.support:support-annotations:25.2.0'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'org.mockito:mockito-core:1.9.5'
buildTypes {
debug {
testCoverageEnabled = true
}
}
}
android.libraryVariants.all { variant ->
def name = variant.buildType.name
if (name.equals(BuilderConstants.DEBUG)) {
return; // Skip debug builds.
}
def task = project.tasks.create "jar${name.capitalize()}", Jar
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
artifacts.add('archives', task);
dependencies {
compile 'com.android.support:support-annotations:' + supportLibraryVersion
androidTestCompile 'com.google.dexmaker:dexmaker:' + dexmakerVersion
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
androidTestCompile 'org.mockito:mockito-core:' + mockitoVersion
}
android.libraryVariants.all { variant ->
task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
title = "ExoPlayer library"
description "Generates Javadoc for $variant.name."
source = variant.javaCompile.source
classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath())
options {
links "http://docs.oracle.com/javase/7/docs/api/"
linksOffline "https://developer.android.com/reference","${android.sdkDirectory}/docs/reference"
encoding = 'UTF-8'
}
exclude '**/BuildConfig.java'
exclude '**/R.java'
doLast {
copy {
from "src/main/javadoc"
into "$buildDir/docs/javadoc"
}
}
}
ext {
javadocTitle = 'Core module'
}
apply from: '../../javadoc_library.gradle'
ext {
releaseArtifact = 'exoplayer'
releaseDescription = 'The ExoPlayer library.'
releaseArtifact = 'exoplayer-core'
releaseDescription = 'The ExoPlayer library core module.'
}
apply from: '../publish.gradle'
apply from: '../../publish.gradle'
......@@ -16,7 +16,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.test">
package="com.google.android.exoplayer2.core.test">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
......@@ -27,7 +27,7 @@
</application>
<instrumentation
android:targetPackage="com.google.android.exoplayer2.test"
android:targetPackage="com.google.android.exoplayer2.core.test"
android:name="android.test.InstrumentationTestRunner"
tools:replace="android:targetPackage"/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment