Android 如何获取 WAV 文件的音频时长

在 Android 开发中,我们经常需要获取音频文件的时长信息。本文将介绍如何使用 Android 提供的 API 来获取 WAV 文件的音频时长。

1. WAV 文件格式简介

WAV(Waveform Audio File Format)是一种常见的音频文件格式,它存储了原始音频数据以及音频的元数据信息,如采样率、声道数等。WAV 文件的头部包含了一些固定的信息,其中包括音频的时长。

2. 获取 WAV 文件的音频时长

要获取 WAV 文件的音频时长,我们需要读取 WAV 文件的头部信息,并解析其中的时长字段。

下面是一个示例代码,演示了如何获取 WAV 文件的音频时长:

import android.media.MediaMetadataRetriever;

public class AudioUtils {

    public static long getWavDuration(String filePath) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        retriever.setDataSource(filePath);

        String durationString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        long duration = Long.parseLong(durationString);

        retriever.release();

        return duration;
    }

}

在上面的代码中,我们使用了 MediaMetadataRetriever 类来获取 WAV 文件的元数据信息。该类是 Android 提供的一个用于检索音频、视频文件元数据的工具类。

首先,我们创建一个 MediaMetadataRetriever 对象,并通过调用 setDataSource 方法将 WAV 文件的路径传递给它。然后,我们使用 extractMetadata 方法来提取指定的元数据信息,其中 METADATA_KEY_DURATION 表示音频的时长。

最后,我们将获取到的时长字符串转换为 long 类型,并返回结果。

3. 示例

接下来,我们将通过一个示例来演示如何使用上述代码来获取 WAV 文件的音频时长。

首先,我们需要在 Android 项目中添加读取外部存储权限,以便能够读取 WAV 文件。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

然后,我们在界面中添加一个按钮和一个文本框,用于选择 WAV 文件和显示音频时长。

<Button
    android:id="@+id/btn_select_file"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Select WAV File" />

<TextView
    android:id="@+id/tv_duration"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

接下来,我们在活动中处理点击按钮事件,并调用 getWavDuration 方法获取 WAV 文件的音频时长:

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_SELECT_FILE = 1;

    private Button btnSelectFile;
    private TextView tvDuration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSelectFile = findViewById(R.id.btn_select_file);
        tvDuration = findViewById(R.id.tv_duration);

        btnSelectFile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this,
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                            REQUEST_CODE_SELECT_FILE);
                } else {
                    selectWavFile();
                }
            }
        });
    }

    private void selectWavFile() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("audio/wav");
        startActivityForResult(intent, REQUEST_CODE_SELECT_FILE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_SELECT_FILE && grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            selectWavFile();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_SELECT_FILE && resultCode == RESULT_OK) {
            Uri uri = data.getData();
            String filePath = FileUtils.getPath(this, uri);
            long duration = AudioUtils.getWavDuration(filePath);
            tvDuration.setText("Duration: " + duration