[英]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.