返回Android中的视频播放活动时出现黑屏
我目前正在开发android应用程序ServeStream,遇到了无法修复的问题。我的应用程序将使用android MediaPlayer类流式播放音乐和视频。我根据以下示例对我的类进行建模: 此示例与我自己的代码之间的区别在于,我的MediaPlayer运行在一个允许它在后台继续播放的服务中。示例android代码的问题在于,如果我正在观看视频,我离开当前窗口/活动(即按下菜单按钮等)并返回到播放活动,我会看到一个黑屏,但仍然从正在播放的视频接收音频 最初创建播放活动时,将执行以下代码。此代码基本上创建用于播放的视图,然后将其绑定到媒体播放器:返回Android中的视频播放活动时出现黑屏,android,video,screen,media-player,playback,Android,Video,Screen,Media Player,Playback,我目前正在开发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);
重要的一行是mmediplayer.setDisplay(holder),因为它将当前视图/显示绑定到媒体播放器。当您离开活动时,视图(“持有者”)将被销毁。返回活动并重新创建视图后,再次执行mmediplayer.setDisplay(holder)似乎不会重新附加新创建的视图。显示的是黑屏而不是视频
是否有人对此问题有解决方法或解决方案。如果您能提供任何帮助或建议,我将不胜感激。我想我知道问题的原因。似乎只有在调用prepare/Async()时,mediaplayer才会初始化其表面。如果你在那之后改变表面,你会得到你所得到的。因此,解决方案是通过android:configChanges=“orientation | keyboardHidden”禁用活动的标准生命周期。这将阻止您的活动进行娱乐。否则,您应该在每次重新创建holder时致电prepare。我也有同样的问题 在播放视频时,我按HOME(主页)按钮,然后返回应用程序。我进去了:
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
playVideo();
}
在playVideo()
中,我有:
private void playVideo() {
if (extras.getString("video_path").equals("VIDEO_URI")) {
showToast("Please, set the video URI in HelloAndroidActivity.java in onClick(View v) method");
} else {
try {
if (flag == 0) {
player.setDataSource(extras.getString("video_path"));
player.prepareAsync();
flag = 1;
}
else
{
player.start();
}
} catch (IllegalArgumentException e) {
showToast("Error while playing video");
Log.i(TAG, "========== IllegalArgumentException ===========");
e.printStackTrace();
} catch (IllegalStateException e) {
showToast("Error while playing video");
Log.i(TAG, "========== IllegalStateException ===========");
e.printStackTrace();
} catch (IOException e) {
showToast("Error while playing video. Please, check your network connection.");
Log.i(TAG, "========== IOException ===========");
e.printStackTrace();
}
}
}
我有空白的黑色背景,听音频流
我注意到,如果在第一次启动此活动时,如果我没有制作player.setDisplay(holder)代码>我将有相同的行为
我花了两天时间试图解决这个问题……我看到同样的问题只是在Galaxy S3和Xoom平板电脑上播放视频。我关闭了播放器设置中的硬件(HW)加速,它解决了问题。我不为Android开发,但希望这将引导您找到一个解决方案。也许您可以切换此设置以解决问题。我正在使用的设备可能没有硬件加速功能。编辑:请注意,此解决方案在4.x设备上不起作用-视频根本不会出现,只有空白屏幕,我无法在那里工作。
这是一个执行以下操作的状态机:
1.播放短短几秒钟的视频/res/raw/anim_mp4.mp4(在onCreate()方法中启动的过程)
2.若用户按下home(主页)按钮,然后返回应用程序,它将查找视频到开始位置并立即暂停(过程在onResume()方法中启动)
package com.test.video;
导入android.app.Activity;
导入android.media.AudioManager;
导入android.media.MediaPlayer;
导入android.media.MediaPlayer.OnCompletionListener;
导入android.net.Uri;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.SurfaceHolder;
导入android.view.SurfaceView;
导入android.view.WindowManager;
公共类MediaPlayerActivity扩展了CompletionListener上的活动实现,
MediaPlayer.OnPreparedListener、MediaPlayer.OnSeekCompleteListener、SurfaceHolder.Callback{
私有最终整数状态未初始化=0;
私有最终整数状态_=1;
私有最终int状态_INITIALIZED=2;
私有最终整数状态_=3;
私有最终int状态_延迟=4;
私人最终int状态_播放=5;
私有最终int状态_FINISHED=6;
私有最终int状态_=7;
私有最终int状态\u恢复\u准备=8;
私有最终int状态恢复准备=9;
私有最终int状态恢复搜索=10;
private int state=未初始化的状态;
私人表面查看表面;
私人媒体播放器;
私人土地持有人;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
d(Constants.TAG,“onCreate()”);
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_全屏,
WindowManager.LayoutParams.FLAG(全屏);
setContentView(R.layout.mediaplayer);
表面=(表面视图)findViewById(R.id.idSurface);
holder=surface.getHolder();
holder.addCallback(本);
夹持器。设置类型(表面夹持器。表面夹持器类型推压缓冲);
}
@凌驾
受保护的void onStart(){
Log.d(Constants.TAG,“onStart()”);
super.onStart();
状态();
}
@凌驾
受保护的void onResume(){
d(Constants.TAG,“onResume()”);
super.onResume();
if(STATE_FINISHED==状态){
状态=恢复的状态;
状态();
}
}
@凌驾
受保护的空onDestroy(){
Log.d(Constants.TAG,“onDestroy()”);
super.ondestory();
如果(玩家!=null){
player.release();
player=null;
}
}
@凌驾
公共无效表面更改(表面更改arg0、int arg1、int arg2、int arg3){
Log.d(Constants.TAG,“surfaceChanged()”);
}
@凌驾
已创建公共空白表面(表面文件夹arg0){
Log.d(Constants.TAG,“surfaceCreated()”);
}
@凌驾
公共空间表面已覆盖(表面层arg0){
Log.d(Constants.TAG,“surfaceDestroyed()”);
}
@凌驾
已准备好公开作废(MediaPlayer mp){
Log.d(Constants.TAG,“onPrepared()”);
状态();
}
@凌驾
完成时的公共作废(MediaPlayer mp){
d(Constants.TAG,“onCompletion()”);
状态();
}
@凌驾
seekcomplete上的公共无效(MediaPlayer MediaPlayer){
d(Constants.TAG,“onSeekComplete()”);
package com.test.video;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class MediaPlayerActivity extends Activity implements OnCompletionListener,
MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener, SurfaceHolder.Callback {
private final int STATE_NOT_INITIALIZED = 0;
private final int STATE_INITIALIZING = 1;
private final int STATE_INITIALIZED = 2;
private final int STATE_SEEKING = 3;
private final int STATE_DELAYING = 4;
private final int STATE_PLAYING = 5;
private final int STATE_FINISHED = 6;
private final int STATE_RESUMED = 7;
private final int STATE_RESUMED_PREPARING = 8;
private final int STATE_RESUMED_PREPARED = 9;
private final int STATE_RESUMED_SEEKING = 10;
private int state = STATE_NOT_INITIALIZED;
private SurfaceView surface;
private MediaPlayer player;
private SurfaceHolder holder;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(Constants.TAG, "onCreate()");
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.mediaplayer);
surface = (SurfaceView) findViewById(R.id.idSurface);
holder = surface.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
protected void onStart() {
Log.d(Constants.TAG, "onStart()");
super.onStart();
state();
}
@Override
protected void onResume() {
Log.d(Constants.TAG, "onResume()");
super.onResume();
if (STATE_FINISHED == state) {
state = STATE_RESUMED;
state();
}
}
@Override
protected void onDestroy() {
Log.d(Constants.TAG, "onDestroy()");
super.onDestroy();
if (player != null) {
player.release();
player = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.d(Constants.TAG, "surfaceChanged()");
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.d(Constants.TAG, "surfaceCreated()");
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.d(Constants.TAG, "surfaceDestroyed()");
}
@Override
public void onPrepared(MediaPlayer mp) {
Log.d(Constants.TAG, "onPrepared()");
state();
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(Constants.TAG, "onCompletion()");
state();
}
@Override
public void onSeekComplete(MediaPlayer mediaplayer) {
Log.d(Constants.TAG, "onSeekComplete()");
state();
}
private class ResumeDelayed extends PlayDelayed {
protected void onPostExecute(Void result) {
Log.d(Constants.TAG, "ResumeDelayed.onPostExecute()");
state();
};
}
private void initPlayer() {
Log.d(Constants.TAG, "initPlayer()");
try {
if (player == null) {
player = new MediaPlayer();
player.setScreenOnWhilePlaying(true);
} else {
player.stop();
player.reset();
}
String uri = "android.resource://" + getPackageName() + "/" + R.raw.anim_mp4;
player.setDataSource(this, Uri.parse(uri));
player.setDisplay(holder);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.prepareAsync();
player.setOnCompletionListener(this);
player.setOnSeekCompleteListener(this);
} catch (Throwable t) {
Log.e(Constants.TAG, "Exception in media prep", t);
}
}
private class PlayDelayed extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... arg0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(Constants.TAG, "Can't sleep", e);
}
return null;
}
protected void onPostExecute(Void result) {
Log.d(Constants.TAG, "PlayDelayed.onPostExecute()");
initPlayer();
};
}
private void state() {
switch (state) {
case STATE_NOT_INITIALIZED:
state = STATE_INITIALIZING;
initPlayer();
break;
case STATE_INITIALIZING:
state = STATE_INITIALIZED;
new PlayDelayed().execute();
break;
case STATE_INITIALIZED:
state = STATE_SEEKING;
player.start();
player.seekTo(0);
break;
case STATE_SEEKING:
state = STATE_DELAYING;
player.pause();
new ResumeDelayed().execute();
break;
case STATE_DELAYING:
state = STATE_PLAYING;
player.start();
break;
case STATE_PLAYING:
state = STATE_FINISHED;
break;
case STATE_RESUMED:
state = STATE_RESUMED_PREPARING;
initPlayer();
break;
case STATE_RESUMED_PREPARING:
state = STATE_RESUMED_PREPARED;
new PlayDelayed().execute();
break;
case STATE_RESUMED_PREPARED:
state = STATE_RESUMED_SEEKING;
player.start();
player.seekTo(0);
break;
case STATE_RESUMED_SEEKING:
state = STATE_FINISHED;
player.pause();
break;
default:
break;
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/black" >
<SurfaceView
android:id="@+id/idSurface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.video"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="@drawable/ic_launcher"
android:theme="@android:style/Theme.Black.NoTitleBar" >
<activity
android:name=".MediaPlayerActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
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);
@Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
try {
player.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (player != null) {
mCurrentVideoPosition = player.getCurrentPosition();
player.release();
player = null;
}
}
@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();
}
}
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);