8

我有一个包含 2 个片段(不是 ViewPager)的活动,并且想在其中一个片段中使用 ExoPlayer2 来播放内容。初始片段显示内容列表,单击时显示第二个片段以播放所选内容。但是,当我单击返回初始片段时,我仍然可以听到播放的内容;就好像第二个片段仍然打开一样。我(试图)以这种方式释放播放器:

@Override
public void onStop() {
    super.onStop();
    releasePlayer();
}

public void releasePlayer() {

    if (player != null) {
        player.setPlayWhenReady(true);
        player.stop();
        player.release();
        player = null;
        trackSelector = null;
        simpleExoPlayerView.setPlayer(null);
        simpleExoPlayerView = null;
        System.out.println("releasePlayer");
    }
}

我读了这个,但它并没有提供太多的解决方案。此外,阅读几篇在 ViewPager 片段中使用 ExoPlayer 的帖子,但不确定这些示例是如何释放播放器的。遵循此处找到的演示应用程序中的 releasePlayer() 方法,但没有运气。从 onPause()、onDetach()、onDestroyView() 调用 releasePlayer() 但没有区别。

这是在将侦听器添加到播放器后设置的一些日志记录,但看不到任何解释它为什么不释放的东西......

07-05 19:01:07.216 2529-2643/? V/RenderScript: 0xe0494000 Launching thread(s), CPUs 4
07-05 19:01:11.871 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.876 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:11.904 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:12.467 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:12.468 3064-3064/? V/MediaCodecInfo: Listener-onTimelineChanged...
07-05 19:01:12.515 3064-3099/? V/SoftFFmpegVideo: got OMX_IndexParamPortDefinition, width: 320, height: 180
07-05 19:01:12.708 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:12.708 3064-3064/? V/MediaCodecInfo: Listener-onPlayerStateChanged...
07-05 19:01:13.380 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:13.655 3064-3064/? V/MediaCodecInfo: Listener-onLoadingChanged...
07-05 19:01:18.528 3064-3099/? V/SoftFFmpegVideo: ~SoftFFmpegVideo

尝试单击按钮但失败

fragmentExoBinding.button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            System.out.println("button click");
            releasePlayer();
        }
    });

每次我关闭它时它都会崩溃(使用后按,家庭或最近)b / c不再有播放器。使用 if (player != null) 更新了 releasePlayer() 方法,但即使在单击按钮后仍能听到播放的内容。

4

3 回答 3

2

我在 Activity 中使用 ExoPlayer,我使用的是两步过程。onPause我正在停止播放:

private SimpleExoPlayer player;     
@Override
protected void onPause() {
    super.onPause();

    // Pause video if it's playing
    if (isVideoPlaying()) {
        if (player != null)
            player.setPlayWhenReady(false);
    }
}

然后onDestroy我释放播放器

@Override
protected void onDestroy() {
    releasePlayer();
    super.onDestroy();
}

private void releasePlayer() {
        if (player != null) {
            player.stop();
            player.release();
            player = null;
        }
    }
于 2017-07-06T04:25:30.013 回答
0

你的问题表明onStop()Fragment的没有被调用。

您是否没有在两个屏幕上使用相同的Fragment对象或在其他地方创建另一个不必要的实例?

于 2018-05-11T05:00:11.840 回答
0

我有一个理论,但我不确定。为了避免写超过 9000 条评论,我会发布它是一个答案。

  1. <Button>如果您将 a 添加到您的布局并onClick()调用,播放器是否会停止(并被释放)releasePlayer();

  2. 如果上述方法有效,则覆盖您的活动onBackPressed(),并在调用之前super.onBackPressed(),获取片段的实例并调用releasePlayer(). 如果您想取悦 Java 人员并假装有一天您会对其进行单元测试,您可以让您的片段实现一些接口……或者您可以公开该方法并将其强制转换到您的片段并花费 5 秒而不是浪费 5 分钟和 16kb记忆 :)

无论如何,界面示例:

public interface BackHandlerListener {
    void onBackPressed();
}

然后让你的片段......

class MyFragment extends Fragment implements BackHandlerListener {
    @Override
    public void onBackPressed() {
        releasePlayer();
    }
}

还有你的活动……</p>

    @Override
    public void onBackPressed() {
        // get your fragment’s instance
        Fragment fragment =
         getSupportFragmentManager() 
            .findFragmentById(R.id.your_fragment_container);

        if (fragment instanceof BackHandlerListener) {
            ((BackHandlerListener) fragment).onBackPressed();
        }

        super.onBackPressed();
    }

你得到了演习。

  1. 如果 #1 不起作用,那么您的播放器就会发生一些奇怪的事情,它拒绝停止,但似乎与 Fragment 的生命周期有些无关。(*)

(*) 除非问题是当片段停止并且引用泄露时媒体播放器正在死机(因为它是本机代码)。如果是这样的话,恐怕我不得不阅读更多关于 ExoPlayer2 这些天是如何工作的(上次我使用媒体播放器时,ExoPlayer1 是一个“测试版”的东西,承诺会有更好的体验,但效果不佳与所有设备)。在那些日子里,我不得不使用 Android 服务来保持 MediaPlayer 并播放并将广播意图发送到我的服务来命令它。¯_(ツ)_/¯

于 2017-07-06T17:06:26.407 回答