задержка звука в Android

1

Я пытаюсь воспроизвести звук при нажатии кнопки, но есть некоторая задержка между тем, когда я нажимаю кнопку и когда звук воспроизводится. Я получаю эту ошибку: AudioFlinger(17396): write blocked for 162 msecs, 3 delayed writes, thread 0x15440 Это то, что я получил до сих пор:

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

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) {
        mediaPlayer = 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);
    }
  }
}

Любые подсказки?

Спасибо заранее.

редактирует: Поэтому я добавил синглтон, и он помог, но все еще задерживается. Вот как это выглядит сейчас:

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;
        }
    });

Любые идеи? То, что я пытаюсь сделать, это как барабан, поэтому кнопки должны отвечать правильно.

Теги:

2 ответа

0
Лучший ответ

I/O на Android работает медленно. Звуковая подсистема вынуждена ждать его данных и достаточно любезна, чтобы предупредить об этом.

Вместо того, чтобы предоставить MediaPlayer необработанный FileDescriptor (который не будет применять буферизацию), попробуйте использовать файл://URI. При любой удаче поставщик системного контента для файла: он будет буферизовать его для вас в момент его открытия.

  • 0
    Хотелось бы увидеть некоторые критерии по этому вопросу - я уверен, что вы правы
  • 0
    Я пытался сделать это, как вы сказали, безуспешно. Это все еще играет отложено. Вот что я получил: mediaPlayer.setDataSource(pathToFile); mediaPlayer.prepare(); где pathToFile - это строка. Есть какие-нибудь подсказки?
Показать ещё 8 комментариев
0

Я действительно не знаю Android в глубину, но, глядя на этот код, вы могли бы попробовать использовать AudioPlayer в качестве одноэлементного и повторно использовать экземпляр MediaPlayer?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню