android - 返回到 Android 中的视频播放 Activity 时出现黑屏

标签 android video screen media-player playback

我目前正在开发 Android 应用程序 ServeStream,我遇到了无法解决的问题。我的应用程序将使用 android MediaPlayer 类流式传输音乐和视频。我在以下位置找到的示例之后为我的类(class)建模:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.html

此示例与我自己的代码之间的区别是我的 MediaPlayer 在允许它在后台继续播放的服务中运行。示例 android 代码的问题是,如果我正在观看视频并离开当前窗口/Activity (即按菜单按钮等)并返回播放 Activity ,我会出现黑屏但仍会收到来自视频的音频正在播放。

最初创建我的播放 Activity 时,会执行下面显示的代码。此代码实质上创建了用于播放的 View ,然后将其绑定(bind)到媒体播放器:

        setContentView(R.layout.mediaplayer_2);
        mPreview = (SurfaceView) findViewById(R.id.surface);
        holder = mPreview.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
...
        mMediaPlayer.setDisplay(holder);

重要的一行是 mMediaPlayer.setDisplay(holder) 因为它将当前 View /显示绑定(bind)到媒体播放器。当您离开 Activity 时, View (“持有者”)将被销毁。返回 Activity 并重新创建 View 后,再次执行 mMediaPlayer.setDisplay(holder) 似乎不会重新附加新创建的 View 。显示黑屏而不是视频。

有没有人有解决此问题的方法或解决方案。如果有任何帮助或建议,我将不胜感激。

最佳答案

经过大量谷歌搜索和头疼 state diagram MediaPlayer,我终于设法避免了这种所谓的黑屏。我已经在 OP 的评论部分发布了这个问题似乎已通过最新的 Android 版本(高于 4.x)解决,因此我也选择在 Gingerbread 设备上有类似的行为。

不用说,SurfaceHolder 回调方法在有界 MediaPlayer-SurfaceView 实现的生命周期中起着非常关键的作用。这些回调方法对我摆脱这种情况非常有用。

首先:

onCreate() 中: - 基本的初始化内容..

    mVideoSurface = (SurfaceView) findViewById(R.id.videoSurface);
    videoHolder = mVideoSurface.getHolder();
    videoHolder.addCallback(this);

    // For Android 2.2

    videoHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    // Media Player and Controller

    player = new MediaPlayer();
    controller = new VideoControllerView(this);

然后, SurfaceView 回调:

不要忘记将 Display 设置为您的 MediaPlayer 和恕我直言,surfaceCreated() 是执行此操作的最佳位置。

@Override
 public void surfaceCreated(SurfaceHolder holder) {
    player.setDisplay(holder);
    try {
    player.prepareAsync();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
}

这是最重要的事情。当用户通过按下 Home 按钮或打开一个不同的 Activity 并期待任何结果离开当前 Activity 时,我们的 SurfaceView 将被销毁。我想要实现的是在上下文切换时从正在播放的位置恢复正在进行的视频的播放。 所以,为了做到这一点,

将当前播放位置保存在一个变量中,以便我们稍后可以使用它来寻找播放到该特定位置。 还有一个。释放该死的 MediaPlayer 实例。我试图避免释放 MediaPlayer 实例,它是重新创建的,但我不断失败。所以..点了。

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (player != null) {
        mCurrentVideoPosition = player.getCurrentPosition();
        player.release();
        player = null;
    }

}

现在,onPrepared() 如果您有兴趣,请在此处初始化任何 MediaController。检查视频是否已经在播放,然后将视频搜索到该位置。

     @Override
 public void onPrepared(MediaPlayer mp) {
    controller.setMediaPlayer(this);
    controller.setAnchorView((FrameLayout) findViewById(R.id.videoSurfaceContainer));
    player.start();

    if (mCurrentVideoPosition != 0) {
        player.seekTo(mCurrentVideoPosition);
        player.start();
    }

}

最后,播放视频:

 void playVideo(){  

   try {
        if (player == null) 
            player = new MediaPlayer();
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setDataSource("SOME_VIDEO_FILE.3gp");
        player.setOnPreparedListener(this);
        player.setOnErrorListener(new OnErrorListener() {

            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                mp.reset();
                return false;
            }
        });

    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
     }

仅此而已。我知道问题不存在于较新的版本中,一切都很好,但是......仍然有很多 GB。

关于android - 返回到 Android 中的视频播放 Activity 时出现黑屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6347924/

相关文章:

javascript - Html5 视频 - 在屏幕上点击播放/暂停视频

swift - 如何制作方形视频?

javascript - 从 YOUTUBE URL 获取视频 ID,然后将其插入文本区域

ionic-framework - IONIC-我无法转换 'image to base64'

html - 如何使移动屏幕的图像居中(使用 HTML)?

android - 屏幕像素和显示像素有什么区别

android - 在文本输入布局android之外单击时如何将 float 标签文本重置为其原始位置

android - 检查设备上次连接互联网的时间

android - WifiManager.setWifiEnabled 在 hive 上无法正常工作

java - 应用程序连接到 Firebase 时程序崩溃