简体   繁体   English

MediaPlayer 只播放某些 WAV 文件

[英]MediaPlayer only plays certain WAV files

So the app I'm writing is hitting an API and getting base64 encoded WAV voicemails.所以我正在编写的应用程序正在访问 API 并获取 base64 编码的 WAV 语音邮件。 Decoding and creating the WAV file works but some will crash when calling setDataSource.解码和创建 WAV 文件是有效的,但在调用 setDataSource 时有些会崩溃。 I can pull the WAV files from my phones storage and play them on Mac so I know the file is being saved okay.我可以从我的手机存储中提取 WAV 文件并在 Mac 上播放它们,所以我知道文件正在保存。

The Base64 I'm decoding looks different and I can tell whether MediaPlayer will play it or not based on looking at it.我正在解码的 Base64 看起来不同,我可以通过查看它来判断 MediaPlayer 是否会播放它。 I have read that WAV file bitrates behave differently with MediaPlayer so I think that may be the issue?我已经读过 WAV 文件比特率与 MediaPlayer 的行为不同,所以我认为这可能是问题所在? The Base64 that doesn't play is much shorter than the Base64 that does even with the same audio duration.不播放的 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()
    }

Crash -碰撞 -

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)

Examples of the Base64 that plays vs not plays (Just shorter snippets of them)播放与不播放的 Base64 示例(只是它们的较短片段)

UklGRi96AABXQVZFZm10IBQAAAARAAEAQB8AANcPAAAAAQQAAgD5AWZhY3QEAAAAoPAAAGRhdGH7eQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwACqAA1CwyADYA2wQEgDeupwoNzQiub6tCiE1JYHJvLsYRDQSqMysiTBEM9QAGQCozLsKMDYkgcnLqxhTQxKozLuJQTQjktrbmikyNSKozLuLQDQkgrq9

^^ Does not play ^^ 不玩

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

^^ Does play ^^ 会玩

First sample is:第一个样本是:

RIFF (little-endian) data, WAVE audio, IMA ADPCM, mono 8000 Hz RIFF(小端)数据、WAVE 音频、IMA ADPCM、单声道 8000 Hz

second is:第二个是:

RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 16000 Hz RIFF(小端)数据,WAVE 音频,Microsoft PCM,16 位,单声道 16000 Hz

As per Supported media formats , under the details for PCM/WAVE :根据支持的媒体格式,在PCM/WAVE的详细信息下:

8- and 16-bit linear PCM (rates up to limit of hardware). 8 位和 16 位线性 PCM(速率达到硬件限制)。 Sampling rates for raw PCM recordings at 8000, 16000 and 44100 Hz. 8000、16000 和 44100 Hz 原始 PCM 录音的采样率。

In determining whether those files are linear PCM or not, from my reading of Pulse-code modulation , the second is linear PCM, whereas the former is adaptive differential PCM (ADPCM) so it may not be supported, hence what you are seeing.在确定这些文件是否为线性 PCM 时,根据我对脉冲编码调制的阅读,第二个是线性 PCM,而前者是自适应差分 PCM (ADPCM),因此它可能不受支持,因此您所看到的。

msbit's answer led me to looking at ways to play IMA ADPCM wav files on Android. msbit 的回答让我开始寻找在 Android 上播放 IMA ADPCM wav 文件的方法。 I decided to try swapping out MediaPlayer for ExoPlayer.我决定尝试将 MediaPlayer 换成 ExoPlayer。 ExoPlayer seems to be playing the files MediaPlayer couldn't. ExoPlayer 似乎正在播放 MediaPlayer 无法播放的文件。

Let's try to play one .wav file.让我们尝试播放一个 .wav 文件。 Let's say the name of your .wav file is test.wav and it is in res.raw folder in your android project.假设您的 .wav 文件的名称是 test.wav,它位于您的 android 项目的 res.raw 文件夹中。 Please try the following lines of code and let me know.请尝试以下代码行并告诉我。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM