VB.net解码来自JSON Byte数组的MP3文件

时间:2014-06-10 12:42:22

标签: android json vb.net xmpp

有点奇怪!

我有大量Android(4.4.2)设备运行一些自定义传送跟踪软件(我写的) - 其中一项功能是录制语音报告并通过移动网络发送。它通常都工作得非常出色,但是我已经购买了一些新设备,突然所有的录音都以50kb的大小和0:00的长度进行。

现在,每个数据包都使用JSON进行编码,并通过XMPP(通过OpenFire)发送到用VB.NET编写的XMPP bot客户端(使用jabber) - 下面显示了一个示例数据包(我省略了一些,到期)它的长度,但你会得到一般的想法):

    {"mMessageType":{"batteryInfo":{"mHealth":2,"mLevel":84,
"mPlugged":2,"mStatus":2,"mTemp":318},"content":"VOICE",
"mType":"VOICE","userId":406},"mPayload":{"data":[0,0,0,24,
102,116,121,112,51,103,112,52,0,0,0,0,105,115,111,109,51,103,
112,52,0,0,5,8,109,111,111,118,0,0,0,108,109,118,104,100,0,
0,0,0,-49,-68,-88,-64,-49,-68,-88,-64,0,0,3,-24,0,0,14,36,0,
1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,27,117,100,116,97,
0,0,0,19,97,117,116,104,0,0,0,0,21,-57,76,71,69,0,47,0,0,4,
121,116,114,97,107,0,0,0,92,116,107,104,100,0,0,0,7,-49,-68,
-88,-64,-49,-68,-88,-64,0,0,0,1,0,0,0,0,0,0,14,36,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,4,21,
109,100,105,97,0,0,0,32,109,100,104,100,0,0,0,0,-49,-68,-88,
-64,-49,-68,-88,-64,0,0,31,64,0,0,113,32,0,0,0,0,0,0,0,44,
104,100,108,114,0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,
0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,0,0,0,
3,-63,109,105,110,102,0,0,0,16,115,109,104,100,0,0,0,0,0,0,
0,0,0,0,0,36,100,105,110,102,0,0,0,28,100,114,101,102,0,0,0,
0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1,0,0,3,-123,115,
116,98,108,0,0,0,69,115,116,115,100,0,0,0,0,0,0,0,1,0,0,0,
53,115,97,109,114,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,16,
0,0,0,0,31,64,0,0,0,0,0,17,100,97,109,114,32,32,32,0,0,
-125,-1,0,1,0,0,0,32,115,116,116,115,0,0,0,0,0,0,0,2,0,0,0,
1,0,0,0,-96,0,0,0,-76,0,0,0,-96,0,0,2,-24,115,116,115,122,0,
0,0,0,0,0,0,0,0,0,0,-75,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,
0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,
... Removed for sanity sake
,96],"timestamp":"","path":"/storage/emulated/0/audio_85344_1.3gp",
"reportedFully":0,"deliverySiteId":85344,"id":17,"reported":1}}

这是在这里输入我的.NET客户端:

 Public Sub ProcessVoiceMessage(ByVal o As Message)
    Dim messageObject = JsonConvert.DeserializeObject(Of Transaction)(o.Body)

    ' Incoming Message
    WriteToLog(o.From.User & "/" & o.From.Resource, "VOICE Transaction >> Device Record ID: " &
               messageObject.mPayload("id") & " - for DeliveryID: " & messageObject.mPayload("deliverySiteId"))
    Dim i As Long = 0
    Dim audioBytes(1024 * 50) As Byte

    For Each jval As JValue In messageObject.mPayload("data")
        Dim byteseses(1024 * 2) As Byte
        byteseses = BitConverter.GetBytes(jval.Value)
        audioBytes(i) = byteseses(0)
        i += 1
    Next

    Dim fn As String = IO.Path.Combine(IO.Path.GetTempPath, IO.Path.GetTempFileName & ".mp3")
    File.WriteAllBytes(fn, audioBytes)

    ' See if this payload is linked to a delivery drop, or that of a device level recording 
    ' (in which case, we save against the device object itself)
    If (CLng(messageObject.mPayload("deliverySiteId")) > 0) Then
        Dim ds As New DeliverySite(CLng(messageObject.mPayload("deliverySiteId")))
        ds.AddDocument(fn, GlobalStoreDocument.eAttachmentType.Upload, GlobalStoreDocument.eDocumentType.PODVoice, Nothing, ds.ParentDelivery.Driver.ID)


        Dim mt As New MessageType(MessageType.Type.CONFIRMATION)
        Dim conf As New Confirmation(ConfirmationStatus.ALL_OK,
                "VOICE",
                "GEE_THANKS!",
                messageObject.mPayload("id"))
        SendMessage(MakeTransactionPacket(mt, conf, o.From.Bare))

        ds.Dispose()
        ds = Nothing

        mt = Nothing
        conf = Nothing
    Else
        ' Device level voice recording
        Dim d As New Device(o.From.User)
        d.AddDocument(fn, GlobalStoreDocument.eAttachmentType.Upload, GlobalStoreDocument.eDocumentType.PODVoice, Nothing, CLng(messageObject.mMessageType("userId")))


        Dim mt As New MessageType(MessageType.Type.CONFIRMATION)
        Dim conf As New Confirmation(ConfirmationStatus.ALL_OK,
                "VOICE",
                "GEE_THANKS!",
                messageObject.mPayload("id"))
        SendMessage(MakeTransactionPacket(mt, conf, o.From.Bare))

        d.Dispose()
        d = Nothing

        mt = Nothing
        conf = Nothing
    End If

    IO.File.Delete(fn)
    messageObject = Nothing
    audioBytes = Nothing
