mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-13 13:10:56 +00:00
Merge pull request #361 from chrisk325/patch-8
Several optimizations for exoplayer for preventing crashes with heavy file sizes
This commit is contained in:
commit
20601cd7ba
2 changed files with 51 additions and 30 deletions
|
|
@ -161,7 +161,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
AdEvent.AdEventListener,
|
||||
AdErrorEvent.AdErrorListener {
|
||||
|
||||
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 1;
|
||||
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 0.5;
|
||||
public static final double DEFAULT_MIN_BUFFER_MEMORY_RESERVE = 0;
|
||||
|
||||
private static final String TAG = "ReactExoplayerView";
|
||||
|
|
@ -244,7 +244,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
private BufferingStrategy.BufferingStrategyEnum bufferingStrategy;
|
||||
private boolean disableDisconnectError;
|
||||
private boolean preventsDisplaySleepDuringVideoPlayback = true;
|
||||
private float mProgressUpdateInterval = 250.0f;
|
||||
private float mProgressUpdateInterval = 1000.0f;
|
||||
protected boolean playInBackground = false;
|
||||
private boolean mReportBandwidth = false;
|
||||
private boolean controls = false;
|
||||
|
|
@ -270,6 +270,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
private final String instanceId = String.valueOf(UUID.randomUUID());
|
||||
|
||||
private CmcdConfiguration.Factory cmcdConfigurationFactory;
|
||||
private static final ExecutorService SHARED_EXECUTOR = Executors.newSingleThreadExecutor();
|
||||
|
||||
public void setCmcdConfigurationFactory(CmcdConfiguration.Factory factory) {
|
||||
this.cmcdConfigurationFactory = factory;
|
||||
|
|
@ -642,6 +643,8 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
}
|
||||
|
||||
private void initializePlayer() {
|
||||
drmRetryCount = 0;
|
||||
hasDrmFailed = false;
|
||||
disableCache = ReactNativeVideoManager.Companion.getInstance().shouldDisableCache(source);
|
||||
|
||||
ReactExoplayerView self = this;
|
||||
|
|
@ -664,10 +667,14 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder,
|
||||
this.enterPictureInPictureOnLeave);
|
||||
}
|
||||
if (!source.isLocalAssetFile() && !source.isAsset() && source.getBufferConfig().getCacheSize() > 0) {
|
||||
long requestedCacheSize = source.getBufferConfig().getCacheSize();
|
||||
long MAX_SAFE_CACHE_SIZE = 100L * 1024 * 1024;
|
||||
long effectiveCacheSize = Math.min(requestedCacheSize, MAX_SAFE_CACHE_SIZE);
|
||||
if (!source.isLocalAssetFile() && !source.isAsset() && effectiveCacheSize > 0) {
|
||||
RNVSimpleCache.INSTANCE.setSimpleCache(
|
||||
this.getContext(),
|
||||
source.getBufferConfig().getCacheSize());
|
||||
effectiveCacheSize
|
||||
);
|
||||
useCache = true;
|
||||
} else {
|
||||
useCache = false;
|
||||
|
|
@ -677,8 +684,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
exoPlayerView.invalidateAspectRatio();
|
||||
// DRM session manager creation must be done on a different thread to prevent
|
||||
// crashes so we start a new thread
|
||||
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
es.execute(() -> {
|
||||
SHARED_EXECUTOR.execute(() -> {
|
||||
// DRM initialization must run on a different thread
|
||||
if (viewHasDropped && runningSource == source) {
|
||||
return;
|
||||
|
|
@ -876,13 +882,10 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
MediaSource mediaSource = Objects.requireNonNullElse(mediaSourceWithAds, videoSource);
|
||||
|
||||
// wait for player to be set
|
||||
while (player == null) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
DebugLog.e(TAG, ex.toString());
|
||||
}
|
||||
if (player == null) {
|
||||
DebugLog.w(TAG, "Player not ready yet, aborting source initialization");
|
||||
playerNeedsSource = true;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
|
||||
|
|
@ -1515,8 +1518,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
ArrayList<Track> textTracks = getTextTrackInfo();
|
||||
|
||||
if (source.getContentStartTime() != -1) {
|
||||
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
es.execute(() -> {
|
||||
SHARED_EXECUTOR.execute(() -> {
|
||||
// To prevent ANRs caused by getVideoTrackInfo we run this on a different thread
|
||||
// and notify the player only when we're done
|
||||
ArrayList<VideoTrack> videoTracks = getVideoTrackInfoFromManifest();
|
||||
|
|
@ -1629,12 +1631,11 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
// conditions
|
||||
@WorkerThread
|
||||
private ArrayList<VideoTrack> getVideoTrackInfoFromManifest(int retryCount) {
|
||||
ExecutorService es = Executors.newSingleThreadExecutor();
|
||||
final DataSource dataSource = this.mediaDataSourceFactory.createDataSource();
|
||||
final Uri sourceUri = source.getUri();
|
||||
final long startTime = source.getContentStartTime() * 1000 - 100; // s -> ms with 100ms offset
|
||||
|
||||
Future<ArrayList<VideoTrack>> result = es.submit(new Callable() {
|
||||
Future<ArrayList<VideoTrack>> result = SHARED_EXECUTOR.submit(new Callable<ArrayList<VideoTrack>>() {
|
||||
final DataSource ds = dataSource;
|
||||
final Uri uri = sourceUri;
|
||||
final long startTimeUs = startTime * 1000; // ms -> us
|
||||
|
|
@ -1684,7 +1685,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
if (results == null && retryCount < 1) {
|
||||
return this.getVideoTrackInfoFromManifest(++retryCount);
|
||||
}
|
||||
es.shutdown();
|
||||
return results;
|
||||
} catch (Exception e) {
|
||||
DebugLog.w(TAG, "error in getVideoTrackInfoFromManifest handling request:" + e.getMessage());
|
||||
|
|
@ -1993,13 +1993,15 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||
if (!hasDrmFailed) {
|
||||
// When DRM fails to reach the app level certificate server it will fail with a
|
||||
// source error so we assume that it is DRM related and try one more time
|
||||
hasDrmFailed = true;
|
||||
playerNeedsSource = true;
|
||||
updateResumePosition();
|
||||
initializePlayer();
|
||||
setPlayWhenReady(true);
|
||||
return;
|
||||
}
|
||||
if (drmRetryCount < 1) {
|
||||
drmRetryCount++;
|
||||
hasDrmFailed = true;
|
||||
playerNeedsSource = true;
|
||||
updateResumePosition();
|
||||
initializePlayer();
|
||||
setPlayWhenReady(true);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,13 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
/* Animations - State & Refs */
|
||||
const [showBackwardSign, setShowBackwardSign] = React.useState(false);
|
||||
const [showForwardSign, setShowForwardSign] = React.useState(false);
|
||||
const [previewTime, setPreviewTime] = React.useState(currentTime);
|
||||
const isSlidingRef = React.useRef(false);
|
||||
React.useEffect(() => {
|
||||
if (!isSlidingRef.current) {
|
||||
setPreviewTime(currentTime);
|
||||
}
|
||||
}, [currentTime]);
|
||||
|
||||
/* Separate Animations for Each Button */
|
||||
const backwardPressAnim = React.useRef(new Animated.Value(0)).current;
|
||||
|
|
@ -280,10 +287,22 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
}}
|
||||
minimumValue={0}
|
||||
maximumValue={duration || 1}
|
||||
value={currentTime}
|
||||
onValueChange={onSliderValueChange}
|
||||
onSlidingStart={onSlidingStart}
|
||||
onSlidingComplete={onSlidingComplete}
|
||||
|
||||
value={previewTime}
|
||||
|
||||
onValueChange={(v) => setPreviewTime(v)}
|
||||
|
||||
onSlidingStart={() => {
|
||||
isSlidingRef.current = true;
|
||||
onSlidingStart();
|
||||
}}
|
||||
|
||||
onSlidingComplete={(v) => {
|
||||
isSlidingRef.current = false;
|
||||
setPreviewTime(v);
|
||||
onSlidingComplete(v);
|
||||
}}
|
||||
|
||||
minimumTrackTintColor={currentTheme.colors.primary}
|
||||
maximumTrackTintColor={currentTheme.colors.mediumEmphasis}
|
||||
thumbTintColor={Platform.OS === 'android' ? currentTheme.colors.white : undefined}
|
||||
|
|
@ -608,4 +627,4 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
);
|
||||
};
|
||||
|
||||
export default PlayerControls;
|
||||
export default PlayerControls;
|
||||
|
|
|
|||
Loading…
Reference in a new issue