Coo*_*per 18 android surfaceview android-mediaplayer
我的xml文件:
<SurfaceView
android:id="@+id/surfaceView"
android:layout_marginTop="50dp"
android:layout_width="fill_parent"
android:layout_height="300dp" />
Run Code Online (Sandbox Code Playgroud)
我的setDisplay功能:
public void playVideo() {
MediaPlayer mp = new MediaPlayer();
SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView);
try {
mp.setDataSource("sdcard/test/a.3gp");
SurfaceHolder sh = sv.getHolder();
mp.setDisplay(sh);***----the exception occured here***
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
日志如下:
04-24 22:19:33.645: W/System.err(16106): java.lang.IllegalArgumentException: The surface has been released
04-24 22:19:33.645: W/System.err(16106): at android.media.MediaPlayer._setVideoSurface(Native Method)
04-24 22:19:33.645: W/System.err(16106): at android.media.MediaPlayer.setDisplay(MediaPlayer.java:698)
Run Code Online (Sandbox Code Playgroud)
我在这里发现了一些类似的问题,但所有这些都不适合我.等待你的答案.非常感谢.
Eya*_*sha 13
表面可以被破坏.这就是为什么你需要public void surfaceDestroyed(SurfaceHolder holder)像这样添加到SurfaceView的实现:
Run Code Online (Sandbox Code Playgroud)@Override public void surfaceDestroyed(SurfaceHolder holder) { synchronized (this) { hasActiveHolder = false; synchronized(this) { this.notifyAll(); } } }
您还应该添加一个处理Surface创建的函数:
Run Code Online (Sandbox Code Playgroud)@Override public void surfaceCreated(SurfaceHolder holder) { synchronized (this) { hasActiveHolder = true; this.notifyAll() } }
并以这种方式修改自己的功能:
mp.setDataSource("sdcard/test/a.3gp");
SurfaceHolder sh = sv.getHolder();
synchronized (this) {
while (!hasActiveHolder) {
try {
this.wait();
} catch (InterruptedException e) {
//Print something
}
}
mp.setDisplay(sh);
mp.prepare();
}
Run Code Online (Sandbox Code Playgroud)
您有另一种选择,就像Google建议您使用SurfaceView一样:在一个单独的线程中.
Muh*_*aat 10
这是与执行顺序相关的事情,因为必须在设置显示之前首先创建表面MediaPlayer,因此您必须将回调方法覆盖surfaceCreated到以下内容:
@Override
public void surfaceCreated(SurfaceHolder holder) {
mp.setDisplay(sh); // now "mp" is defined as a class variable
}
Run Code Online (Sandbox Code Playgroud)
现在你的play方法中没有setDisplay:
private MediaPlayer mp; // to use it inside surfaceCreated callback method
public void playVideo() {
mp = new MediaPlayer();
SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView);
try {
mp.setDataSource("sdcard/test/a.3gp");
SurfaceHolder sh = 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();
}
}
Run Code Online (Sandbox Code Playgroud)
使用 SurfaceHolder.Callback 如下
SurfaceView mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
SurfaceHolder holder = mSurfaceView.getHolder();
final MediaPlayer player = new MediaPlayer();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(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(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24732 次 |
| 最近记录: |