在 Android 中获取音频文件持续时间的最佳方法是什么?

发布于 2024-10-12 11:28:13 字数 1273 浏览 7 评论 0原文

我正在使用 SoundPool 来播放我的应用程序中的音频剪辑。一切都很好,但我需要知道剪辑播放何时完成。

目前,我通过使用 MediaPlayer 实例。这工作得很好,但为了获取持续时间而加载每个文件两次看起来很浪费。我可以粗略地计算自己知道文件长度的持续时间(可从 AssetFileDescriptor),但我仍然需要知道采样率和通道数。

我看到了该问题的两个潜在解决方案:

  1. 确定剪辑何时完成播放(使用 SoundClip 似乎不可能)。
  2. 有一个类可以仅加载音频文件的标头并为我提供采样率/通道数(理想情况下,还可以提供样本计数以获得准确的持续时间)。

有什么建议吗?

谢谢, Max

我目前使用的代码(工作正常,但对于目的来说相当沉重):

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();
    // ...
}

顺便说一句,这个问题已经询问但没有得到答案。

I'm using a SoundPool to play audio clips in my app. All is fine but I need to know when the clip playback has finished.

At the moment I track it in my app by obtaining the duration of each clip using a MediaPlayer instance. That works fine but it looks wasteful to load each file twice, just to get the duration. I could roughly calculate the duration myself knowing the length of the file (available from the AssetFileDescriptor) but I'd still need to know the sample rate and the number of channels.

I see two potential solutions to that problem:

  1. Figuring out when a clip has finished playing (doesn't seem to be possible with SoundClip).
  2. Having a class which could load just the header of an audio file and give me the sample rate/number of channels (and, ideally, the sample count to get the exact duration).

Any suggestions?

Thanks,
Max

The code I'm using at the moment (works fine but is rather heavy for the purpose):

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();
    // ...
}

On a side note, this question has already been asked but got no answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爺獨霸怡葒院 2024-10-19 11:28:13

您是否尝试过此操作:

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

但我不确定这是否比现有代码更轻。

Did you try this:

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

But i am not exactly sure that this is lighter than exisiting code.

谷夏 2024-10-19 11:28:13

尝试 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();

Try 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();
夜巴黎 2024-10-19 11:28:13

这对我来说是为了获取资产音频文件持续时间(以总秒为单位)=====>

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;

}

this is work for me to get assets audio file duration in total seconds=====>

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

Updated

method to get assets audio file duration in seconds

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

method to get internal storage audio file duration in 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;

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文