mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Fix proguard configurations
1. When we try and load something via reflection and find the class, always throw rather than failing silently if we subsequently fail to instantiate an instance. This is indicative of a broken proguard setup, and failing silently makes it hard to spot. 2. Add library/core proguard configuration to ensure extension renderer constructors that we access via reflection are kept. 3. Add demos/main proguard configuration to ensure ImaAdsLoader constructor that we access via reflection is kept. 4. Added IMA proguard file to hopefully fix #3723, although I wasn't actually able to reproduce the issue. Issue: #3723 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=183648187
This commit is contained in:
parent
e26dc3990d
commit
1f6d161d4d
@ -27,7 +27,10 @@ android {
|
|||||||
release {
|
release {
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt')
|
proguardFiles = [
|
||||||
|
"proguard-rules.txt",
|
||||||
|
getDefaultProguardFile('proguard-android.txt')
|
||||||
|
]
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
jniDebuggable = true
|
jniDebuggable = true
|
||||||
|
6
demos/main/proguard-rules.txt
Normal file
6
demos/main/proguard-rules.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Proguard rules specific to the main demo app.
|
||||||
|
|
||||||
|
# Constructor accessed via reflection in PlayerActivity
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.ima.ImaAdsLoader {
|
||||||
|
<init>(android.content.Context, android.net.Uri);
|
||||||
|
}
|
@ -16,7 +16,6 @@
|
|||||||
package com.google.android.exoplayer2.demo;
|
package com.google.android.exoplayer2.demo;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -76,6 +75,7 @@ import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
|||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||||
import com.google.android.exoplayer2.util.EventLogger;
|
import com.google.android.exoplayer2.util.EventLogger;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.CookieHandler;
|
import java.net.CookieHandler;
|
||||||
import java.net.CookieManager;
|
import java.net.CookieManager;
|
||||||
import java.net.CookiePolicy;
|
import java.net.CookiePolicy;
|
||||||
@ -353,9 +353,10 @@ public class PlayerActivity extends Activity
|
|||||||
releaseAdsLoader();
|
releaseAdsLoader();
|
||||||
loadedAdTagUri = adTagUri;
|
loadedAdTagUri = adTagUri;
|
||||||
}
|
}
|
||||||
try {
|
MediaSource adsMediaSource = createAdsMediaSource(mediaSource, Uri.parse(adTagUriString));
|
||||||
mediaSource = createAdsMediaSource(mediaSource, Uri.parse(adTagUriString));
|
if (adsMediaSource != null) {
|
||||||
} catch (Exception e) {
|
mediaSource = adsMediaSource;
|
||||||
|
} else {
|
||||||
showToast(R.string.ima_not_loaded);
|
showToast(R.string.ima_not_loaded);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -463,39 +464,47 @@ public class PlayerActivity extends Activity
|
|||||||
.buildHttpDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
|
.buildHttpDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Returns an ads media source, reusing the ads loader if one exists. */
|
||||||
* Returns an ads media source, reusing the ads loader if one exists.
|
private @Nullable MediaSource createAdsMediaSource(MediaSource mediaSource, Uri adTagUri) {
|
||||||
*
|
|
||||||
* @throws Exception Thrown if it was not possible to create an ads media source, for example, due
|
|
||||||
* to a missing dependency.
|
|
||||||
*/
|
|
||||||
private MediaSource createAdsMediaSource(MediaSource mediaSource, Uri adTagUri) throws Exception {
|
|
||||||
// Load the extension source using reflection so the demo app doesn't have to depend on it.
|
// Load the extension source using reflection so the demo app doesn't have to depend on it.
|
||||||
// The ads loader is reused for multiple playbacks, so that ad playback can resume.
|
// The ads loader is reused for multiple playbacks, so that ad playback can resume.
|
||||||
Class<?> loaderClass = Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsLoader");
|
try {
|
||||||
if (adsLoader == null) {
|
Class<?> loaderClass = Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsLoader");
|
||||||
adsLoader = (AdsLoader) loaderClass.getConstructor(Context.class, Uri.class)
|
if (adsLoader == null) {
|
||||||
.newInstance(this, adTagUri);
|
// Full class names used so the LINT.IfChange rule triggers should any of the classes move.
|
||||||
adUiViewGroup = new FrameLayout(this);
|
// LINT.IfChange
|
||||||
// The demo app has a non-null overlay frame layout.
|
Constructor<? extends AdsLoader> loaderConstructor =
|
||||||
playerView.getOverlayFrameLayout().addView(adUiViewGroup);
|
loaderClass
|
||||||
}
|
.asSubclass(AdsLoader.class)
|
||||||
AdsMediaSource.MediaSourceFactory adMediaSourceFactory =
|
.getConstructor(android.content.Context.class, android.net.Uri.class);
|
||||||
new AdsMediaSource.MediaSourceFactory() {
|
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||||
@Override
|
adsLoader = loaderConstructor.newInstance(this, adTagUri);
|
||||||
public MediaSource createMediaSource(
|
adUiViewGroup = new FrameLayout(this);
|
||||||
Uri uri, @Nullable Handler handler, @Nullable MediaSourceEventListener listener) {
|
// The demo app has a non-null overlay frame layout.
|
||||||
return PlayerActivity.this.buildMediaSource(
|
playerView.getOverlayFrameLayout().addView(adUiViewGroup);
|
||||||
uri, /* overrideExtension= */ null, handler, listener);
|
}
|
||||||
}
|
AdsMediaSource.MediaSourceFactory adMediaSourceFactory =
|
||||||
|
new AdsMediaSource.MediaSourceFactory() {
|
||||||
|
@Override
|
||||||
|
public MediaSource createMediaSource(
|
||||||
|
Uri uri, @Nullable Handler handler, @Nullable MediaSourceEventListener listener) {
|
||||||
|
return PlayerActivity.this.buildMediaSource(
|
||||||
|
uri, /* overrideExtension= */ null, handler, listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int[] getSupportedTypes() {
|
public int[] getSupportedTypes() {
|
||||||
return new int[] {C.TYPE_DASH, C.TYPE_SS, C.TYPE_HLS, C.TYPE_OTHER};
|
return new int[] {C.TYPE_DASH, C.TYPE_SS, C.TYPE_HLS, C.TYPE_OTHER};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new AdsMediaSource(
|
return new AdsMediaSource(
|
||||||
mediaSource, adMediaSourceFactory, adsLoader, adUiViewGroup, mainHandler, eventLogger);
|
mediaSource, adMediaSourceFactory, adsLoader, adUiViewGroup, mainHandler, eventLogger);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// IMA extension not loaded.
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseAdsLoader() {
|
private void releaseAdsLoader() {
|
||||||
|
6
demos/main/src/main/proguard-rules.txt
Normal file
6
demos/main/src/main/proguard-rules.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Proguard rules specific to the main demo app.
|
||||||
|
|
||||||
|
# Constructor accessed via reflection in PlayerActivity
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.ima.ImaAdsLoader {
|
||||||
|
<init>(android.content.Context, android.net.Uri);
|
||||||
|
}
|
6
extensions/ima/proguard-rules.txt
Normal file
6
extensions/ima/proguard-rules.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Proguard rules specific to the IMA extension.
|
||||||
|
|
||||||
|
-keep class com.google.ads.interactivemedia.** { *; }
|
||||||
|
-keep interface com.google.ads.interactivemedia.** { *; }
|
||||||
|
-keep class com.google.obf.** { *; }
|
||||||
|
-keep interface com.google.obf.** { *; }
|
6
extensions/ima/src/main/proguard-rules.txt
Normal file
6
extensions/ima/src/main/proguard-rules.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Proguard rules specific to the IMA extension.
|
||||||
|
|
||||||
|
-keep class com.google.ads.interactivemedia.** { *; }
|
||||||
|
-keep interface com.google.ads.interactivemedia.** { *; }
|
||||||
|
-keep class com.google.obf.** { *; }
|
||||||
|
-keep interface com.google.obf.** { *; }
|
@ -21,6 +21,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion project.ext.minSdkVersion
|
minSdkVersion project.ext.minSdkVersion
|
||||||
targetSdkVersion project.ext.targetSdkVersion
|
targetSdkVersion project.ext.targetSdkVersion
|
||||||
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround to prevent circular dependency on project :testutils.
|
// Workaround to prevent circular dependency on project :testutils.
|
||||||
|
25
library/core/proguard-rules.txt
Normal file
25
library/core/proguard-rules.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Proguard rules specific to the core module.
|
||||||
|
|
||||||
|
# Constructors accessed via reflection in DefaultRenderersFactory
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer {
|
||||||
|
<init>(boolean, long, android.os.Handler, com.google.android.exoplayer2.video.VideoRendererEventListener, int);
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer {
|
||||||
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer {
|
||||||
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
||||||
|
}
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer {
|
||||||
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Constructors accessed via reflection in DefaultExtractorsFactory
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.flac.FlacExtractor {
|
||||||
|
<init>();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Constructors accessed via reflection in DefaultDataSource
|
||||||
|
-keepclassmembers class com.google.android.exoplayer2.ext.rtmp.RtmpDataSource {
|
||||||
|
<init>();
|
||||||
|
}
|
@ -185,18 +185,32 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz =
|
// Full class names used for constructor args so the LINT rule triggers if any of them move.
|
||||||
Class.forName("com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer");
|
// LINT.IfChange
|
||||||
Constructor<?> constructor = clazz.getConstructor(boolean.class, long.class, Handler.class,
|
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer");
|
||||||
VideoRendererEventListener.class, int.class);
|
Constructor<?> constructor =
|
||||||
Renderer renderer = (Renderer) constructor.newInstance(true, allowedVideoJoiningTimeMs,
|
clazz.getConstructor(
|
||||||
eventHandler, eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
|
boolean.class,
|
||||||
|
long.class,
|
||||||
|
android.os.Handler.class,
|
||||||
|
com.google.android.exoplayer2.video.VideoRendererEventListener.class,
|
||||||
|
int.class);
|
||||||
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
|
Renderer renderer =
|
||||||
|
(Renderer)
|
||||||
|
constructor.newInstance(
|
||||||
|
true,
|
||||||
|
allowedVideoJoiningTimeMs,
|
||||||
|
eventHandler,
|
||||||
|
eventListener,
|
||||||
|
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded LibvpxVideoRenderer.");
|
Log.i(TAG, "Loaded LibvpxVideoRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
// Expected if the app was built without the extension.
|
// Expected if the app was built without the extension.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// The extension is present, but instantiation failed.
|
||||||
|
throw new RuntimeException("Error instantiating VP9 extension", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,48 +244,67 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz =
|
// Full class names used for constructor args so the LINT rule triggers if any of them move.
|
||||||
Class.forName("com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer");
|
// LINT.IfChange
|
||||||
Constructor<?> constructor = clazz.getConstructor(Handler.class,
|
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer");
|
||||||
AudioRendererEventListener.class, AudioProcessor[].class);
|
Constructor<?> constructor =
|
||||||
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener,
|
clazz.getConstructor(
|
||||||
audioProcessors);
|
android.os.Handler.class,
|
||||||
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
|
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
||||||
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
|
Renderer renderer =
|
||||||
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded LibopusAudioRenderer.");
|
Log.i(TAG, "Loaded LibopusAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
// Expected if the app was built without the extension.
|
// Expected if the app was built without the extension.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// The extension is present, but instantiation failed.
|
||||||
|
throw new RuntimeException("Error instantiating Opus extension", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> clazz =
|
// Full class names used for constructor args so the LINT rule triggers if any of them move.
|
||||||
Class.forName("com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer");
|
// LINT.IfChange
|
||||||
Constructor<?> constructor = clazz.getConstructor(Handler.class,
|
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer");
|
||||||
AudioRendererEventListener.class, AudioProcessor[].class);
|
Constructor<?> constructor =
|
||||||
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener,
|
clazz.getConstructor(
|
||||||
audioProcessors);
|
android.os.Handler.class,
|
||||||
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
|
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
||||||
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
|
Renderer renderer =
|
||||||
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded LibflacAudioRenderer.");
|
Log.i(TAG, "Loaded LibflacAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
// Expected if the app was built without the extension.
|
// Expected if the app was built without the extension.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// The extension is present, but instantiation failed.
|
||||||
|
throw new RuntimeException("Error instantiating FLAC extension", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Full class names used for constructor args so the LINT rule triggers if any of them move.
|
||||||
|
// LINT.IfChange
|
||||||
Class<?> clazz =
|
Class<?> clazz =
|
||||||
Class.forName("com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer");
|
Class.forName("com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer");
|
||||||
Constructor<?> constructor = clazz.getConstructor(Handler.class,
|
Constructor<?> constructor =
|
||||||
AudioRendererEventListener.class, AudioProcessor[].class);
|
clazz.getConstructor(
|
||||||
Renderer renderer = (Renderer) constructor.newInstance(eventHandler, eventListener,
|
android.os.Handler.class,
|
||||||
audioProcessors);
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
|
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
||||||
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
|
Renderer renderer =
|
||||||
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded FfmpegAudioRenderer.");
|
Log.i(TAG, "Loaded FfmpegAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
// Expected if the app was built without the extension.
|
// Expected if the app was built without the extension.
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// The extension is present, but instantiation failed.
|
||||||
|
throw new RuntimeException("Error instantiating FFmpeg extension", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,13 +55,17 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
|
|||||||
static {
|
static {
|
||||||
Constructor<? extends Extractor> flacExtractorConstructor = null;
|
Constructor<? extends Extractor> flacExtractorConstructor = null;
|
||||||
try {
|
try {
|
||||||
|
// LINT.IfChange
|
||||||
flacExtractorConstructor =
|
flacExtractorConstructor =
|
||||||
Class.forName("com.google.android.exoplayer2.ext.flac.FlacExtractor")
|
Class.forName("com.google.android.exoplayer2.ext.flac.FlacExtractor")
|
||||||
.asSubclass(Extractor.class).getConstructor();
|
.asSubclass(Extractor.class)
|
||||||
|
.getConstructor();
|
||||||
|
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
// Extractor not found.
|
// Expected if the app was built without the FLAC extension.
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (Exception e) {
|
||||||
// Constructor not found.
|
// The FLAC extension is present, but instantiation failed.
|
||||||
|
throw new RuntimeException("Error instantiating FLAC extension", e);
|
||||||
}
|
}
|
||||||
FLAC_EXTRACTOR_CONSTRUCTOR = flacExtractorConstructor;
|
FLAC_EXTRACTOR_CONSTRUCTOR = flacExtractorConstructor;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import android.util.Log;
|
|||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
|
* A {@link DataSource} that supports multiple URI schemes. The supported schemes are:
|
||||||
@ -193,18 +192,16 @@ public final class DefaultDataSource implements DataSource {
|
|||||||
private DataSource getRtmpDataSource() {
|
private DataSource getRtmpDataSource() {
|
||||||
if (rtmpDataSource == null) {
|
if (rtmpDataSource == null) {
|
||||||
try {
|
try {
|
||||||
|
// LINT.IfChange
|
||||||
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.rtmp.RtmpDataSource");
|
Class<?> clazz = Class.forName("com.google.android.exoplayer2.ext.rtmp.RtmpDataSource");
|
||||||
rtmpDataSource = (DataSource) clazz.getDeclaredConstructor().newInstance();
|
rtmpDataSource = (DataSource) clazz.getConstructor().newInstance();
|
||||||
|
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
// Expected if the app was built without the RTMP extension.
|
||||||
Log.w(TAG, "Attempting to play RTMP stream without depending on the RTMP extension");
|
Log.w(TAG, "Attempting to play RTMP stream without depending on the RTMP extension");
|
||||||
} catch (InstantiationException e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Error instantiating RtmpDataSource", e);
|
// The RTMP extension is present, but instantiation failed.
|
||||||
} catch (IllegalAccessException e) {
|
throw new RuntimeException("Error instantiating RTMP extension", e);
|
||||||
Log.e(TAG, "Error instantiating RtmpDataSource", e);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
Log.e(TAG, "Error instantiating RtmpDataSource", e);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
Log.e(TAG, "Error instantiating RtmpDataSource", e);
|
|
||||||
}
|
}
|
||||||
if (rtmpDataSource == null) {
|
if (rtmpDataSource == null) {
|
||||||
rtmpDataSource = baseDataSource;
|
rtmpDataSource = baseDataSource;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user