gpt4 book ai didi

java - 如何修复exo播放器加载视频慢的问题

转载 作者:行者123 更新时间:2023-12-01 12:55:58 30 4
gpt4 key购买 nike

我正在尝试编写一个应用程序,其中有几个需要播放的视频 URL。我正在使用 ExoPlayer 播放视频。

ExoPlayer 正在播放视频,但我面临的问题是,ExoPlayer 正在加载视频的某些部分(比如说 5 秒)然后播放它们,一旦 exo 播放器完成播放该部分,它就会尝试加载视频的下一部分和然后播放那部分视频。即使互联网速度很好,也会出现此问题。

我尝试阅读 ExoPlayer 文档和其他 stackoverflow 帖子,但我无法弄清楚这里出了什么问题。

下面是我的 exo 播放器单例类代码:

/**
* Singleton class that manages all video playback in the app. Ensures that only a single stream can be heard at a time
* and reports the current playback status to any interested listeners.
*/
public class VideoWrapper {
private static String TAG = "VideoWrapper";

private int VideoPlaybackState = VideoPlaybackListener.STATE_VIDEO_STOPPED;

// Player that plays the videos.
private SimpleExoPlayer exoPlayer;

// Singleton instance of the class
private static VideoWrapper videoWrapper;

// URL of Current Video Item that is getting played.
private String mCurrentStreamingUrl;

// Handler to take request of video playback in-case there is a playlist is being sent for play.
private Handler handler;

// Add the listener and notify them if required. -- For demo i am not using it but for UI updates and all it will be useful.
private List<VideoPlaybackListener> listeners = new LinkedList<>();

// Tells to which screen we have to go back
private String mPreviousScreenName;

private Context context;

public static VideoWrapper getInstance() {
if (videoWrapper == null) {
videoWrapper = new VideoWrapper();
}

return videoWrapper;
}

// Default constrructor!
private VideoWrapper() {
// Nothing to do.
}

public void setCurrentPreviousScreen(String screen) {
mPreviousScreenName = screen;
}

public void init(Context context) {
try {
this.context = context;
handler = new Handler(context.getMainLooper());
} catch (Exception e) {
// TODO
}
}

public void stopAndReleasePlayer() {

// Stop the player first.
stopVideoStreaming();

// Now release the player and make it null.
if (exoPlayer != null) {
exoPlayer.release();
exoPlayer = null;
}
}

public void addListener(VideoPlaybackListener listener) {
listeners.add(listener);
}

public void removeListener(VideoPlaybackListener listener) {
listeners.remove(listener);
}

public int getVideoPlaybackState() {
return VideoPlaybackState;
}

private SimpleExoPlayer.VideoListener gVideoEventListener = new SimpleExoPlayer.VideoListener() {
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
// TODO: Do Something!
}

@Override
public void onRenderedFirstFrame() {
// TODO: Do Something!
}
};

private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() {
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
// TODO: Do Something!
}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// TODO: Do Something!
}

@Override
public void onLoadingChanged(boolean isLoading) {
// TODO: Do Something!
}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
// playback state handling serially
case ExoPlayer.STATE_IDLE:
// TODO: Do something!
break;

case ExoPlayer.STATE_BUFFERING:
// TODO: Do something!
break;

case ExoPlayer.STATE_READY:
// TODO: Do something!
break;

case ExoPlayer.STATE_ENDED:
// TODO: Do something!
break;
}
}

@Override
public void onPlayerError(ExoPlaybackException error) {
int errorType = error.type;
switch (errorType) {
case ExoPlaybackException.TYPE_RENDERER:
// TODO: Do something!
break;
case ExoPlaybackException.TYPE_SOURCE:
// TODO: Do something!
break;
case ExoPlaybackException.TYPE_UNEXPECTED:
// TODO: Do something!
break;
default:
// TODO: Do something!
break;
}
}

@Override
public void onPositionDiscontinuity() {
// TODO: Do something!
}
};

private boolean canPlayCurrentItem() {
return mCurrentStreamingUrl != null && !TextUtils.isEmpty(mCurrentStreamingUrl);
}

