MediaPlayer 只播放某些 WAV 文件

Posted

技术标签:

【中文标题】MediaPlayer 只播放某些 WAV 文件【英文标题】:MediaPlayer only plays certain WAV files 【发布时间】:2020-10-01 00:19:12 【问题描述】:

所以我正在编写的应用程序正在使用 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 示例(只是更短的 sn-ps)

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//

^^ 会玩

【问题讨论】:

【参考方案1】:

第一个样本是:

RIFF(小端序)数据、WAVE 音频、IMA ADPCM、单声道 8000 Hz

第二个是:

RIFF(小端序)数据、WAVE 音频、Microsoft PCM、16 位、单声道 16000 Hz

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

8 位和 16 位线性 PCM(速率达到硬件限制)。 8000、16000 和 44100 Hz 原始 PCM 录音的采样率。

在确定这些文件是否为线性 PCM 时,根据我对Pulse-code modulation 的阅读,第二个是线性 PCM,而前者是自适应差分 PCM (ADPCM),因此它可能不受支持,因此您所看到的.

【讨论】:

绝对让我朝着正确的方向前进!谢谢。【参考方案2】:

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于MediaPlayer 只播放某些 WAV 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 MediaPlayer 类从内存播放 WAV 文件

delphi怎么用mediaplayer播放资源?

Android使用AudioTrack播放WAV音频文件

求助:关于C#中使用axwindowsmediaplayer 播放wav文件的问题

Android Studio Java MediaPlayer 只播放音频的第一秒然后停止

求助:C#中使用axwindowsmediaplayer 播放wav文件的问题