У меня есть следующий код, написанный для службы на Android, который воспроизводит видео с URL-адреса. Причина, по которой я пользуюсь услугой, заключается в том, что я хочу, чтобы медиаплеер сохранял воспроизведение звука при переключении с действия с видом поверхности на один без (например).Mediaplayer, используемый в службе на Android 2.3
Хотя код работает на Android 4.0+ устройств, у меня возникли проблемы, решая:
- Ошибка (100, 0)
- Ошибка (-38, 0)
При запуске на Android 2.3 (в настоящее время тестируется на Samsung Galaxy S1).
Ниже у вас есть код для моей службы:
/**
* The MediaPlayer instance
*/
private MediaPlayer mediaPlayer;
/**
* Boolean value indicating if the service is running or not.
*/
private static boolean videoServiceRunning = false;
/**
* Boolean value indicating if the video is playing or not.
*/
private static boolean videoPlaying = false;
/**
* Boolean value indicating if the video has not been started yet or if it has ended playing.
*/
private static boolean videoPrepared = false;
@Override
public void onCreate() {
super.onCreate();
Log.i(LOGTAG, "Service Started.");
mediaPlayer = new MediaPlayer();
videoServiceRunning = true;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("MyService", "Service Stopped.");
videoServiceRunning = false;
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
setVideoPlaying(false);
}
mediaPlayer.release();
}
catch (IllegalStateException e) {
e.printStackTrace();
sendMessageToActivity(MEDIAPLAYER_ERROR);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOGTAG, "Received start id " + startId + ": " + intent);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
return START_STICKY; // Run until explicitly stopped.
}
@Override
public IBinder onBind(Intent intent) {
Log.i(LOGTAG, "onBind");
return inMessenger.getBinder();
}
public static boolean isVideoServiceRunning()
{
return videoServiceRunning;
}
private void prepareVideo() {
try {
mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(videoURL));
mediaPlayer.setScreenOnWhilePlaying(true);
mediaPlayer.prepare();
setVideoPrepared(true);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
String message = isNetworkAvailable() ?
getApplicationContext().getString(R.string.movie_unavailable) :
getApplicationContext().getString(R.string.network_error);
sendErrorMessageToActivity(message);
}
}
private void play() {
try {
mediaPlayer.start();
setVideoPlaying(true);
sendMessageToActivity(MEDIAPLAYER_PLAYING);
}
catch (IllegalStateException e) {
e.printStackTrace();
sendMessageToActivity(MEDIAPLAYER_ERROR);
}
}
private void pause() {
try {
mediaPlayer.pause();
setVideoPlaying(false);
sendMessageToActivity(MEDIAPLAYER_PAUSED);
}
catch (IllegalStateException e) {
e.printStackTrace();
sendMessageToActivity(MEDIAPLAYER_ERROR);
}
}
private void coupleSurface() {
try {
SurfaceHolder surfaceHolder = SurfaceViewHolder.getInstance().getSurfaceHolder();
mediaPlayer.setDisplay(surfaceHolder);
sendMessageToActivity(MEDIAPLAYER_SURFACE_COUPLED);
}
catch (IllegalStateException e) {
e.printStackTrace();
sendMessageToActivity(MEDIAPLAYER_ERROR);
}
}
private void uncoupleSurface() {
try {
mediaPlayer.setDisplay(null);
sendMessageToActivity(MEDIAPLAYER_SURFACE_UNCOUPLED);
}
catch (IllegalStateException e) {
e.printStackTrace();
sendMessageToActivity(MEDIAPLAYER_ERROR);
}
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
setVideoPlaying(false);
sendMessageToActivity(MEDIAPLAYER_ENDED);
}
@Override
public void onPrepared(MediaPlayer mp) {
sendMessageToActivity(ACTIVITY_VIDEO_PREPARED);
VideoService.videoDuration = mediaPlayer.getDuration();
VideoService.videoWidth = mediaPlayer.getVideoWidth();
VideoService.videoHeight = mediaPlayer.getVideoHeight();
Runnable updateProgressRunnable = new Runnable() {
@Override
public void run() {
if (videoServiceRunning) {
currentPosition = -1;
try {
currentPosition = mediaPlayer.getCurrentPosition();
}
catch (IllegalStateException e) {
Log.e(LOGTAG, "An exception has occurred while trying to retrieve the current position: "+ e);
}
if (currentPosition != -1) {
SurfaceViewHolder.getInstance().updateSeekBarProgress(currentPosition);
}
//TODO should the handler continue scheduling the runnable for execution in case of an exception?
handler.postDelayed(this, 1000);
}
}
};
handler.postDelayed(updateProgressRunnable, 1000);
SurfaceHolder surfaceHolder = SurfaceViewHolder.getInstance().getSurfaceHolder();
mediaPlayer.setDisplay(surfaceHolder);
if (playVideo) {
play();
}
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(LOGTAG, "What: "+what+", Extra: "+extra);
return false;
}
public static synchronized boolean isVideoPlaying() {
return VideoService.videoPlaying;
}
public static synchronized void setVideoPlaying(boolean videoPlaying) {
VideoService.videoPlaying = videoPlaying;
}
public static synchronized boolean isVideoPrepared() {
return videoPrepared;
}
public static synchronized void setVideoPrepared(boolean videoPrepared) {
VideoService.videoPrepared = videoPrepared;
}
Кроме того, выход LogCat:
09-24 15:10:57.671: D/VideoService(5561): handleMessage: 4
09-24 15:10:57.765: D/VideoService(5561): handleMessage: 0
09-24 15:10:57.765: I/MediaPlayer(5561): uri is:http://techslides.com/demos/sample-videos/small.mp4
09-24 15:10:57.765: I/MediaPlayer(5561): path is null
09-24 15:10:57.769: D/MediaPlayer(5561): Couldn't open file on client side, trying server side
09-24 15:11:00.679: D/VideoService(5561): handleMessage: 1
09-24 15:11:08.718: I/dalvikvm(5561): threadid=4: reacting to signal 3
09-24 15:11:08.730: I/dalvikvm(5561): Wrote stack traces to '/data/anr/traces.txt'
09-24 15:11:12.214: D/VideoService(5561): handleMessage: 7
09-24 15:11:15.722: W/IMediaDeathNotifier(5561): media server died
09-24 15:11:15.726: E/MediaPlayer(5561): error (100, 0)
09-24 15:11:15.726: W/AudioSystem(5561): AudioFlinger server died!
09-24 15:11:15.753: E/MediaPlayer(5561): Error (100,0)
09-24 15:11:15.753: E/VideoService(5561): What: 100, Extra: 0
09-24 15:11:15.812: D/VideoService(5561): handleMessage: 1
09-24 15:11:15.812: E/MediaPlayer(5561): start called in state 0
09-24 15:11:15.812: E/MediaPlayer(5561): error (-38, 0)
09-24 15:11:15.921: E/MediaPlayer(5561): Error (-38,0)
09-24 15:11:15.921: E/VideoService(5561): What: -38, Extra: 0
09-24 15:11:16.996: D/VideoService(5561): handleMessage: 1
09-24 15:11:16.996: E/MediaPlayer(5561): start called in state 0
09-24 15:11:17.000: E/MediaPlayer(5561): error (-38, 0)
09-24 15:11:17.003: E/MediaPlayer(5561): Error (-38,0)
09-24 15:11:17.007: E/VideoService(5561): What: -38, Extra: 0
Пожалуйста, имейте в виду, что
- Это только тест- проект, поэтому я могу понять шаги, прежде чем внедрять это в приложение, над которым я работаю
- Я оставил часть класса VideoService относительно связи с Activity и из нее (поскольку авария связана с медиапланером).
- SurfaceViewHolder - одноэлементный элемент, используемый для хранения различных элементов пользовательского интерфейса (например, ссылка на индикатор выполнения или в настоящее время доступный SurfaceView, если таковой имеется), полезный для переключения между действиями (с различными пользовательскими интерфейсами) и сохранения воспроизведения видео (или сохранения звука на заднем плане)
LE:
После возвращения верно в onErrorListener на наличие ошибок 100 и -38 я получаю следующий результат LogCat всякий раз, когда я пытаюсь воспроизвести видео. Ошибка сервера Media Server по-прежнему присутствует.
09-25 11:07:12.226: E/AndroidRuntime(7921): Set to default setting_6 : region=-Duser.region=US propRegn=US
09-25 11:07:15.378: E/AndroidRuntime(7930): Set to default setting_6 : region=-Duser.region=US propRegn=US
09-25 11:07:19.097: E/AndroidRuntime(7946): Set to default setting_6 : region=-Duser.region=US propRegn=US
09-25 11:07:30.027: E/MediaPlayerService(7886): MediaPlayerService::mIsAnyDrmVideoPlaying : 0
09-25 11:07:30.449: E/SecHardwareRenderer(7886): Unable to create the overlay!
09-25 11:07:30.449: A/SoftwareRenderer(7886): frameworks/base/media/libstagefright/colorconversion/SoftwareRenderer.cpp:59 mConverter.isValid()
09-25 11:07:35.167: E/dalvikvm(1566): Failed to write stack traces to /data/anr/traces.txt (1627 of 2166): No such file or directory
09-25 11:07:35.941: E/dalvikvm(1642): Failed to write stack traces to /data/anr/traces.txt (816 of 2839): No such file or directory
09-25 11:07:37.449: E/dalvikvm(7751): Failed to write stack traces to /data/anr/traces.txt (1162 of 2250): No such file or directory
09-25 11:07:37.449: E/dalvikvm(7787): Failed to write stack traces to /data/anr/traces.txt (-1 of 2249): Math result not representable
09-25 11:07:37.468: E/dalvikvm(7763): Failed to write stack traces to /data/anr/traces.txt (-1 of 2250): Math result not representable
09-25 11:07:37.476: E/dalvikvm(7803): Failed to write stack traces to /data/anr/traces.txt (-1 of 3216): Math result not representable
09-25 11:07:37.796: E/dalvikvm(7954): Failed to write stack traces to /data/anr/traces.txt (-1 of 2376): Math result not representable
09-25 11:07:37.800: E/dalvikvm(7744): Failed to write stack traces to /data/anr/traces.txt (-1 of 2241): Math result not representable
09-25 11:07:37.804: E/dalvikvm(7907): Failed to write stack traces to /data/anr/traces.txt (-1 of 2230): Math result not representable
09-25 11:07:37.929: E/dalvikvm(7829): Failed to write stack traces to /data/anr/traces.txt (10370 of 13387): No such file or directory
09-25 11:07:44.617: E/MediaPlayer(7954): error (100, 0)
09-25 11:07:44.625: E/MediaPlayer(7954): Error (100,0)
09-25 11:07:44.632: E/VideoService(7954): What: 100, Extra: 0
09-25 11:07:45.074: E/SoundBooster(7989): readSBTable: file open error!
09-25 11:07:45.074: E/AcousticEQ(7989): [AEQ] aeqcoe.txt: file open error!
09-25 11:07:46.117: E/AudioService(1462): Media server died.
09-25 11:07:46.125: E/AudioService(1462): Media server started.
Надеюсь, кто-то с большим опытом, чем я, может мне помочь.
Заранее благодарен!
Ошибка 100 и ошибка -38 ничего не значат для меня. Я думаю, вы должны быть более конкретными, например, сообщения logcat. –
Добавлен вывод logcat, хотя, к сожалению, он не очень много говорит. – Eugen
Если эти выражения и коды ошибок исходят из 'e.printStackTrace();' calls, как насчет добавления дополнительной метки, чтобы вы могли видеть, какие из них генерируют эти ошибки. –