두 개의 조각 (왼쪽 및 오른쪽)이 있고 왼쪽 분할에서 Radiostreams 목록을 가져 왔습니다. 이러한 스트림 중 하나를 클릭하면 오른쪽 조각이 스트림의 이름을 변경하고 주어진 URI를 사용하여 스트림 재생을 시작해야합니다.Android MediaPlayer AudioStream AudioFlinger 서버가 사망했습니다., 치명적인 신호 11
2 문제 :
- 라디오 스트림의 일부는 그래서 그들 중 많은 더 이상 작동하지 않습니다,하지 최신 있습니다. 문제는, 내 응용 프로그램이 강제 폐쇄를 일으키는 것입니다! 나는 오류 처리를했지만 이러한 스트림을 호출 한 후 내가 얻을 : 나는 이유를 알고하지 않습니다
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)를 호출하기 전에 모든 스트림을 검사 할 수있는 방법이 있습니까? (내 코드를 참조하십시오)
- 리모컨으로 왼쪽 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있어로드 할 수없는 경우
my fix https://stackoverflow.com/a/47992111/4592448 – Fortran