从 Base64 字符串慢声音转换而来的 Android 播放 PCM 字节数组 [英] Android Play PCM byte array from Converted from Base64 String Slow Sounds

查看:29
本文介绍了从 Base64 字符串慢声音转换而来的 Android 播放 PCM 字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如很长的标题所暗示的那样,我无法播放我通过网络通过 PubNunb.我所做的是使用以下代码从 AudioRecord 录制时发送音频:

As the very long title suggests, I'm having trouble playing the audio from a audio that I send over the network through PubNunb. What I do is I send the audio while recording from AudioRecord using this code:

 AudioConfig audioConfig = getValidSampleRates(AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    buffer = new byte[audioConfig.getBufferSize()];

    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, audioConfig.getSampleSize(), AudioFormat.CHANNEL_IN_MONO, AUDIO_FORMAT, audioConfig.getBufferSize());

当用户按住按钮时发送记录的数据:

Recorded data is sent when the user holds the button down:

   private class RecorderRunnable implements Runnable {
    @Override
    public void run() {
        while(mRecording) {
            Log.d("RECORDER_STATE", "Recording LOOP");
            recorder.read(buffer, 0, buffer.length);

            String base64EncodedBuffer = Base64.encodeToString(buffer, Base64.NO_WRAP);

            pubnub.publish(MainActivity.CHANNEL_ID, base64EncodedBuffer, new Callback() {
                @Override
                public void successCallback(String channel, Object message) {
                    super.successCallback(channel, message);
                }
            });
        }
    }
}

接收代码:

       @Override
                    public void successCallback(String channel, final Object message) {


                        byte[] decodedBase64 = Base64.decode(message.toString(), Base64.NO_WRAP);

                        speaker.write(decodedBase64, 0, decodedBase64.length);
                    }

问题:我得到了音频,但我得到的声音真的很慢.你好"听起来像:"嘻-*静态*-ll-*静态*-oo"

Issue: I get the audio, but I get sounds that are really slow. "Hello" would sound like: "Hee-*static*-ll-*static*-oo"

为了排除可能的原因,我立即尝试播放这样的音频(没有网络):

To rule out possible causes, I tried immediately playing the audio like this (without the network):

 while(mRecording) {
            Log.d("RECORDER_STATE", "Recording LOOP");
            recorder.read(buffer, 0, buffer.length);

            String base64EncodedBuffer = Base64.encodeToString(buffer, Base64.NO_WRAP);

            byte[] decodedBase64 = Base64.decode(base64EncodedBuffer, Base64.NO_WRAP);

            speaker.write(decodedBase64, 0, decodedBase64.length);
        }

(注意:我故意转换为 base64 并返回到字节数组.)

上面代码的结果(录音后直接播放)还是不错的.所以我想知道通过网络处理它时我做错了什么.

The result for the code above (directly playing it after recording) is pretty good. So I'm wondering what I'm doing wrong when handling it over the network.

任何建议表示赞赏.谢谢你.

Any suggestion is appreciated. Thank you.

08/28/2015这里.但现在的问题是,使用我当前的实现处理网络抖动/缓冲和丢包的最佳方法是什么.

08/28/2015 Found a good explanation for this here. But now the question is, what's the best way of handling network jitter/buffering and packetloss using my current implementation.

推荐答案

pubnub 通过 tcp 传递数据 (不是 udp).http://www.pubnub.com/knowledge-base/discussion/263/does-pubnub-support-the-udp-protocol

pubnub delivers data through tcp (not udp). http://www.pubnub.com/knowledge-base/discussion/263/does-pubnub-support-the-udp-protocol

在您的应用程序中应该不需要处理数据包丢失.

There should be no need to handle packet loss in your application.

您可能需要通过创建某种缓冲区来处理抖动.由于没有严格的实时约束,我将讨论一种方法而不是粘贴代码.

You may need to handle jitter by creating a buffer of some sort. Since there would be no rigid realtime constraint, I will discuss an approach rather than pasting code.

您可以使用队列创建缓冲区.我建议有两个线程.一个给你的读者(你的播放器),一个给作者(网络流).在让读者阅读之前,让作者排队一些数据(可能是几秒钟的数据).在纸面上,通过非常简单的概念证明,您应该不会遇到同时读取和写入的问题,因为作者正在写入队列的末尾而读者正在队列的开头读取.

You can make a buffer using a queue. I suggest having two threads. One for your reader (your player) and one for writer (the network stream). Let the writer queue up some data (maybe a few seconds of data) before letting the reader read. On paper, with a very simply proof of concept, you should not have issues with simultaneous reads and writes since the writer is writing to the end of the queue and the reader is reading at the beginning of the queue.

把它想象成一个半满的桶.你往里倒水,让水以同样的速度漏出.

Think of it as a bucket that is halfway full. You pour water in and let water leak out at the same rate.

这篇关于从 Base64 字符串慢声音转换而来的 Android 播放 PCM 字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