2013-09-24 2 views
0

У меня есть следующий код, написанный для службы на 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. 

Надеюсь, кто-то с большим опытом, чем я, может мне помочь.

Заранее благодарен!

+0

Ошибка 100 и ошибка -38 ничего не значат для меня. Я думаю, вы должны быть более конкретными, например, сообщения logcat. –

+0

Добавлен вывод logcat, хотя, к сожалению, он не очень много говорит. – Eugen

+0

Если эти выражения и коды ошибок исходят из 'e.printStackTrace();' calls, как насчет добавления дополнительной метки, чтобы вы могли видеть, какие из них генерируют эти ошибки. –

ответ

0

Начало действия в состоянии 0 (-38) означает, что вы вызываете начало, прежде чем правильно настроить носитель и подготовить его. Ошибка 100 - это сообщение с сообщением о медиа-сервере. В любом случае вы поставляете недопустимые носители и запускаете вызов. Перед подготовкой и запуском следует добавить некоторые операторы if, а также обработать вывод ошибок в обратных вызовах onInfo и onError для MediaPlayer.

Редактировать: В обработчике onError различают фатальные ошибки и нефатальные ошибки. Верно true для нефатальных ошибок, указывающих на то, что ошибка была обработана. Возврат false сообщает MediaPlayer для вызова обработчика onCompletion и остановки. Я часто вижу ошибку «медиа-сервер», и это не обязательно означает, что носитель недействителен (как вы отметили). Извините, я этого раньше не замечал.

+0

Спасибо, Дейв. Я знаю, я искал ошибки. Тем не менее, носитель действителен (я передаю URL-адреса в .mp4 on-line видео), и логика выглядит нормально, так как я использую это в устройствах Android 4.0 и работает так, как ожидалось. Если предложения будут останавливать мое приложение только на «onPrepared», на самом деле не решить ошибку 100. – Eugen

+0

См. Мое редактирование. Не все ошибки, переданные onError, являются фатальными, поэтому вы не всегда должны возвращать false. – Dave

+0

Спасибо. Я рассмотрю это и дам вам знать, что я разработал. – Eugen

Смежные вопросы