End Sub

正如我之前所说的那样,它正在发挥作用,所以我立刻就像一只疯狂的猴子一样开始劈开它......(不用担心,我是所有的SVN' d!)它&# 39;显然是从JSON数组解码字节值的问题,因此转换回二进制格式,但我无法理解它。

**编辑** 应该真的添加所有的Android代码!用于语音报告的MediaRecorder:

    public void startRecording() 
    {       
        ++voiceRecordingNumber;

        filename = Environment.getExternalStorageDirectory().getPath();//.getAbsolutePath();
        if(this.d != null)
        {
            // FOR DELIVERY RECORDING OF PROOF //
            filename += String.format("/audio_%s_%d.%s", this.d.getDeliveryId(), voiceRecordingNumber, Constants.VOICE_EXT);
        }
        else
        {
            // FOR HOME SCREEN RECORDING OF PROOF //
            filename += String.format("/audio_PROOF_%s.%s", String.valueOf(System.currentTimeMillis()), Constants.VOICE_EXT);
        }

        Log.i("VoiceRecorder", "Startup");      

        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);                 // Default audio source
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);         // 3GPP Media File
        recorder.setOutputFile(filename);                                       // Output filename
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);            // audio codec
        recorder.setAudioSamplingRate(Constants.SAMPLERATES_MPEG1_L3[0]);       // Sample rate

        try 
        {
            recorder.prepare();
        } catch (IllegalStateException e) 
        {
            e.printStackTrace();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }

        Log.i("VoiceRecorder","Am prepared");       
        recorder.start();
    }

通过xmpp发送所有数据的后台进程:

        // Get a list of all voice recordings to send
        List<AudioRecording> audios = new AudioRecording().getAllRecords();
        for(AudioRecording a : audios)
        {
            // Process the audio files on local storage for sending over the wire
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            File audioFile = new File(a.getPath());
            InputStream is = new FileInputStream(audioFile);
            byte[] b = new byte[1024];
            int read;

            try
            {
                while((read = is.read(b)) >= 0)
                {
                    baos.write(b, 0, read);
                }
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
            finally
            {
                try 
                {
                    is.close();
                }
                catch (IOException e) 
                {           
                    e.printStackTrace();
                }
            }

            byte[] data = baos.toByteArray();
            a.setData(data);

            Log.i("BGCP", "Processing voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ")");

            Intent intent = new Intent(getApplicationContext(), BackgroundXmppConnector.class);
            intent.putExtra("MESSAGEDATA", new Gson().toJson(
                Utility.makeTransaction(getApplicationContext(),
                MessageType.Type.VOICE,
                a)));

            if(mService.sendMessage(intent))
            {
                Log.i("BGCP", "Voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ") HAS been reported");
                a.setReported(1);
                a.updateRecord();
            }
            else
            {
                Log.i("BGCP", "Voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ") HAS NOT been reported");
                // Ignore the updating of this record, it'll get sent out when we spin in 1 minute
            }

            b = null;           
            is = null;
            data = null;
            baos = null;
            intent = null;
            audioFile = null;
        }

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

通过将字节数组转换为Base64字符串并将其发送出去来解决此问题。解码现在变得更加容易:

    Dim ms As MemoryStream = GetVoiceRecordingFromString(messageObject.mPayload("dataAsString"))
    File.WriteAllBytes(fn, ms.ToArray())

方法

    Public Function GetVoiceRecordingFromString(ByVal s As String) As MemoryStream
    If s = "" Then
        Return Nothing
    End If

    Dim b As Byte() = Convert.FromBase64String(s)
    Using ms As MemoryStream = New MemoryStream(b, 0, b.Length)
        ms.Write(b, 0, b.Length)

        Return ms
    End Using
End Function