diff --git a/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java b/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java deleted file mode 100644 index 5a037896..00000000 --- a/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.brentvatne.exoplayer; - -import android.net.Uri; - -import androidx.annotation.NonNull; -import androidx.media3.common.util.Util; -import androidx.media3.datasource.AssetDataSource; -import androidx.media3.datasource.DataSource; -import androidx.media3.datasource.DataSpec; -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 java.util.Map; - -import okhttp3.Call; -import okhttp3.JavaNetCookieJar; -import okhttp3.OkHttpClient; - -public class DataSourceUtil { - - private DataSourceUtil() { - } - - private static DataSource.Factory defaultDataSourceFactory = null; - private static HttpDataSource.Factory defaultHttpDataSourceFactory = null; - private static String userAgent = null; - - public static void setUserAgent(String userAgent) { - DataSourceUtil.userAgent = userAgent; - } - - public static String getUserAgent(ReactContext context) { - if (userAgent == null) { - userAgent = Util.getUserAgent(context, context.getPackageName()); - } - return userAgent; - } - - public static DataSource.Factory getDefaultDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map requestHeaders) { - if (defaultDataSourceFactory == null || (requestHeaders != null && !requestHeaders.isEmpty())) { - defaultDataSourceFactory = buildDataSourceFactory(context, bandwidthMeter, requestHeaders); - } - return defaultDataSourceFactory; - } - - public static HttpDataSource.Factory getDefaultHttpDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map requestHeaders) { - if (defaultHttpDataSourceFactory == null || (requestHeaders != null && !requestHeaders.isEmpty())) { - defaultHttpDataSourceFactory = buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders); - } - return defaultHttpDataSourceFactory; - } - - private static DataSource.Factory buildDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map requestHeaders) { - return new DefaultDataSource.Factory(context, buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders)); - } - - private static HttpDataSource.Factory buildHttpDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter, Map requestHeaders) { - OkHttpClient client = OkHttpClientProvider.getOkHttpClient(); - CookieJarContainer container = (CookieJarContainer) client.cookieJar(); - ForwardingCookieHandler handler = new ForwardingCookieHandler(context); - container.setCookieJar(new JavaNetCookieJar(handler)); - OkHttpDataSource.Factory okHttpDataSourceFactory = new OkHttpDataSource.Factory((Call.Factory) client) - .setTransferListener(bandwidthMeter); - - if (requestHeaders != null) { - okHttpDataSourceFactory.setDefaultRequestProperties(requestHeaders); - if (!requestHeaders.containsKey("User-Agent")) { - okHttpDataSourceFactory.setUserAgent(getUserAgent(context)); - } - } else { - okHttpDataSourceFactory.setUserAgent(getUserAgent(context)); - } - - return okHttpDataSourceFactory; - } - - public static DataSource.Factory buildAssetDataSourceFactory(ReactContext context, Uri srcUri) throws AssetDataSource.AssetDataSourceException { - DataSpec dataSpec = new DataSpec(srcUri); - final AssetDataSource rawResourceDataSource = new AssetDataSource(context); - rawResourceDataSource.open(dataSpec); - return new DataSource.Factory() { - @NonNull - @Override - public DataSource createDataSource() { - return rawResourceDataSource; - } - }; - } -} diff --git a/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.kt b/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.kt new file mode 100644 index 00000000..96a7887d --- /dev/null +++ b/android/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.kt @@ -0,0 +1,88 @@ +package com.brentvatne.exoplayer + +import android.net.Uri +import androidx.media3.common.util.Util +import androidx.media3.datasource.AssetDataSource +import androidx.media3.datasource.DataSource +import androidx.media3.datasource.DataSpec +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 okhttp3.Call +import okhttp3.JavaNetCookieJar + +object DataSourceUtil { + private var defaultDataSourceFactory: DataSource.Factory? = null + private var defaultHttpDataSourceFactory: HttpDataSource.Factory? = null + private var userAgent: String? = null + + private fun getUserAgent(context: ReactContext): String { + if (userAgent == null) { + userAgent = Util.getUserAgent(context, context.packageName) + } + return userAgent as String + } + + @JvmStatic + fun getDefaultDataSourceFactory(context: ReactContext, bandwidthMeter: DefaultBandwidthMeter?, requestHeaders: Map?): DataSource.Factory { + if (defaultDataSourceFactory == null || !requestHeaders.isNullOrEmpty()) { + defaultDataSourceFactory = buildDataSourceFactory(context, bandwidthMeter, requestHeaders) + } + return defaultDataSourceFactory as DataSource.Factory + } + + @JvmStatic + fun getDefaultHttpDataSourceFactory( + context: ReactContext, + bandwidthMeter: DefaultBandwidthMeter?, + requestHeaders: Map? + ): HttpDataSource.Factory { + if (defaultHttpDataSourceFactory == null || !requestHeaders.isNullOrEmpty()) { + defaultHttpDataSourceFactory = buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders) + } + return defaultHttpDataSourceFactory as HttpDataSource.Factory + } + + private fun buildDataSourceFactory( + context: ReactContext, + bandwidthMeter: DefaultBandwidthMeter?, + requestHeaders: Map? + ): DataSource.Factory = DefaultDataSource.Factory(context, buildHttpDataSourceFactory(context, bandwidthMeter, requestHeaders)) + + private fun buildHttpDataSourceFactory( + context: ReactContext, + bandwidthMeter: DefaultBandwidthMeter?, + requestHeaders: Map? + ): HttpDataSource.Factory { + val client = OkHttpClientProvider.getOkHttpClient() + val container = client.cookieJar as CookieJarContainer + val handler = ForwardingCookieHandler(context) + container.setCookieJar(JavaNetCookieJar(handler)) + val okHttpDataSourceFactory = OkHttpDataSource.Factory(client as Call.Factory) + .setTransferListener(bandwidthMeter) + + if (requestHeaders != null) { + okHttpDataSourceFactory.setDefaultRequestProperties(requestHeaders) + if (!requestHeaders.containsKey("User-Agent")) { + okHttpDataSourceFactory.setUserAgent(getUserAgent(context)) + } + } else { + okHttpDataSourceFactory.setUserAgent(getUserAgent(context)) + } + + return okHttpDataSourceFactory + } + + @JvmStatic + fun buildAssetDataSourceFactory(context: ReactContext?, srcUri: Uri?): DataSource.Factory { + val dataSpec = DataSpec(srcUri!!) + val rawResourceDataSource = AssetDataSource(context!!) + rawResourceDataSource.open(dataSpec) + return DataSource.Factory { rawResourceDataSource } + } +} diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index e650b564..194727f2 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -7,7 +7,6 @@ import static androidx.media3.common.C.CONTENT_TYPE_RTSP; import static androidx.media3.common.C.CONTENT_TYPE_SS; import static androidx.media3.common.C.TIME_END_OF_SOURCE; -import static com.brentvatne.exoplayer.DataSourceUtil.buildAssetDataSourceFactory; import android.annotation.SuppressLint; import android.app.Activity; @@ -1060,7 +1059,7 @@ public class ReactExoplayerView extends FrameLayout implements case CONTENT_TYPE_OTHER: if ("asset".equals(uri.getScheme())) { try { - DataSource.Factory assetDataSourceFactory = buildAssetDataSourceFactory(themedReactContext, uri); + DataSource.Factory assetDataSourceFactory = DataSourceUtil.buildAssetDataSourceFactory(themedReactContext, uri); mediaSourceFactory = new ProgressiveMediaSource.Factory(assetDataSourceFactory); } catch (Exception e) { throw new IllegalStateException("cannot open input file" + uri);