Skip to content

Commit

Permalink
feat(android): replace deprecated ExoPlayer2 with AndroidX media3 (#3337
Browse files Browse the repository at this point in the history
)

* feat(android): implement AndroidX media3 dependencies
* refactor(android): remove duplicate code
* refactor(android): remove unused codes
* feat(android): replace ExoPlayer2 with AndroidX media3
* fix(android): move default properties to gradle.properties
* revert(android): prevent security exception
* chore: align indent
* chore: remove redundant comments
* chore: reorder import
* fix: apply media3's legacy player control view
  • Loading branch information
YangJonghun authored Nov 18, 2023
1 parent 1ba93f9 commit f2e80e9
Show file tree
Hide file tree
Showing 20 changed files with 441 additions and 476 deletions.
91 changes: 51 additions & 40 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,24 @@ def safeExtGet(prop) {
return rootProject.ext.has(prop) ? rootProject.ext.get(prop) : project.properties["RNVideo_" + prop]
}

def getExtOrDefault(name, defaultValue) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : defaultValue
}

def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}

def supportsNamespace() {
def parsed = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
def major = parsed[0].toInteger()
def minor = parsed[1].toInteger()
def parsed = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
def major = parsed[0].toInteger()
def minor = parsed[1].toInteger()

// Namespace support was added in 7.3.0
if (major == 7 && minor >= 3) {
return true
}
// Namespace support was added in 7.3.0
if (major == 7 && minor >= 3) {
return true
}

return major >= 8
return major >= 8
}

def useExoplayerIMA = getExtOrDefault("RNVUseExoplayerIMA", false)
def useExoplayerIMA = safeExtGet("RNVUseExoplayerIMA")?.toBoolean() ?: false

println "useExoplayerIMA:" + useExoplayerIMA

Expand All @@ -58,28 +54,28 @@ if (isNewArchitectureEnabled()) {

android {
if (supportsNamespace()) {
namespace 'com.brentvatne.react'
namespace 'com.brentvatne.react'

sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
}
}
}
}

compileSdkVersion safeExtGet('compileSdkVersion')
buildToolsVersion safeExtGet('buildToolsVersion')

def agpVersion = Version.ANDROID_GRADLE_PLUGIN_VERSION
if (agpVersion.tokenize('.')[0].toInteger() < 8) {
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.majorVersion
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.majorVersion
}
}

