The Surface Has Been Released When I Try To Setdisplay To Mediaplayer
Solution 1:
The Surface can be destroyed. That's why you need to add to the a public void surfaceDestroyed(SurfaceHolder holder)
to your SurfaceView's implementation like this:
@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {
synchronized (this) {
hasActiveHolder = false;
synchronized(this) {
this.notifyAll();
}
}
}
You should also add a function that handles Surface creation:
@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
synchronized (this) {
hasActiveHolder = true;
this.notifyAll()
}
}
And modify your own function this way:
mp.setDataSource("sdcard/test/a.3gp");
SurfaceHoldersh= sv.getHolder();
synchronized (this) {
while (!hasActiveHolder) {
try {
this.wait();
} catch (InterruptedException e) {
//Print something
}
}
mp.setDisplay(sh);
mp.prepare();
}
You have another option which is the way Google suggests you use SurfaceView: in a separate thread.
Solution 2:
It's something related to the sequence of executing, as the surface has to be created first before setting display for the MediaPlayer
, so you have to override the callback method surfaceCreated
to the following:
@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
mp.setDisplay(sh); // now "mp" is defined as a class variable
}
and now there is no need to setDisplay inside your play method:
private MediaPlayer mp; // to use it inside surfaceCreated callback methodpublicvoidplayVideo() {
mp = newMediaPlayer();
SurfaceViewsv= (SurfaceView) this.findViewById(R.id.surfaceView);
try {
mp.setDataSource("sdcard/test/a.3gp");
SurfaceHoldersh= sv.getHolder();
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Solution 3:
The simplest way is just to call setDisplay
in surfaceCreated
:
@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
mp.setDisplay(holder)
}
and don't forget to unbind surface:
@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {
mp.setDisplay(null);
}
Note: media player should be initialized somewhere before, for example in onCreate
.
Solution 4:
Make use of SurfaceHolder.Callback as below
SurfaceViewmSurfaceView= (SurfaceView) findViewById(R.id.surfaceView);
SurfaceHolderholder= mSurfaceView.getHolder();
finalMediaPlayerplayer=newMediaPlayer();
holder.addCallback(newSurfaceHolder.Callback() {
@OverridepublicvoidsurfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
}
@OverridepublicvoidsurfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@OverridepublicvoidsurfaceDestroyed(SurfaceHolder holder) {
}
});
String UrlPath="android.resource://"+getActivity().getPackageName()+"/"+R.raw.your_file_name_without_extension;
try {
player.setDataSource(getActivity(),Uri.parse(UrlPath));
player.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
player.setOnPreparedListener(newMediaPlayer.OnPreparedListener() {
@OverridepublicvoidonPrepared(MediaPlayer mp) {
mp.start();
}
});
Solution 5:
For those still having issues, try implementing SurfaceHolder.Callback in your activity/fragment/etc and at the onCreate/onCreateView method, call the addCallback(SurfaceHolder.Callback callback) method, using your activity/fragment/etc as the parameter callback.
Post a Comment for "The Surface Has Been Released When I Try To Setdisplay To Mediaplayer"