- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我目前正在开发 Android 应用程序 ServeStream,我遇到了无法解决的问题。我的应用程序将使用 android MediaPlayer 类流式传输音乐和视频。我在以下位置找到的示例之后为我的类(class)建模:
此示例与我自己的代码之间的区别是我的 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/
到目前为止,我已经生成了以下代码来尝试将相关数据整合在一起。 但是,使用“+ 7”函数会产生以下问题。 Registration date = '2018-01-01' 它正在推迟 2018-04-0
我已经成功地将我的自定义购物车发布到 PayPal——它处理订单非常漂亮,当收到付款时,它会将数据发回我在配置中指定的 URL。代码基于此处找到的库:http://www.phpfour.com/bl
我是一名优秀的程序员,十分优秀!