Jump to content

TCP get metadata


nend
 Share

Recommended Posts

Hi,
 

I'm trying to get a block of metadata of a audio stream.

I find this manual but I'm stuck half way. ( http://stackoverflow.com/questions/4911062/pulling-track-info-from-an-audio-stream-using-php/4914538#4914538 )

I made the code which collect the icy data en collect the "metaint" from it.

I found a website which state:
 

Ok, the server will respond with a bunch of headers and then start sending you data. In those headers will be an icy-metaint:8192 or similar. That 8192 is the meta interval. This is important, and really the only value you need. It is usually 8192, but not always, so make sure to actually read this value!

Basically it means, you will get 8192 bytes of MP3 data and then a chunk of meta, followed by 8192 bytes of MP3 data, followed by a chunk of meta.

Read 8192 bytes of data (make sure you are not including the header in this count), discard them, and then read the next byte. This byte is the first byte of meta data, and indicates how long the meta data is. Take the value of this byte (the actual byte with ord() (doc)), and multiply it by 16. The result is the number of bytes to read for metadata. Read those number of bytes into a string variable for you to work with.

Next, trim the value of this variable. Why? Because the string is padded with 0x0 at the end (to make it fit evenly into a multiple of 16 bytes), and trim() (doc) takes care of that for us.

You will be left with something like this:

StreamTitle='Awesome Trance Mix - DI.fm';StreamUrl=''

 

Now I can't find a way to do this last step.

Can someone help me? here is the code.

I only need once the metadata and then disconect.

$link = "http://icecast-qmusic.cdp.triple-it.nl/Qmusic_nl_fouteuur_96.mp3"

TCPStartUp()
$url_array = _NetInfo_NameToIP($link)

ConsoleWrite("Ip = " & $url_array[0] & @CRLF)
ConsoleWrite("Link = " & $url_array[1] & @CRLF)
ConsoleWrite("Port = " & $url_array[2] & @CRLF)

$meta_total = _Get_stream_info($url_array[0], $url_array[1], $url_array[2])
If Not @error Then
    $metaint = _Get_stream_meta_interval($meta_total)
    ConsoleWrite("Metaint = " & $metaint & @CRLF)
    _Get_stream_meta($url_array[0], $url_array[1], $url_array[2], $metaint)
EndIf

TCPShutdown()

Func _Get_stream_info($_Host, $link, $_Port=80, $_TimeOut=1500)
    Local $_Timer = TimerInit()
    Local $_Shoutcast = TCPConnect($_Host, $_Port)
    If Not @error Then
        If $_Shoutcast = -1 Then
            TCPShutdown ( )
            Return 0
        EndIf
        TCPSend($_Shoutcast, "GET /" & $link & " HTTP/1.1" & @CRLF & _
                             "Icy-MetaData:1"  & @CRLF & _
                             "User-Agent: TR" & @CRLF & _
                             "Host: icecast-qmusic.cdp.triple-it.nl" & @CRLF & _
                             "Connection: Close" & @CRLF & _
                             "Cache-Control: no-cache" & @CRLF & @CRLF)

        While 1
            $_Recv = BinaryToString(TCPRecv($_Shoutcast, 1024))
            If $_Recv <> "" Then
                ExitLoop
            EndIf
            If TimerDiff($_Timer) > $_TimeOut Then
                ExitLoop
            EndIf
        WEnd
        TCPCloseSocket($_Shoutcast)
        Return $_Recv
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc

Func _Get_stream_meta_interval($string)
    Local $split_line, $split_metaint
    $split_line = StringSplit($string, @CR, 2)
    If Not @error Then
        For $i = 0 To UBound($split_line) -1
            If StringInStr($split_line[$i], "icy-metaint") Then
                $split_metaint = StringSplit($split_line[$i], ":", 2)
                If Not @error Then
                    Return $split_metaint[1]
                Else
                    SetError(2)
                EndIf
                ExitLoop
            EndIf
        Next
    Else
        SetError(1)
    EndIf
EndFunc

Func _Get_stream_meta($_Host, $link, $_Port, $metaint, $_TimeOut=5500)
    Local $total_Recv
    Local $_Timer = TimerInit()
    Local $_Shoutcast = TCPConnect($_Host, $_Port)
    If Not @error Then
        If $_Shoutcast = -1 Then
            TCPShutdown ( )
            Return 0
        EndIf
        TCPSend($_Shoutcast, "GET /" & $link & " HTTP/1.1" & @CRLF & @CRLF)

        While 1
            $_Recv = BinaryToString(TCPRecv($_Shoutcast, $metaint))
            If $_Recv <> "" Then
            ;       ConsoleWrite($_Recv & @CRLF)
                    $total_Recv = $total_Recv & $_Recv
            EndIf
            If TimerDiff($_Timer) > $_TimeOut Then
                ExitLoop
            EndIf
        WEnd
        TCPCloseSocket($_Shoutcast)
        Return $total_Recv
    Else
        Return 0
    EndIf
EndFunc


Func _NetInfo_NameToIP($Domain_total)
    Local $aResult, $splitarray, $return[3], $port

    StringRegExpReplace($Domain_total, "/", "/", 0)
    If @extended > 2 Then
        $Domain = StringLeft($Domain_total, StringInStr($Domain_total, "/", Default, 3)-1)
        $link = StringReplace($Domain_total, $Domain, "")
    EndIf

    $Domain = StringReplace($Domain, "http://", "")
    $Domain = StringReplace($Domain, "www.", "")

    If $port = False Then
        If StringInStr($Domain, ":") Then
            $splitarray = StringSplit($Domain, ":", 2)
            If Not @error Then
                $Domain = $splitarray[0]
                $port = $splitarray[1]

            EndIf
        EndIf
        $aResult = TCPNameToIP($Domain)
        If @error Then
            Return SetError(1, 0, "")
        EndIf
    Else
        If StringInStr($Domain, ":") Then
            $splitarray = StringSplit($Domain, ":")
            $aResult = $splitarray[2]
        EndIf
    EndIf

    If $port = "" Then
        $port  = 80
    EndIf

    $return[0] = $aResult
    $return[1] = $link
    $return[2] = $port

    Return $return
EndFunc

 

Edited by nend
Link to comment
Share on other sites

I didn't run your script and I don't know which protocol this particular procedure uses, but if you want to receive binary data, TCPRecv should have $flag = 1...

Anyway what is your problem? What do you get instead of the wanted meta-data?

Edited by j0kky
Link to comment
Share on other sites

I get the mp3 stream data, but the metadata is inserted in the data stream, I don't know how to extract the meta data from the mp3 stream data.

EDIT:

"but if you want to receive binary data, TCPRecv should have $flag = 1... "

Flag with TCPRecv is not filled in so it's default.

Help file state, "$TCP_DATA_DEFAULT (0) - (Default) will auto detect between binary/string"

So I don't see the problem.

 

Edited by nend
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...