Каков наилучший способ получить продолжительность аудиофайла в Android?

Я использую SoundPool для воспроизведения аудиоклипов в моем приложении. Все в порядке, но мне нужно знать, когда закончилось воспроизведение клипа.

В настоящий момент я отслеживаю его в своем приложении, получая продолжительность каждого клипа с помощью MediaPlayer. Это работает нормально, но выглядит бесполезно, чтобы загрузить каждый файл дважды, просто чтобы получить продолжительность. Я мог бы приблизительно рассчитать продолжительность, зная длину файла (доступный из AssetFileDescriptor), но мне все равно нужно знать частоты дискретизации и количества каналов.

Я вижу два возможных решения этой проблемы:

  • Выясните, когда клип закончил воспроизведение (кажется, это невозможно в SoundClip).
  • Наличие класса, который может загружать только заголовок аудиофайла и давать мне частоту выборки/количество каналов (и, в идеале, количество отсчетов для получения точной продолжительности).

Любые предложения?

Спасибо, Макс

Код, который я использую в данный момент (отлично работает, но для этой цели довольно тяжелый):

String[] fileNames = ...
MediaPlayer mp = new MediaPlayer();
for (String fileName : fileNames) {
    AssetFileDescriptor d = context.getAssets().openFd(fileName);
    mp.reset();
    mp.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength());
    mp.prepare();
    int duration = mp.getDuration();
    // ...
}

С другой стороны, этот вопрос уже был спросил, но не получил ответов.

Ответы

Ответ 1

Вы пробовали это:

String mediaPath = Uri.parse("android.resource://<your-package-name>/raw/filename").getPath();
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(mediaPath);
String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
mmr.release();

Но я не совсем уверен, что это легче, чем существующий код.

Ответ 2

Попробуйте FFmpegMediaMetadataRetriever:

String[] fileNames = ...
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();

for (String fileName : fileNames) {
    AssetFileDescriptor d = context.getAssets().openFd(fileName);
    mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength());
    String duration = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
}

mmr.release();

Ответ 3

это работа для меня, чтобы получить продолжительность аудиофайла активов в общей сложности секунд ===== →

MediaMetadataRetriever mmr = new MediaMetadataRetriever();
AssetFileDescriptor d = context.getAssets().openFd(fileName);
mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength());
String duration = 
mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
mmr.release();

Обновление

способ получения аудиофайла активов в секундах

  public String gettotaltimeassets() {

   MediaMetadataRetriever mmr = new MediaMetadataRetriever();
    AssetFileDescriptor d = null;
    try {
        d = getApplicationContext().getAssets().openFd("ASSETS FILE NAME");
    } catch (IOException e) {
        e.printStackTrace();
    }
    mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength());
    String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
    long dur = Long.parseLong(duration);
    String seconds = String.valueOf((dur % 60000) / 1000);
    Log.d("seconds===========>", seconds);
    mmr.release();
    return  seconds;
}

для получения продолжительности аудиофайла внутреннего хранилища в секундах

public String gettotaltimestorage(String filePath) {
    // load data file
    Log.d("time=================>","time=================>");
    MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
    metaRetriever.setDataSource(YourACTIVITY.this, Uri.parse(filePath));
    Log.d("time=================>","time=================>");
    String out = "";
    // get mp3 info

    // convert duration to minute:seconds
    String duration =
            metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
    Log.d("time=================>", duration);
    long dur = Long.parseLong(duration);
    String seconds = String.valueOf((dur % 60000) / 1000);
    Log.d("seconds===========>", seconds);
    // close object
    metaRetriever.release();
    return  seconds;

}