Closed OneBobone closed 5 years ago
Yep, it's probably UTF-8. It comes from the audio source directly, as does the "astm" data. I don't know what it means -- song time in milliseconds?
Cover art can be any picture format; again it comes straight from the audio source and is encoded in BASE64 form. I have observed JPEGs and PNGs.
Sorry for being dense:
Hmm, I maybe don’t need to know all the background, but my problem remains.
The data encoded in utf-8 from the udp stream minus the header “ssndpict” looks very similar, but still different than other jpgs. The characters/bytes have the same position but are sometimes slightly different. The file will not be accepted as pictures in viewers (chunked or not) or online picture repair sites. It makes me think that the utf8 bytes are encoded correctly, but the more advanced bytes are not.
Or should I separate out the header, then encode back the rest to base64 and then decode to some other format for the jpg file? (The middle step is obviously unnecessary, but written for clarity)
The metadata was originally intended for output over a unix pipe. Later work by another contributor put it out on UDP. Have a look in the sample metadata reader for hints, and also have a look in RTSP.c for some information.
There doesn't seem to be any metadata indicating the format of the picture -- you have to look at the raw data.
I imagine the artwork is copyright, BTW, so sharing it with other sites is really a questionable practice.
Thx for the tip. WIll have a look. To other public sites, definitely questionable, for private use between screens, I think less. :-)
UTF7 gives the closest results, but not good enough. Think I have to give up for now... I am puzzled.
I finally solved this more more less well. There where two problems:
Read also (wish it were better sorted): https://github.com/tchapi/shairport-sync-ui/blob/master/DMAP_DAAP_Codes.md
For Cover art, it is best to save the UDP byte stream directly to a file. Howeever, I searched for "PICT" in the UTF8 encoded string (the right coding), and then used that position to cut out the right array from the UDP stream.
Chunking does not seem to work perfectly and caused some headache. Not all bytes make it through in the second chunk. The final "ssncpcen" after the last chunk is also not present (maybe it is in the last chunk...)
hs.Writelog(LogLabel, "Opened Shairport UDP Server")
Try
While hs.GetVar("ApReceive") = True
Dim UDPbytes As Byte() = listener.Receive(groupEP)
Metadata = Encoding.UTF8.GetString(UDPbytes, 0, UDPbytes.Length)
PICTpos = instr(1, Metadata, "ssncPICT")
astmpos = instr(1, Metadata, "coreastm")
If PICTpos > 0 Then ' This is where image creation takes place
If instr(1, Metadata, "ssncchnk") Or UDPbytes.Length > 10000 Then ' Discard a standard thumbnail
Dim filePath As String = "C:\Program Files\HomeSeer HS3\html\images\Shairport\Thumbnails\"
Dim fileName As String = trim(hs.GetVar("ApArtist")) & " - " & trim(hs.GetVar("ApTitle")) & ".jpg"
PICTpos = PICTpos + 7
Dim mySubArray(Ubound(UDPbytes) - PICTpos) As Byte
System.Array.Copy(UDPbytes, PICTpos, mySubArray, 0, mySubArray.Length - 1) 'Could be: mySubArray.Length - 0 ?
My.Computer.FileSystem.WriteAllBytes(filePath & fileName, mySubArray, True) ' Always append
File.Copy(filePath & fileName, filePath & "CurrentApThumbnail.jpg", True) ' Always overwrite
Hs.waitsecs(0.3)
End If
ElseIf astmpos > 0 Then ' Determine Duration
astmpos = astmpos + 7
Dim mySubArray(3) As Byte
System.Array.Copy(UDPbytes, astmpos, mySubArray, 0, 4)
Array.Reverse(mySubArray)
hs.SaveVar("ApDuration", int(BitConverter.ToInt32(mySubArray, 0) / 100))
Else
Hs.RunScriptFunc("Airplay.vb", "Main", Metadata, True, False) ' This is where the core parsing of metadata takes place
End If
End While
Catch e As SocketException
hs.Writelog(LogLabel, e)
Finally
listener.Close()
hs.Writelog(LogLabel, "Closed Shairport UDP Server")
End Try
The latter part decipers the song duration or coreastm = SongtTime. This was really tricky as the insignificant looking data following coreastm is not a string, but a 4-byte Integer. On top of that in reversed order compared to my windows environment! The resulting integer is in milliseconds (but I need a 10-multiple of seconds for my integration).
The issue is quite closed, but it would be great if the chunking autor could provide more documentation.
Fantastic SW, thank you so much! Am having some issues encoding the data sent over UDP. Metadata text works fine when I encode using UTF8 (ASCII is not international enough), but I am having some problems with the cover art. It "looks" similar to other cover art jpegs that I have, but there are some slight differences. UTF7 looks slightly better for a jpeg but destroys int'l letters. What is the right way to encode/decode the UDP stream? Also, I get some short data in coreastm ("song time" = duration?), but cannot decipher it.