diff --git a/packages/expo-av/CHANGELOG.md b/packages/expo-av/CHANGELOG.md index 8fbcae6f8abe1..a723ca4ac41cc 100644 --- a/packages/expo-av/CHANGELOG.md +++ b/packages/expo-av/CHANGELOG.md @@ -11,6 +11,8 @@ ### 🐛 Bug fixes +- Allow playing media files embedded as resources in an Android APK. ([#8936](https://github.com/expo/expo/pull/8936) by [@esamelson](https://github.com/esamelson)) + ## 8.2.1 — 2020-05-29 _This version does not introduce any user-facing changes._ diff --git a/packages/expo-av/android/src/main/java/expo/modules/av/player/MediaPlayerData.java b/packages/expo-av/android/src/main/java/expo/modules/av/player/MediaPlayerData.java index ddb403eafce22..99a464532bab2 100644 --- a/packages/expo-av/android/src/main/java/expo/modules/av/player/MediaPlayerData.java +++ b/packages/expo-av/android/src/main/java/expo/modules/av/player/MediaPlayerData.java @@ -69,8 +69,13 @@ public void load(final Bundle status, final MediaPlayer unpreparedPlayer = new MediaPlayer(); try { + Uri uri = mUri; + if (uri.getScheme() == null) { + int resourceId = mAVModule.getContext().getResources().getIdentifier(uri.toString(), "raw", mAVModule.getContext().getPackageName()); + uri = Uri.parse("android.resource://" + mAVModule.getContext().getPackageName() + "/" + resourceId); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - unpreparedPlayer.setDataSource(mAVModule.getContext(), mUri, null, getHttpCookiesList()); + unpreparedPlayer.setDataSource(mAVModule.getContext(), uri, null, getHttpCookiesList()); } else { Map headers = new HashMap<>(1); StringBuilder cookieBuilder = new StringBuilder(); @@ -89,7 +94,7 @@ public void load(final Bundle status, } } } - unpreparedPlayer.setDataSource(mAVModule.getContext(), mUri, headers); + unpreparedPlayer.setDataSource(mAVModule.getContext(), uri, headers); } } catch (final Throwable throwable) { loadCompletionListener.onLoadError("Load encountered an error: setDataSource() threw an exception was thrown with message: " + throwable.toString()); diff --git a/packages/expo-av/android/src/main/java/expo/modules/av/player/SimpleExoPlayerData.java b/packages/expo-av/android/src/main/java/expo/modules/av/player/SimpleExoPlayerData.java index f5fabc66987a5..c78f5bb401b2f 100644 --- a/packages/expo-av/android/src/main/java/expo/modules/av/player/SimpleExoPlayerData.java +++ b/packages/expo-av/android/src/main/java/expo/modules/av/player/SimpleExoPlayerData.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import android.text.TextUtils; +import android.util.Log; import android.util.Pair; import android.view.Surface; @@ -40,6 +41,7 @@ import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; +import com.google.android.exoplayer2.upstream.RawResourceDataSource; import com.google.android.exoplayer2.util.Util; import java.io.IOException; @@ -54,6 +56,7 @@ class SimpleExoPlayerData extends PlayerData implements Player.EventListener, ExtractorMediaSource.EventListener, SimpleExoPlayer.VideoListener, AdaptiveMediaSourceEventListener { private static final String IMPLEMENTATION_NAME = "SimpleExoPlayer"; + private static final String TAG = SimpleExoPlayerData.class.getSimpleName(); private SimpleExoPlayer mSimpleExoPlayer = null; private String mOverridingExtension; @@ -367,6 +370,17 @@ public void onRenderedFirstFrame() { // https://github.com/google/ExoPlayer/blob/2b20780482a9c6b07416bcbf4de829532859d10a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java#L365-L393 private MediaSource buildMediaSource(Uri uri, String overrideExtension, Handler mainHandler, DataSource.Factory factory) { + try { + if (uri.getScheme() == null) { + int resourceId = mReactContext.getResources().getIdentifier(uri.toString(), "raw", mReactContext.getPackageName()); + DataSpec dataSpec = new DataSpec(RawResourceDataSource.buildRawResourceUri(resourceId)); + final RawResourceDataSource rawResourceDataSource = new RawResourceDataSource(mReactContext); + rawResourceDataSource.open(dataSpec); + uri = rawResourceDataSource.getUri(); + } + } catch (Exception e) { + Log.e(TAG, "Error reading raw resource from ExoPlayer", e); + } @C.ContentType int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(String.valueOf(uri)) : Util.inferContentType("." + overrideExtension); switch (type) { case C.TYPE_SS: