MediaPlayer 只播放某些 WAV 文件

MediaPlayer only plays certain WAV files

所以我正在编写的应用程序正在点击 API 并获取 base64 编码的 WAV 语音邮件。解码和创建 WAV 文件是可行的,但有些会在调用 setDataSource 时崩溃。我可以从我的手机存储中提取 WAV 文件并在 Mac 上播放它们,所以我知道文件保存正常。

我正在解码的 Base64 看起来不一样,我可以根据它来判断 MediaPlayer 是否会播放它。我读过 WAV 文件比特率与 MediaPlayer 的行为不同,所以我认为这可能是问题所在?即使相同的音频时长,不播放的 Base64 比播放的 Base64 短得多。

    try {
        val fileInputStream = FileInputStream(voicemailFile)

        if (audioManager == null) {
            audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager?
        }

        audioManager?.let { audioManager ->
            audioManager.isSpeakerphoneOn = isSpeakerPhoneOn
            audioManager.mode = AudioManager.MODE_IN_CALL
        }

        mediaPlayer.setAudioAttributes(AudioAttributes
                .Builder()
                .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
                .build())

        mediaPlayer.setDataSource(fileInputStream.fd)
        mediaPlayer.setOnCompletionListener {
            finishPlayingVoicemail()
        }

        mediaPlayer.prepare()

        currentProgress?.let { currentProgress ->
            mediaPlayer.seekTo(currentProgress)
        }

        mediaPlayer.start()

        shouldResumePlaying = true

        fileInputStream.close()
    } catch (e: Exception) {
        e.printStackTrace()
    }

崩溃-

E/GenericSource: initFromDataSource, cannot create extractor!
E/GenericSource: Failed to init from data source!
E/MediaPlayerNative: error (1, -2147483648)
W/System.err: java.io.IOException: Prepare failed.: status=0x1
W/System.err: at android.media.MediaPlayer.prepare(MediaPlayer.java:1274)

播放与不播放的 Base64 示例(只是其中的较短片段)

UklGRi96AABXQVZFZm10IBQAAAARAAEAQB8AANcPAAAAAQQAAgD5AWZhY3QEAAAAoPAAAGRhdGH7eQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwACqAA1CwyADYA2wQEgDeupwoNzQiub6tCiE1JYHJvLsYRDQSqMysiTBEM9QAGQCozLsKMDYkgcnLqxhTQxKozLuJQTQjktrbmikyNSKozLuLQDQkgrq9

^^ 不玩

UklGRqTvAwBXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YYDvAwD//wAAAAD/////AAD/////AAAAAP///f/+/wEAAgD///z/+v/6//3//v/+//3//v/9//3//v8BAAEA/v/6//j//P8CAAAA9//1//v//P/4//f//P/+//z/9//0//j//v8AAPv/+f/7//z/+v/5//v//P/8//v/+f/6/////P/1//b//f/9//f/9f/6//3/+//4//b/+v8CAAAA9//0//r//f/8//v//f/+//3/+v/5//v///8AAP7//f8AAP///P/7//3//v/8//v//P///wIAAAD7//

^^ 会玩吗

让我们尝试播放一个 .wav 文件。假设您的 .wav 文件的名称是 test.wav,它位于 android 项目的 res.raw 文件夹中。请尝试以下代码行并告诉我。

Media mPlayer;
private Context mContext;
mPlayer = MediaPlayer.create(mContext, R.raw.test);
mPlayer.start();

第一个样本是:

RIFF (little-endian) data, WAVE audio, IMA ADPCM, mono 8000 Hz

第二个是:

RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 16000 Hz

根据 Supported media formats,在 PCM/WAVE 的详细信息下:

8- and 16-bit linear PCM (rates up to limit of hardware). Sampling rates for raw PCM recordings at 8000, 16000 and 44100 Hz.

在判断这些文件是否是线性PCM时,根据我的阅读Pulse-code modulation,第二种是线性PCM,而前者是自适应差分PCM(ADPCM),所以它可能不受支持,因此你看到了什么。

msbit 的回答让我开始寻找在 Android 上播放 IMA ADPCM wav 文件的方法。我决定尝试将 MediaPlayer 换成 ExoPlayer。 ExoPlayer 似乎正在播放 MediaPlayer 无法播放的文件。