Android 中返回视频播放活动时出现黑屏
我目前正在开发 Android 应用程序 ServeStream,我遇到了无法解决的问题。我的应用程序将使用 android MediaPlayer 类流式传输音乐和视频。我按照以下位置的示例对我的类进行了建模:
区别在这个示例和我自己的代码之间,我的 MediaPlayer 在一个服务中运行,该服务允许它在后台继续播放。示例 Android 代码的问题是,如果我正在观看视频,并且离开当前窗口/活动(即按菜单按钮等)并返回到播放活动,我会看到黑屏,但仍会收到视频中的音频那是在玩。
当我的播放活动最初创建时,将执行下面所示的代码。此代码本质上创建用于播放的视图,然后将其绑定到媒体播放器:
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),因为它将当前视图/显示绑定到媒体播放器。当您离开活动时,视图(“持有者”)将被销毁。返回活动并重新创建视图后,再次执行 mMediaPlayer.setDisplay(holder) 似乎不会重新附加新创建的视图。显示黑屏而不是视频。
有谁有解决此问题的方法或解决方案。我将不胜感激任何帮助或建议。
I'm currently developing the android application ServeStream and I've encountered and problem that I can't fix. My application will stream music and video using the android MediaPlayer class. I've modeled my class after the example found at:
The difference between this example and my own code is my MediaPlayer is runs in a service which allows it to continue playback in the background. The problem with the example android code is if I'm watching a video and I leave the current window/activity (i.e press the menu button, etc) and return to the playback activity I get a black screen but still receive audio from the video that is playing.
When my playback activity is initially created the code shown below is executed. This code essentially creates the view used for playback and then ties it to the media player:
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);
The important line is mMediaPlayer.setDisplay(holder) because it ties the current view/display to the media player. The view (the "holder") is destroyed when you leave the activity. After returning to the activity and recreating the view, executing mMediaPlayer.setDisplay(holder) again doesn't appear to re-attach the newly created view. A black screen is shown instead of the video.
Does anyone have a workaround or solution for this issue. I would appreciate any help or advice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在对
MediaPlayer状态图进行了大量搜索和摸索之后code>,我终于设法避免了这种所谓的黑屏。我已经在 OP 的评论部分发布了这个问题似乎已在最新的 Android 版本(大于 4.x)中得到解决,因此我选择在 Gingerbread 设备上也有类似的行为。
不用说,
SurfaceHolder
回调方法在有界MediaPlayer
-SurfaceView
实现的生命周期中发挥着非常重要的作用。这些回调方法对我摆脱这种情况非常方便。首先:
在onCreate():内 - 基本初始化内容..
然后,
SurfaceView 回调:
不要忘记将
Display
设置为您的MediaPlayer
,恕我直言,surfaceCreated()
是这样做的最佳地点。这是最重要的事情。当用户通过按 Home 按钮或打开一个不同的 Activity 并期望得到任何结果来离开当前 Activity 时,我们的 SurfaceView 将被销毁。我想要实现的是从上下文切换时正在播放的位置恢复正在播放的视频。
因此,为了做到这一点,
请将当前播放位置保存在一个变量中,以便我们稍后可以使用它来寻找我们的播放到该特定位置。
还有一个。释放该死的
MediaPlayer
实例。我试图避免释放 MediaPlayer 实例并重新创建它,但我不断失败。所以..提出了观点。现在,onPrepared()
如果您有兴趣,请在此处初始化任何
MediaController
。检查视频是否已经在播放,然后将视频查找到该位置。最后,播放视频:
仅此而已。我知道新版本不存在这个问题,而且一切都很好,但是......仍然有很多 GB。
After lot of googling around and head-scratching over state diagram of
MediaPlayer
, I finally managed to avoid this so called black screen. I've already posted in the OP's comments section that this problem seems to be resolved with latest Android versions (greater than 4.x)and so I was opting to have similar behavior on Gingerbread devices as well.Needless to say,
SurfaceHolder
callback methods play a very crucial role in the lifecycle of a boundedMediaPlayer
-SurfaceView
implementation. And those very callback methods came handy to me for getting out of this situation.First:
inside onCreate(): - Basic initialization stuff..
Then,
SurfaceView Callbacks :
don't forget to set the
Display
to yourMediaPlayer
and IMHO,surfaceCreated()
is the best place to do that.And here's the most important thing. When user leaves the current activity by either pressing Home button or by opening a different activity with expecting any results, our
SurfaceView
is going to to be get destroyed. What I wanted to achieve was to resume the playback of ongoing video from the position it was playing when the context got switched.So, in order to do that,
Save the current playback position in a variable so that we can use it later on to seek our playback to that particular position.
And one more. Release the damn
MediaPlayer
instance. I tried to avoid releasing theMediaPlayer
instance and it's re-creation but I keep failing over and over. So..point made.Now, onPrepared()
Initialize any
MediaController
here if you're interested. Check if the video was already playing and so seek the video to that position.Finally, to play the video:
And that's all of it. I know the issue is not there with newer versions and all great but... lots of GBs are still out there.
我想我知道问题的原因。看来媒体播放器仅在调用prepare/Async()时才初始化其表面。如果之后你改变表面,你就会得到你所拥有的。因此,解决方案是通过 android:configChanges="orientation|keyboardHidden" 禁用活动的标准生命周期。这将妨碍您的娱乐活动。否则,您应该在每次重新创建持有人时要求准备。
I think I know the cause of the problem. It seems that mediaplayer initializes its surface ONLY when you call prepare/Async(). If you will change the surface after that, you will get what you`ve got. So the solution would be to disable standard lifecycle of activity via android:configChanges="orientation|keyboardHidden". This will prevent your activity from recreations. Otherwise you should call for prepare each time you recreate holder.
您可以执行以下操作:
mMediaPlayer.setDisplay(null)
当surfaceDestroy
时以及当您再次输入视频时setDisplay
为带有新surfaceHolder
的 mediaPlayer代码>.请记住,始终将此代码放在
onStart
内,因为当按下 home 或锁定屏幕时,它将强制使用新的持有者触发“sufaceCreate”。视图将被重新创建,视频将显示黑屏希望这有帮助!
You can do:
mMediaPlayer.setDisplay(null)
whensurfaceDestroy
and when you enter video againsetDisplay
for mediaPlayer with newsurfaceHolder
.Remember, always put this code below inside
onStart
, because when home pressed or lockscreen, it will force `sufaceCreate' fired with new holder. View will be recreated, video will show instead black screenHope this help!!
我有同样的问题!
播放视频时,我按“主页”按钮,然后返回到应用程序。我进入:
在
playVideo()
我有:我有空白的黑色背景并听到音频流。
我注意到,如果在第一次启动此 Activity 时,如果我不执行
player.setDisplay(holder);
,我将具有相同的行为。A花了两天时间试图解决这个问题......
I have the same issue!
While video is playing I press HOME button and then return to the Application. I get in:
In the
playVideo()
I have:And I have blank black background and hear audiostream.
I noticed that if in the first time of launching this Activity if I don't make
player.setDisplay(holder);
I will have the same behavior.A spent two days trying to solve this issue...
编辑:请注意,此解决方案不适用于 4.x 设备 - 视频根本不会出现,只有空白屏幕,我无法让它在那里工作。
这是一个执行以下操作的状态机:
1. 播放短几秒的视频 /res/raw/anim_mp4.mp4 (在 onCreate() 方法中启动的过程)
2. 如果用户按下主页按钮然后返回到应用程序,它将寻找视频的开始位置并立即暂停(在 onResume() 方法中启动的过程)
mediaplayer.xml 布局:
AndroidManifest.xml 如下所示:
EDIT: Please note this solution does not work on 4.x devices - video simply never appears, only blank screen and I couldn't make it work there.
Here's a state machine that does the following:
1. plays short couple of seconds video /res/raw/anim_mp4.mp4 (procedure initiated in onCreate() method)
2. if user presses home button then returns to app it will seek video to start position and pause immediatelly (procedure initiated in onResume() method)
mediaplayer.xml layout:
AndroidManifest.xml looks like:
我在 Galaxy S3 和 Xoom 平板电脑上播放视频时也遇到了同样的问题。我在播放器设置中关闭了硬件 (HW) 加速,它解决了问题。我不为 Android 开发,但希望这会引导您找到解决方案。也许您可以切换此设置以获得解决方法。我正在使用的设备可能没有硬件加速。
I saw the same issue simply playing video on my Galaxy S3 and on a Xoom Tablet. I turned off hardware (HW) acceleration in the player settings and it solved the problem. I don't develop for Android but hopefully this will lead you to a solution. Maybe you can toggle this setting for a workaround. The device I'm using might not have HW acceleration.
您希望返回时不显示该活动吗?
如果是,你可以简单地使用标志
如果你希望你的媒体在后台播放,我建议你使用视频表面,因为它一直让我在后台播放,尽管我不想要。方法有很多,但我希望这个方法能给你带来成果
http://www.brightec.co.uk/blog/custom-android -media-controller
这个链接实际上是用于根据您的意愿自定义媒体控制器,但当我用它创建我的媒体控制器时,我很烦恼按主页键,视频将在后台播放。
Do you want the activity not to be shown when you return?
if yes you can simply use flag
If you want your media to be played in background I suggest you to use video surface as it has been irritating me playing in background though I dont want. There are ways but I hope this one will be fruitful for you
http://www.brightec.co.uk/blog/custom-android-media-controller
this link actually is for customizing media controllers as you wish but as I created mine with it, I was bothered as pressing home key, the video would be played in background.