gpt4 book ai didi

android - 我如何让 ExoPlayer 在我的 Activity 的 onStart() 方法中恢复视频?

转载 作者:行者123 更新时间:2023-11-29 16:58:09 28 4
gpt4 key购买 nike

我正在使用 ExoPlayer 从 URL 播放一些 mp4。当用户单击主页按钮或任何导致应用程序从用户 View 中删除然后返回到我的应用程序(和视频 Activity )时,我希望视频从它停止的地方继续播放。我尝试通过在 onStop() 中保存视频位置然后重建播放器并在 onStart() 中使用 seekTo() 来实现这一点。我在 onStart() 中检查我当前的 exoplayer 是否为 null,但是此检查从未通过,所以我认为这就是问题所在。现在它是如何编码的我的视频永远不会恢复。如果我通过按下主页按钮离开应用程序 onStop() 被调用,然后当我返回我的应用程序时 onStart() 将被调用,但是视频播放器仍然存在黑色,从不播放视频。如果我删除空检查,每当我从主要 Activity 开始播放视频时,我都会播放两个视频实例,因为它在 onCreate()onStart() 中都被调用.有没有更好的方法来获得我想要的功能?感谢您的帮助!

public class VideoActivity extends AppCompatActivity {

private SimpleExoPlayer exoPlayer;
private SimpleExoPlayerView simpleExoPlayerView;
private long playerPosition;
private String mp4Url;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_activity);

// Get the Intent that started this activity and extract the video url
Intent intent = getIntent();
mp4Url = intent.getStringExtra(MainActivity.VIDEO_URL);
// Create an exoplayer instance and start playing video
buildPlayer(mp4Url);

}

private void buildPlayer(String mp4Url) {
// Create a default TrackSelector
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

// Create the player
exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector); // no LoadControl?
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);

// Set media controller
simpleExoPlayerView.setUseController(true);
simpleExoPlayerView.requestFocus();

// Bind player to the view
simpleExoPlayerView.setPlayer(exoPlayer);

// Create Uri from video location
// TODO: should this be in some network class? Should I be appending APIKEY here?
Uri mp4Uri = Uri.parse(mp4Url + "?api_key=" + BuildConfig.GIANTBOMB_API_KEY);
Timber.v("Video url with api key: " + mp4Uri.toString());

// Create another bandwidth meter for bandwidth during playback (not strictly necessary)
DefaultBandwidthMeter playbackBandwidthMeter = new DefaultBandwidthMeter();

// DataSourceFactory to produce DataSource instances through which media data is loaded
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "GiantBombForAndroid"),
playbackBandwidthMeter);

// Produces Extractor instances for parsing the media data
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

ExtractorMediaSource.EventListener eventListener = new ExtractorMediaSource.EventListener() {
@Override
public void onLoadError(IOException error) {
Timber.e("Error loading video from source");
}
};

final MediaSource videoSource = new ExtractorMediaSource(mp4Uri,
dataSourceFactory,
extractorsFactory,
mainHandler,
eventListener);

exoPlayer.prepare(videoSource);

exoPlayer.addListener(new ExoPlayer.EventListener() {
@Override
public void onLoadingChanged(boolean isLoading) {
Timber.v("Listener-onLoadingChanged...");

}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Timber.v("Listener-onPlayerStateChanged...");

}

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
Timber.v("Listener-onTimelineChanged...");

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// TODO: Do I need anything here?
}

@Override
public void onPlayerError(ExoPlaybackException error) {
Timber.v("Listener-onPlayerError...");
exoPlayer.stop();
exoPlayer.prepare(videoSource);
exoPlayer.setPlayWhenReady(true);
}

@Override
public void onPositionDiscontinuity() {
Timber.v("Listener-onPositionDiscontinuity...");

}

@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// TODO: Do I need anything here?
}
});
exoPlayer.setPlayWhenReady(true);
}

@Override
protected void onStart() {
super.onStart();
Timber.v("onStart()...");
if (exoPlayer == null) {
Timber.v("No exoplayer instance, recreating...");
buildPlayer(mp4Url);
exoPlayer.seekTo(playerPosition);
}
}

@Override
protected void onStop(){
super.onStop();
Timber.v("onStop()...");
//TODO: pull player creation code into it's own method so it can be called here as well
playerPosition = exoPlayer.getCurrentPosition();
exoPlayer.release();
}

@Override
protected void onDestroy() {
super.onDestroy();
Timber.v("onDestroy()...");
exoPlayer.release();
}
}

最佳答案

目前您正在 onStop() 中调用 release,这将清空播放器的所有重要部分,但不会清空 exoPlayer 字段(并销毁任何状态你没有跟踪自己)。

有几种不同的方法。但无论您做什么,您都可能希望自己跟踪某些状态。下面我将它们用作字段,但它们也可以放在 onSavedInstanceState() 中。在 onStop() 中,我们保存了两条信息,然后在 onStart() 中将它们提取出来。 1) 我们的玩家在暂停时所处的最后位置,以及 2) 我们是否应该在恢复时播放。您可以将 seekTo 调用移出 if == null block ,因为您可能总是希望从中断的地方继续。:

@Override
public void onStart() {
// ...

if (exoPlayer == null) {
// init player
}

// Seek to the last position of the player.
exoPlayer.seekTo(mLastPosition);

// Put the player into the last state we were in.
exoPlayer.setPlayWhenReady(mPlayVideoWhenForegrounded);

// ...
}

@Override
public void onStop() {
// ...

// Store off if we were playing so we know if we should start when we're foregrounded again.
mPlayVideoWhenForegrounded = exoPlayer.getPlayWhenReady();

// Store off the last position our player was in before we paused it.
mLastPosition = exoPlayer.getCurrentPosition();

// Pause the player
exoPlayer.setPlayWhenReady(false);

// ...
}

现在我在您的代码示例中看到的另一个问题是 exoPlayer.release() 不会清空 exoPlayer 字段。因此,您可以在 exoPlayer.release() 之后添加 exoPlayer = null 行,这有望解决您的多个 exoPlayer 问题。您还可以将 release() 调用移动到 onDestroy(),但前提是您知道自己正在正确地重新实例化所有内容。

关于android - 我如何让 ExoPlayer 在我的 Activity 的 onStart() 方法中恢复视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43959176/

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