开发者

delayed audio in android

i'm trying to play audio when a button is clicked but there's some delay between when i press the button and when the audio is actually played. I get this error: AudioFlinger(17396): write blocked for 162 msecs, 3 delayed writes, thread 0x15440 This is what i got so far:

ImageButton i = (ImageButton)findViewById(R.id.button);
        i.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_DOWN){
                    s = new AudioPlayer(getApplicationContext());
                    s.playSound(R.raw.conga1);
            }
            return true;
            }
        });

AudioPlayer class

public class AudioPlayer {

  private MediaPlayer mediaPlayer;
  private final OnCompletionListener mediaPlayerListener = new MediaPlayerListener();
  private Context context = null;

  public AudioPlayer(Context context)
  {
    this.context = context;
    init();
  }

  private void init() {
    if (mediaPlayer == null) {
      AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
      int streamVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
      mediaPlayer = new MediaPlayer();
      mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
      mediaPlayer.setOnCompletionListener(mediaPlayerListener);
      mediaPlayer.setVolume(streamVolume, streamVolume);
    }
  }

  private void setSound(int id) {
    if (mediaPlayer!=null) {
      mediaPlayer.reset();
      AssetFileDescriptor file = context.getResources().openRawResourceFd(id);
      try {
        mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
        file.close();
        mediaPlayer.prepare();
      } catch (IOException e) {
        medi开发者_开发知识库aPlayer = null;
      }
    }
  }

  public void playSound(int id) {
    if (mediaPlayer!=null) {
      setSound(id);
      mediaPlayer.start();
    }
  }

  private static class MediaPlayerListener implements OnCompletionListener {
    public void onCompletion(MediaPlayer mediaPlayer) {
      mediaPlayer.seekTo(0);
    }
  }
}

Any clues?

Thanks in advance.

EDITS: So i added a singleton and it helped but there's still delay. This is how it looks like now:

AudioPlayer:

public static synchronized AudioPlayer getSingletonObject(Context context, Uri pathToFile) {
    if (audioPlayer == null) {
        audioPlayer = new AudioPlayer(context, pathToFile);
    }
    return audioPlayer;
}

public void setSound(String pathToFile) {
    if (mediaPlayer!=null) {
        mediaPlayer.reset();

        try {
            mediaPlayer.setDataSource(pathToFile);
            mediaPlayer.prepareAsync();
        } //catch....
    }
}

public void playSound(String path) {
    if (mediaPlayer!=null) {
        mediaPlayer.reset();

        try {
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepareAsync();
            mediaPlayer.start();
        } //catch...
    }
}

Main:

final String path = "sdcard/myappsounds/snaredrum2.wav";
    final AudioPlayer s = AudioPlayer.getSingletonObject(getApplicationContext(), Uri.parse(path));
    s.setSound(path);

    ImageButton i = (ImageButton)findViewById(R.id.button);
    i.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){

                s.playSound(path);
        }
        return true;
        }
    });

Any ideas? What i'm trying to do is like a drumset, that's why the buttons must respond correctly.


I/O on Android is slow. The audio subsystem is being forced to wait for it's data, and is kind enough to warn about it.

Rather than giving MediaPlayer a raw FileDescriptor (which will have no buffering applied) try using a file:// URI. With any luck the system content provider for file: will buffer it up for you the moment it's opened.


I don't really know Android in depth, but from looking at this code what you could try is to use your AudioPlayer as a singleton and reuse your MediaPlayer instance?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