gpt4 book ai didi

Android MediaPlayer AudioStream AudioFlinger 服务器死了!,致命信号 11

转载 作者:太空宇宙 更新时间:2023-11-03 11:16:46 28 4
gpt4 key购买 nike

我有两个 fragment (左和右)并在左侧 fragment 中获取 radio 流列表。通过单击这些流之一,正确的 fragment 应该更改流的名称并开始使用给定的 uri 播放流。

2个问题:

  1. 一些 radio 流不是最新的,所以其中很多都不再工作了。问题是,这会导致我的应用强制关闭!我做了错误处理,但在调用这样的流后我得到:

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...

我不知道为什么。还有其他方法可以进行错误处理吗?或者有没有办法在调用 mediaPlayer.setDataSource(uri) 之前检查所有流以避免准备 defekt uris? (最后看我的代码)

  1. 我正在使用 Remote 控制左侧的 ListFragment。当我尝试从一个 channel 快速切换到另一个 channel 时,一切都非常滞后。似乎 Mediaplayer 的 reinstanciation 需要很长时间。当我不重新实例化时,再次调用 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(右侧 fragment )。注意:每次单击列表项时,左侧 fragment 都会从 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.getState() == MediaPlayerStateWrapper.State.ERROR 时:

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

最好放在AsyncTask中,避免Not responding error。或者,当您遇到错误时,您必须创建一个新的 MediaPlayer,因为 Media Server 已死:

if(mediaWrapper.getState() == MediaPlayerStateWrapper.State.ERROR){
mediaWrapper = new MediaPlayerStateWrapper();
mediaWrapper.setDataSource(radioCh.getUrl().toString());
mediaWrapper.prepareAsync();
}

如果 MediaPlayer 正在播放流,您必须先停止并重置它:

mediaWrapper.stop();
mediaWrapper.reset();
mediaWrapper.setDataSource(radioCh.getUrl().toString());
mediaWrapper.prepareAsync();

它对我有用,但我认为这不是最好的方法。当您陷入准备状态时,希望有人能找到更好的解决方案。

关于Android MediaPlayer AudioStream AudioFlinger 服务器死了!,致命信号 11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15526023/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com