public void stopVideoStreaming() {
if (exoPlayer != null) {
exoPlayer.setPlayWhenReady(false);
}
}

private void restartVideoStreaming() {
if (canPlayCurrentItem()) {
streamCurrentTrack();
}
}

public void startVideoStreaming(String streamUrl) {
// Stop any video if it is playing.
stopVideoStreaming();
VideoPlaybackState = VideoPlaybackListener.STATE_VIDEO_STOPPED;
mCurrentStreamingUrl = streamUrl;

openStreamUrl();
}

private void openStreamUrl() {
Uri uri = Uri.parse(mCurrentStreamingUrl);

TrackSelector trackSelector = new DefaultTrackSelector();

LoadControl loadControl = new DefaultLoadControl();

DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = buildDataSourceFactory(bandwidthMeter);

// This is the MediaSource representing the media to be played.
HlsMediaSource mediaSource = new HlsMediaSource(uri, dataSourceFactory, handler, new AdaptiveMediaSourceEventListener() {
@Override
public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
// TODO: Do something!
}

@Override
public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
// TODO: Do something!
}

@Override
public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
// TODO: Do something!
}

@Override
public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
// TODO: Do something!
}

@Override
public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
// TODO: Do something!
}

@Override
public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
// TODO: Do something!
}
});

exoPlayer.prepare(mediaSource);

streamCurrentTrack();
}

private DataSource.Factory buildDataSourceFactory(DefaultBandwidthMeter bandwidthMeter){
return new DefaultDataSourceFactory(context, bandwidthMeter, buildHttpDataSourceFactory(bandwidthMeter));
}

private HttpDataSource.Factory buildHttpDataSourceFactory(DefaultBandwidthMeter bandwidthMeter){
return new DefaultHttpDataSourceFactory("TiVoPhoenix", bandwidthMeter);
}

public void togglePlayPause() {
if (canPlayCurrentItem()) {
if (VideoPlaybackState == PlaybackListener.STATE_PLAYING) {
stopVideoStreaming();
VideoPlaybackState = PlaybackListener.STATE_PAUSED;
} else {
restartVideoStreaming();
}
}
}

private void streamCurrentTrack() {
VideoPlaybackState = VideoPlaybackListener.STATE_VIDEO_PLAYING;
exoPlayer.setPlayWhenReady(true);
}

public SimpleExoPlayer getPlayer() {
TrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();

// Stop and release the video player before re-creating it.
stopAndReleasePlayer();

exoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl);
exoPlayer.addListener(eventListener);
exoPlayer.setVideoListener(gVideoEventListener);

return exoPlayer;
}
}

有人可以帮我弄这个吗?

最佳答案

为您的负载控制尝试以下设置:

public class VideoPlayerConfig {
//Minimum Video you want to buffer while Playing
public static final int MIN_BUFFER_DURATION = 2000;
//Max Video you want to buffer during PlayBack
public static final int MAX_BUFFER_DURATION = 5000;
//Min Video you want to buffer before start Playing it
public static final int MIN_PLAYBACK_START_BUFFER = 1500;
//Min video You want to buffer when user resumes video
public static final int MIN_PLAYBACK_RESUME_BUFFER = 2000;
}

LoadControl loadControl = new DefaultLoadControl.Builder()
.setAllocator(new DefaultAllocator(true, 16))
.setBufferDurationsMs(VideoPlayerConfig.MIN_BUFFER_DURATION,
VideoPlayerConfig.MAX_BUFFER_DURATION,
VideoPlayerConfig.MIN_PLAYBACK_START_BUFFER,
VideoPlayerConfig.MIN_PLAYBACK_RESUME_BUFFER)
.setTargetBufferBytes(-1)
.setPrioritizeTimeOverSizeThresholds(true).createDefaultLoadControl();

这个想法是保持最小缓冲区较低,以便视频加载更快。

题外话:而且我不知道你为什么使用单例模式,可能是为了控制应用程序中的任何地方。当您使用单例模式时,您可以使用应用程序上下文的弱引用。

关于java - 如何修复exo播放器加载视频慢的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55773893/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com