簡體   English   中英

VB.net從JSON字節數組解碼MP3文件

[英]VB.net decoding MP3 file from JSON Byte array

有點奇怪!

我有很多運行一些自定義交付跟蹤軟件(我寫過)的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搞砸了!)這顯然是解碼的問題。 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;
        }

任何幫助是極大的贊賞。 謝謝!

通過僅將字節數組轉換為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM