4

두 개의 조각 (왼쪽 및 오른쪽)이 있고 왼쪽 분할에서 Radiostreams 목록을 가져 왔습니다. 이러한 스트림 중 하나를 클릭하면 오른쪽 조각이 스트림의 이름을 변경하고 주어진 URI를 사용하여 스트림 재생을 시작해야합니다.Android MediaPlayer AudioStream AudioFlinger 서버가 사망했습니다., 치명적인 신호 11

2 문제 :

  1. 라디오 스트림의 일부는 그래서 그들 중 많은 더 이상 작동하지 않습니다,하지 최신 있습니다. 문제는, 내 응용 프로그램이 강제 폐쇄를 일으키는 것입니다! 나는 오류 처리를했지만 이러한 스트림을 호출 한 후 내가 얻을 : 나는 이유를 알고하지 않습니다

03-20 14:23:28.192: A/libc(1021): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)

03-20 14:23:28.192: W/AudioSystem(1021): AudioFlinger server died!

03-20 14:23:28.192: W/IMediaDeathNotifier(1021): media server died

03-20 14:23:28.192: E/MediaPlayer(1021): error (100, 0)

03-20 14:23:28.192: I/ServiceManager(1021): Waiting for service media.audio_flinger...

03-20 14:23:28.752: I/dalvikvm(1021): threadid=3: reacting to signal 3

03-20 14:23:28.782: I/dalvikvm(1021): Wrote stack traces to '/data/anr/traces.txt'

03-20 14:23:29.192: I/ServiceManager(1021): Waiting for service media.audio_flinger...

. 오류 처리를 수행하는 다른 방법이 있습니까? 아니면 defekt uris 준비를 피하기 위해 mediaPlayer.setDataSource (uri)를 호출하기 전에 모든 스트림을 검사 할 수있는 방법이 있습니까? (내 코드를 참조하십시오)

  1. 리모컨으로 왼쪽 ListFragment를 제어하고 있습니다. 한 채널에서 다른 채널로 매우 빠르게 전환하려고하면 모든 것이 매우 뒤떨어집니다. Mediaplayer의 재발행은 매우 오래 걸리는 것으로 보입니다. 내가 다시 인스턴스화하지 않으면 mediaPlayer.setDataSource (..)를 다시 호출 할 때 런타임 오류가 발생합니다. 하나의 MediaPlayer 객체에서 .setDataSource를 두 번 호출하는 방법이 있습니까? 내 MediaPlayer를 래퍼 클래스 :

    package net.smart4life.tvplay.model; 
    
    import java.io.IOException; 
    import java.lang.reflect.Method; 
    import java.util.AbstractCollection; 
    import java.util.ArrayList; 
    import java.util.EnumSet; 
    import java.util.HashMap; 
    import java.util.Iterator; 
    import java.util.Map; 
    import android.media.AudioManager; 
    import android.media.MediaPlayer; 
    import android.media.MediaPlayer.OnBufferingUpdateListener; 
    import android.media.MediaPlayer.OnCompletionListener; 
    import android.media.MediaPlayer.OnErrorListener; 
    import android.media.MediaPlayer.OnInfoListener; 
    import android.media.MediaPlayer.OnPreparedListener; 
    import android.util.Log; 
    
    /** 
    * A wrapper class for {@link android.media.MediaPlayer}. 
    * <p> 
    * Encapsulates an instance of MediaPlayer, and makes a record of its internal 
    * state accessible via a {@link MediaPlayerWrapper#getState()} accessor. 
    */ 
    public class MediaPlayerStateWrapper { 
    
        private static String tag = "MediaPlayerWrapper"; 
        private MediaPlayer mPlayer; 
        private State currentState; 
        private MediaPlayerStateWrapper mWrapper; 
    
        public MediaPlayerStateWrapper() { 
         mWrapper = this; 
         mPlayer = new MediaPlayer(); 
         currentState = State.IDLE; 
         mPlayer.setOnPreparedListener(mOnPreparedListener); 
         mPlayer.setOnCompletionListener(mOnCompletionListener); 
         mPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener); 
         mPlayer.setOnErrorListener(mOnErrorListener); 
         mPlayer.setOnInfoListener(mOnInfoListener); 
        } 
    
        /* METHOD WRAPPING FOR STATE CHANGES */ 
        public static enum State { 
         IDLE, ERROR, INITIALIZED, PREPARING, PREPARED, STARTED, STOPPED, PLAYBACK_COMPLETE, PAUSED; 
        } 
    
        public void setDataSource(String path) { 
         if (currentState == State.IDLE) { 
          try { 
           mPlayer.setDataSource(path); 
           currentState = State.INITIALIZED; 
          } catch (IllegalArgumentException e) { 
           e.printStackTrace(); 
          } catch (IllegalStateException e) { 
           e.printStackTrace(); 
          } catch (IOException e) { 
           e.printStackTrace(); 
          } 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void prepareAsync() { 
         Log.d(tag, "prepareAsync()"); 
         if (EnumSet.of(State.INITIALIZED, State.STOPPED).contains(currentState)) { 
          mPlayer.prepareAsync(); 
          currentState = State.PREPARING; 
         } else 
          throw new RuntimeException(); 
        } 
    
        public boolean isPlaying() { 
         Log.d(tag, "isPlaying()"); 
         if (currentState != State.ERROR) { 
          return mPlayer.isPlaying(); 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void seekTo(int msec) { 
         Log.d(tag, "seekTo()"); 
         if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, 
           State.PLAYBACK_COMPLETE).contains(currentState)) { 
          mPlayer.seekTo(msec); 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void pause() { 
         Log.d(tag, "pause()"); 
         if (EnumSet.of(State.STARTED, State.PAUSED).contains(currentState)) { 
          mPlayer.pause(); 
          currentState = State.PAUSED; 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void start() { 
         Log.d(tag, "start()"); 
         if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, 
           State.PLAYBACK_COMPLETE).contains(currentState)) { 
          mPlayer.start(); 
          currentState = State.STARTED; 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void stop() { 
         Log.d(tag, "stop()"); 
         if (EnumSet.of(State.PREPARED, State.STARTED, State.STOPPED, 
           State.PAUSED, State.PLAYBACK_COMPLETE).contains(currentState)) { 
          mPlayer.stop(); 
          currentState = State.STOPPED; 
         } else 
          throw new RuntimeException(); 
        } 
    
        public void reset() { 
         Log.d(tag, "reset()"); 
         mPlayer.reset(); 
         currentState = State.IDLE; 
        } 
    
        /** 
        * @return The current state of the mediaplayer state machine. 
        */ 
        public State getState() { 
         Log.d(tag, "getState()"); 
         return currentState; 
        } 
    
        public void release() { 
         Log.d(tag, "release()"); 
         mPlayer.release(); 
        } 
    
        /* INTERNAL LISTENERS */ 
        private OnPreparedListener mOnPreparedListener = new OnPreparedListener() { 
    
         @Override 
         public void onPrepared(MediaPlayer mp) { 
          Log.d(tag, "on prepared"); 
          currentState = State.PREPARED; 
          mWrapper.onPrepared(mp); 
          mPlayer.start(); 
          currentState = State.STARTED; 
         } 
        }; 
        private OnCompletionListener mOnCompletionListener = new OnCompletionListener() { 
    
         @Override 
         public void onCompletion(MediaPlayer mp) { 
          Log.d(tag, "on completion"); 
          currentState = State.PLAYBACK_COMPLETE; 
          mWrapper.onCompletion(mp); 
         } 
        }; 
        private OnBufferingUpdateListener mOnBufferingUpdateListener = new OnBufferingUpdateListener() { 
    
         @Override 
         public void onBufferingUpdate(MediaPlayer mp, int percent) { 
          Log.d(tag, "on buffering update"); 
          mWrapper.onBufferingUpdate(mp, percent); 
         } 
        }; 
        private OnErrorListener mOnErrorListener = new OnErrorListener() { 
    
         @Override 
         public boolean onError(MediaPlayer mp, int what, int extra) { 
          Log.d(tag, "on error"); 
          currentState = State.ERROR; 
          mWrapper.onError(mp, what, extra); 
          return false; 
         } 
        }; 
        private OnInfoListener mOnInfoListener = new OnInfoListener() { 
    
         @Override 
         public boolean onInfo(MediaPlayer mp, int what, int extra) { 
          Log.d(tag, "on info"); 
          mWrapper.onInfo(mp, what, extra); 
          return false; 
         } 
        }; 
    
        /* EXTERNAL STUBS TO OVERRIDE */ 
        public void onPrepared(MediaPlayer mp) { 
        } 
    
        public void onCompletion(MediaPlayer mp) { 
        } 
    
        public void onBufferingUpdate(MediaPlayer mp, int percent) { 
        } 
    
        boolean onError(MediaPlayer mp, int what, int extra) { 
         // Error Handling of type: "MEdiaPlayer error(100,0) 
         mp.stop(); 
         mp.release(); 
         return false; 
        } 
    
        public boolean onInfo(MediaPlayer mp, int what, int extra) { 
         return false; 
        } 
    
        /* OTHER STUFF */ 
        public int getCurrentPosition() { 
         if (currentState != State.ERROR) { 
          return mPlayer.getCurrentPosition(); 
         } else { 
          return 0; 
         } 
        } 
    
        public int getDuration() { 
         // Prepared, Started, Paused, Stopped, PlaybackCompleted 
         if (EnumSet.of(State.PREPARED, State.STARTED, State.PAUSED, 
           State.STOPPED, State.PLAYBACK_COMPLETE).contains(currentState)) { 
          return mPlayer.getDuration(); 
         } else { 
          return 100; 
         } 
        } 
    } 
    

    가 여기 내 TestFragment (오른쪽 조각)입니다

여기 내 코드입니다. 참고 : 왼쪽 단편은 ListItem이 클릭 될 때마다 TestFragment에서 "newChannel (radioChannel)"메소드를 호출합니다.

package net.smart4life.tvplay.fragment; 

import java.io.IOException; 

import net.smart4life.tvplay.R; 
import net.smart4life.tvplay.model.MediaPlayerStateWrapper; 
import net.smart4life.tvplay.model.RadioChannel; 
import android.app.Fragment; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnErrorListener; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import android.widget.Toast; 

public class TestFragment extends Fragment { 

    private RadioChannel radioCh; 
    private TextView tv_RadioCh; 
    private MediaPlayerStateWrapper mediaWrapper; 
    private View view; 


    // firstcall 
    public TestFragment(RadioChannel radioChannel) { 
     this.radioCh = radioChannel; 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onActivityCreated(savedInstanceState); 

     setRetainInstance(true); 

     tv_RadioCh = (TextView) view.findViewById(R.id.radioText); 

     mediaWrapper = new MediaPlayerStateWrapper(); 

     newChannel(radioCh); 
    } 

    public void newChannel (RadioChannel radioChannel) { 
     this.radioCh = radioChannel; 
     Log.e("RadioChannel", radioCh.getName()); 
     tv_RadioCh.setText(radioCh.getName()); 

     if(mediaWrapper.isPlaying()) { 
      mediaWrapper.stop(); 
      mediaWrapper.reset(); 
     } else if(mediaWrapper.getState() == MediaPlayerStateWrapper.State.PREPARING) { 
      mediaWrapper.release(); 
      mediaWrapper = new MediaPlayerStateWrapper(); 
     } 
     mediaWrapper.setDataSource(radioCh.getUrl().toString());  
     mediaWrapper.prepareAsync(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 

     view = inflater.inflate(R.layout.fragment_radio_player, container, 
       false); 

     return view; 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 

     mediaWrapper.release(); 
    } 

} 

찬성, 한 가지 또는 두 가지 질문으로 저를 도울 수 있습니까? 응답하지 을 방지하기 위해,

mediaWrapper.reset(); 
mediaWrapper.release(); 
System.gc(); 
mediaWrapper = new MediaPlayerStateWrapper(); 
mediaWrapper.setDataSource(radioCh.getUrl().toString()); 
mediaWrapper.prepareAsync(); 

최저은 AsyncTask에 넣어 : 스트림 당신이 준비 상태에서 종종 stucked있어로드 할 수없는 경우

+0

my fix https://stackoverflow.com/a/47992111/4592448 – Fortran

답변

관련 문제