nend Posted December 17, 2016 Share Posted December 17, 2016 (edited) Hi all, I'm trying to get a meta data from a audio stream. I found a PHP script wich works perfectly. expandcollapse popup<?php $stream = getMp3StreamTitle("http://icecast-qmusic.cdp.triple-it.nl/Qmusic_nl_fouteuur_96.mp3"); print($stream); function getMp3StreamTitle($steam_url) { $result = false; $icy_metaint = -1; $needle = 'StreamTitle='; $ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36'; $opts = array( 'http' => array( 'method' => 'GET', 'header' => 'Icy-MetaData: 1', 'user_agent' => $ua ) ); $default = stream_context_set_default($opts); $stream = fopen($steam_url, 'r'); if($stream && ($meta_data = stream_get_meta_data($stream)) && isset($meta_data['wrapper_data'])){ foreach ($meta_data['wrapper_data'] as $header){ if (strpos(strtolower($header), 'icy-metaint') !== false){ $tmp = explode(":", $header); $icy_metaint = trim($tmp[1]); break; } } } print($icy_metaint); if($icy_metaint != -1) { $buffer = stream_get_contents($stream, 300, $icy_metaint); if(strpos($buffer, $needle) !== false) { $title = explode($needle, $buffer); $title = trim($title[1]); $result = substr($title, 1, strpos($title, ';') - 2); } } if($stream) fclose($stream); return $result; } ?> I tryd to make this in autoit with winhttp but I only gets garbage. I think I made a mistake in they binairy part of the script. I don't understand that part well. This is the autoit script so far. #include "WinHttp.au3" Opt("MustDeclareVars", 1) Global $sHost = "http://icecast-qmusic.cdp.triple-it.nl" Global $sTarget = "Qmusic_nl_fouteuur_96.mp3" Global $hHttpOpen = _WinHttpOpen() Global $hHttpConnect = _WinHttpConnect($hHttpOpen, $sHost) Global $hHttpRequest = _WinHttpOpenRequest($hHttpConnect, Default, $sTarget) _WinHttpSendRequest($hHttpRequest) _WinHttpReceiveResponse($hHttpRequest) Global $bChunk, $bData If _WinHttpQueryDataAvailable($hHttpRequest) Then While 1 $bChunk = _WinHttpReadData($hHttpRequest, 2) ; read binary If @error Then ExitLoop $bData = _WinHttpSimpleBinaryConcat($bData, $bChunk) ; concat two binary data If BinaryLen($bData) > 16000 Then ; if downloaded more than the metaint (metaint for this station is 16000) local $B_mid = BinaryMid($bData, 16000, 300); gets the data from 16000 till 16300 ConsoleWrite(BinaryToString($B_mid) & @CRLF); display data in the console ExitLoop EndIf WEnd EndIf ; Close handles _WinHttpCloseHandle($hHttpRequest) _WinHttpCloseHandle($hHttpConnect) _WinHttpCloseHandle($hHttpOpen) I think for some of the wizzkidzz here on the forum it's solved in notime. If use winhttp found here on the website Can some one please help me with this? Edited December 19, 2016 by nend Link to comment Share on other sites More sharing options...
trancexx Posted December 17, 2016 Share Posted December 17, 2016 Maybe like this: #include "WinHttp.au3" $sHost = "http://icecast-qmusic.cdp.triple-it.nl" $sTarget = "Qmusic_nl_fouteuur_96.mp3" $hHttpOpen = _WinHttpOpen() $hHttpConnect = _WinHttpConnect($hHttpOpen, $sHost) $hHttpRequest = _WinHttpOpenRequest($hHttpConnect, Default, $sTarget) _WinHttpSendRequest($hHttpRequest, "Icy-MetaData: 1") _WinHttpReceiveResponse($hHttpRequest) $sYourData = "???" If _WinHttpQueryDataAvailable($hHttpRequest) Then $sYourData = StringRegExpReplace(BinaryToString(_WinHttpReadData($hHttpRequest, 2, 16300)), "(?Us).*?StreamTitle='(.*?)';.*?", "$1") EndIf _WinHttpCloseHandle($hHttpRequest) _WinHttpCloseHandle($hHttpConnect) _WinHttpCloseHandle($hHttpOpen) ConsoleWrite($sYourData & @CRLF) MsgBox(4096, "Your Data...", $sYourData) nend 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
nend Posted December 17, 2016 Author Share Posted December 17, 2016 Thanks for the help trancexx. I see it works perfectly, I will study it so I can do it my self the next time THANKS!! Link to comment Share on other sites More sharing options...
trancexx Posted December 17, 2016 Share Posted December 17, 2016 Sure, np Btw, you don't need BinaryToString() if you read it like this _WinHttpReadData($hHttpRequest, 1, 16300) ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
nend Posted December 18, 2016 Author Share Posted December 18, 2016 @trancexx Thank for the tip. I'm progressing with this script and made it that playlist links wil be extracted before getting the meta data. This goes fine for a lot of streaming links but... not for all and I can't find out why. This script has two streaminglinks in it 1 is working and the other not. Do you have got any idea why? This is the code so far. expandcollapse popup#include "WinHttp.au3" #include <Array.au3> ;$link = "http://www.hitz24.com/streams/listen.pls"; not working $link = "http://62.138.0.105:8000/listen.pls?sid=1"; working ConsoleWrite(_Get_meta_data($link) & @CRLF) Func _Get_meta_data($link) Local $hHttpOpen = _WinHttpOpen() Local $link_array = _Split_playlist_link($link, $hHttpOpen) If Not @error Then For $i = 0 To UBound($link_array)-1 Local $meta = _Get_meta_data_total($link_array[$i], $hHttpOpen) If Not @error Then ExitLoop EndIf Next Else Local $meta = _Get_meta_data_total($link, $hHttpOpen) EndIf _WinHttpCloseHandle($hHttpOpen) Return $meta EndFunc Func _Get_meta_data_total($link, $winhttp_handle) Local $sYourData Local $URL_array = _WinHttpCrackUrl($link) ;_ArrayDisplay($URL_array) Local $hHttpConnect = _WinHttpConnect($winhttp_handle, $URL_array[2], $URL_array[3]) If $URL_array[6] = "" Then Local $hHttpRequest = _WinHttpOpenRequest($hHttpConnect) Else Local $hHttpRequest = _WinHttpOpenRequest($hHttpConnect, Default, $URL_array[6]) EndIf _WinHttpSendRequest($hHttpRequest, "Icy-MetaData:1" & @CRLF & _ "User-Agent: TR" & @CRLF & _ "Connection: Close" & @CRLF & _ "Cache-Control: no-cache", $URL_array[7]) _WinHttpReceiveResponse($hHttpRequest) Local $sHeader = _WinHttpQueryHeaders($hHttpRequest) Local $metaint = StringRegExpReplace($sHeader, "(?Us).*?icy-metaint: (.*?).*?", "$1") If Not @error Then If _WinHttpQueryDataAvailable($hHttpRequest) Then $sYourData = StringRegExpReplace(BinaryToString(_WinHttpReadData($hHttpRequest, 2, $metaint+300)), "(?Us).*?StreamTitle='(.*?)';.*?", "$1") EndIf EndIf _WinHttpCloseHandle($hHttpRequest) _WinHttpCloseHandle($hHttpConnect) Return $sYourData EndFunc Func _Split_playlist_link($link, $winhttp_handle) Local $return_array Local $URL_array = _WinHttpCrackUrl($link) ;_ArrayDisplay($URL_array) Local $hHttpConnect = _WinHttpConnect($winhttp_handle, $URL_array[2], $URL_array[3]) Local $hHttpRequest = _WinHttpOpenRequest($hHttpConnect, Default, $URL_array[6]) _WinHttpSendRequest($hHttpRequest, "User-Agent: TR" & @CRLF & _ "Connection: Close" & @CRLF & _ "Cache-Control: no-cache", $URL_array[7]) _WinHttpReceiveResponse($hHttpRequest) Local $sHeader = _WinHttpQueryHeaders($hHttpRequest) Local $a_content = StringRegExp($sHeader, "(?<=Content-Type:\s).*", 3) If Not @error Then If StringInStr($a_content[0], "pls+xml") Or StringInStr($a_content[0], "x-scpls") Or StringInStr($a_content[0], "x-mpegurl") Then If _WinHttpQueryDataAvailable($hHttpRequest) Then Local $data =_WinHttpReadData($hHttpRequest, 1) $return_array = StringRegExp($data, "http://.*", 3) EndIf EndIf EndIf _WinHttpCloseHandle($hHttpRequest) _WinHttpCloseHandle($hHttpConnect) If IsArray($return_array) Then Return $return_array Else Return SetError(1) EndIf EndFunc Link to comment Share on other sites More sharing options...
nend Posted December 18, 2016 Author Share Posted December 18, 2016 (edited) I've brought it back to a small piece of code but this won't return any info. If I try it with a tcp script it returns this header: cy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR> icy-notice2:SHOUTcast Distributed Network Audio Server/Linux v1.9.8<BR> icy-name:Hitz24 - The Hits Only Station icy-genre:pop icy-url:http://www.hitz24.com content-type:audio/mpeg icy-pub:1 icy-metaint:32768 icy-br:192 But if I use this script (for this link, many other links works well) it won't return anything. #include "WinHttp.au3" #include <Array.au3> _Get_meta_data_total() Func _Get_meta_data_total() Local $hHttpOpen = _WinHttpOpen() Local $sYourData Local $hHttpConnect = _WinHttpConnect($hHttpOpen, "37.59.195.28", "8033") Local $hHttpRequest = _WinHttpOpenRequest($hHttpConnect, Default, "/") _WinHttpSendRequest($hHttpRequest, "Cache-Control: no-cache" & @CRLF & _ "Connection: Close" & @CRLF & _ "Host: 37.59.195.28:8033" & @CRLF & _ "User-Agent: BASS/2.4" & @CRLF & _ "Icy-MetaData: 1" & @CRLF & @CRLF, ""); same as wireshark return when starting this station with bass.dll ConsoleWrite(@error & " error" & @CRLF) _WinHttpReceiveResponse($hHttpRequest) ConsoleWrite(@error & " error" & @CRLF) Local $sHeader = _WinHttpQueryHeaders($hHttpRequest) ConsoleWrite(@error & " error" & @CRLF) ConsoleWrite($sHeader & @CRLF) If Not @error Then If _WinHttpQueryDataAvailable($hHttpRequest) Then $data = BinaryToString(_WinHttpReadData($hHttpRequest, 2, 1000)) ConsoleWrite($data & @CRLF) EndIf EndIf _WinHttpCloseHandle($hHttpRequest) _WinHttpCloseHandle($hHttpConnect) _WinHttpCloseHandle($hHttpOpen) EndFunc This is the TCP script which returns the ICY header. expandcollapse popup#include <Array.au3> Local $url_array[3] TCPStartUp() $url_array[0] = "37.59.195.28" $url_array[2] = "8033" $meta_total = _Get_stream_info($url_array[0], $url_array[1], $url_array[2]) If Not @error Then ConsoleWrite($meta_total & @CRLF) EndIf TCPShutdown() Func _Get_stream_info($_Host, $link, $_Port=80, $_TimeOut=1000) Local $_Timer = TimerInit() Local $socket = TCPConnect($_Host, $_Port) If Not @error Then If $socket = -1 Then Return 0 EndIf TCPSend($socket, "GET /" & $link & " HTTP/1.1" & @CRLF & _ "Icy-MetaData:1" & @CRLF & _ "User-Agent: TR" & @CRLF & _ "Connection: Close" & @CRLF & _ "Cache-Control: no-cache" & @CRLF & @CRLF) While 1 $tcp_recieve = TCPRecv($socket, 1000, 1) $_Recv = BinaryToString($tcp_recieve) ConsoleWrite($_Recv & @CRLF) If StringInStr($_Recv, "icy-metaint:") Then TCPCloseSocket($socket) ExitLoop EndIf If TimerDiff($_Timer) > $_TimeOut Then TCPCloseSocket($socket) ExitLoop EndIf WEnd Else SetError(1) Return 0 EndIf EndFunc Edited December 18, 2016 by nend Link to comment Share on other sites More sharing options...
trancexx Posted December 18, 2016 Share Posted December 18, 2016 That server that you have issues with uses some earlier versions of the software, where the header is malformed and doesn't comply with HTTP protocol rules. WinHttp refuses to process it for security reasons. "ICY 200 OK" response is wrong here. Sorry. nend 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
trancexx Posted December 18, 2016 Share Posted December 18, 2016 Apart from that, you don't have to read the whole header and parse it using regexp. You can do this: $metaint = _WinHttpQueryHeaders($hHttpRequest, $WINHTTP_QUERY_CUSTOM, "icy-metaint") ...and this to read content type: _WinHttpQueryHeaders($hHttpRequest, $WINHTTP_QUERY_CONTENT_TYPE) nend 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
nend Posted December 18, 2016 Author Share Posted December 18, 2016 Ok that explained it why I didn't get it to work. $metaint = _WinHttpQueryHeaders($hHttpRequest, $WINHTTP_QUERY_CUSTOM, "icy-metaint") I didn't know that, thanks for the explaining and all the help. So I will learn every time something new. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now