Поверхность была выпущена, когда я пытаюсь установить Disisplay в MediaPlayer
Мой xml файл:
<SurfaceView
android:id="@+id/surfaceView"
android:layout_marginTop="50dp"
android:layout_width="fill_parent"
android:layout_height="300dp" />
Моя функция 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();
}
}
журнал, как показано ниже:
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)
Здесь я нашел несколько подобных вопросов, но все они не подходят для меня. Жду ваших ответов. Большое спасибо.
Ответы
Ответ 1
Поверхность может быть уничтожена. Для этого вам нужно добавить a public void surfaceDestroyed(SurfaceHolder holder)
к реализации SurfaceView следующим образом:
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
synchronized (this) {
hasActiveHolder = false;
synchronized(this) {
this.notifyAll();
}
}
}
Вы также должны добавить функцию, которая обрабатывает создание поверхности:
@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();
}
У вас есть еще один вариант, который Google предлагает использовать SurfaceView: в отдельном потоке.
Ответ 2
Это что-то связано с последовательностью выполнения, так как поверхность должна быть создана сначала, прежде чем устанавливать отображение для MediaPlayer, so you have to override the callback method
surfaceCreated` на следующее:
@Override
public void surfaceCreated(SurfaceHolder holder) {
mp.setDisplay(sh); // now "mp" is defined as a class variable
}
и теперь нет необходимости устанавливать отображение внутри вашего метода воспроизведения:
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();
}
}
Ответ 3
Для тех, у кого проблемы, попробуйте выполнить SurfaceHolder.Callback в своей деятельности/фрагменте/etc и в методе onCreate/onCreateView, вызовите addCallback ( SurfaceHolder.Callback callback), используя вашу активность/фрагмент/etc в качестве обратного вызова параметра.
Ответ 4
Самый простой способ - просто позвонить setDisplay
в surfaceCreated
:
@Override
public void surfaceCreated(SurfaceHolder holder) {
mp.setDisplay(holder)
}
и не забудьте развязать поверхность:
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mp.setDisplay(null);
}
Примечание. Медиа-плеер должен быть инициализирован где-то раньше, например, в onCreate
.
Ответ 5
Используйте 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();
}
});