Каков наилучший способ получить продолжительность аудиофайла в 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;
}