defaultConfig {
Expand Down Expand Up @@ -119,12 +115,12 @@ android {
java {
if (isNewArchitectureEnabled()) {
srcDirs += [
"src/fabric/java",
"${project.buildDir}/generated/source/codegen/java"
"src/fabric/java",
"${project.buildDir}/generated/source/codegen/java"
]
} else {
srcDirs += [
"src/oldarch/java"
"src/oldarch/java"
]
}
}
Expand All @@ -145,29 +141,44 @@ repositories {
mavenCentral()
}

def media3_version = safeExtGet('media3Version')
def kotlin_version = safeExtGet('kotlinVersion')

dependencies {
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation('com.google.android.exoplayer:exoplayer:2.18.1') {
exclude group: 'com.android.support'
}

implementation "androidx.annotation:annotation:1.7.0"
implementation "androidx.core:core:1.9.0"
implementation "androidx.media:media:1.6.0"
implementation "androidx.activity:activity:1.6.0"

implementation('com.google.android.exoplayer:extension-okhttp:2.18.1') {
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
// For media playback using ExoPlayer
implementation "androidx.media3:media3-exoplayer:$media3_version"

// For Smooth Streaming playback support with ExoPlayer
implementation "androidx.media3:media3-exoplayer-smoothstreaming:$media3_version"
// For DASH playback support with ExoPlayer
implementation "androidx.media3:media3-exoplayer-dash:$media3_version"
// For HLS playback support with ExoPlayer
implementation "androidx.media3:media3-exoplayer-hls:$media3_version"
// For ad insertion using the Interactive Media Ads SDK with ExoPlayer
if (useExoplayerIMA) {
implementation 'com.google.android.exoplayer:extension-ima:2.18.1'
implementation "androidx.media3:media3-exoplayer-ima:$media3_version"
}
implementation "com.squareup.okhttp3:okhttp:" + '$OKHTTP_VERSION'

// For loading data using the OkHttp network stack
implementation "androidx.media3:media3-datasource-okhttp:$media3_version"

// For building media playback UIs
implementation "androidx.media3:media3-ui:$media3_version"

// For exposing and controlling media sessions
implementation "androidx.media3:media3-session:$media3_version"

// Common functionality for loading data
implementation "androidx.media3:media3-datasource:$media3_version"
// Common functionality used across multiple media libraries
implementation "androidx.media3:media3-common:$media3_version"

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
4 changes: 3 additions & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ RNVideo_minSdkVersion=21
RNVideo_targetSdkVersion=31
RNVideo_compileSdkVersion=31
RNVideo_ndkversion=21.4.7075529
RNVideo_buildToolsVersion=30.0.2
RNVideo_buildToolsVersion=30.0.2
RNVideo_media3Version=1.1.1
RNVideo_RNVUseExoplayerIMA=false
22 changes: 0 additions & 22 deletions android/src/main/java/com/brentvatne/ReactBridgeUtils.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.brentvatne.common.API

import com.brentvatne.ReactBridgeUtils
import com.brentvatne.common.toolbox.ReactBridgeUtils
import com.facebook.react.bridge.ReadableMap

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.brentvatne.common.react;

import androidx.annotation.StringDef;

import android.view.View;

import com.brentvatne.common.API.TimedMetadata;
Expand All @@ -12,10 +13,10 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.ArrayList;

public class VideoEventEmitter {
Expand Down Expand Up @@ -124,8 +125,6 @@ public VideoEventEmitter(ReactContext reactContext) {
private static final String EVENT_PROP_STEP_FORWARD = "canStepForward";
private static final String EVENT_PROP_STEP_BACKWARD = "canStepBackward";

private static final String EVENT_PROP_BUFFER_START = "bufferStart";
private static final String EVENT_PROP_BUFFER_END = "bufferEnd";
private static final String EVENT_PROP_DURATION = "duration";
private static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
private static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration";
Expand Down Expand Up @@ -241,8 +240,7 @@ public void load(double duration, double currentPosition, int videoWidth, int vi
load( duration, currentPosition, videoWidth, videoHeight, waAudioTracks, waTextTracks, waVideoTracks, trackId);
}


public void load(double duration, double currentPosition, int videoWidth, int videoHeight,
void load(double duration, double currentPosition, int videoWidth, int videoHeight,
WritableArray audioTracks, WritableArray textTracks, WritableArray videoTracks, String trackId) {
WritableMap event = Arguments.createMap();
event.putDouble(EVENT_PROP_DURATION, duration / 1000D);
Expand All @@ -267,8 +265,6 @@ public void load(double duration, double currentPosition, int videoWidth, int vi
receiveEvent(EVENT_LOAD, event);
}



WritableMap arrayToObject(String field, WritableArray array) {
WritableMap event = Arguments.createMap();
event.putArray(field, array);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package com.brentvatne.exoplayer;

import android.annotation.SuppressLint;
import com.google.android.exoplayer2.C;

import androidx.media3.common.C;

@SuppressLint("InlinedApi")
public enum AudioOutput {
SPEAKER("speaker", C.STREAM_TYPE_MUSIC),
EARPIECE("earpiece", C.STREAM_TYPE_VOICE_CALL);

private final int streamType;
private final @C.StreamType int streamType;
private final String mName;

AudioOutput(final String name, int stream) {
AudioOutput(final String name, @C.StreamType int stream) {
mName = name;
streamType = stream;
}
Expand Down
19 changes: 10 additions & 9 deletions android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.brentvatne.exoplayer;

import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.datasource.HttpDataSource;
import androidx.media3.datasource.okhttp.OkHttpDataSource;
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;

import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.CookieJarContainer;
import com.facebook.react.modules.network.ForwardingCookieHandler;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util;

import java.util.Map;

import okhttp3.Call;
import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
import java.util.Map;

public class DataSourceUtil {

Expand Down Expand Up @@ -76,8 +78,7 @@ private static DataSource.Factory buildRawDataSourceFactory(ReactContext context
}

private static DataSource.Factory buildDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map<String, String> requestHeaders) {
return new DefaultDataSource.Factory(context,
buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders));
return new DefaultDataSource.Factory(context, buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders));
}

private static HttpDataSource.Factory buildHttpDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map<String, String> requestHeaders) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import android.content.Context;

import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;

public class DefaultReactExoplayerConfig implements ReactExoplayerConfig {

Expand Down
Loading

0 comments on commit f2e80e9

Please sign in to comment.