Reputation: 735
I am writing a UPNP-Controller.
To supply the Artist and Title, it's necessary that I can get the metadata, probably supplied as XML somewhere in the Stream.
For that, I want to read the (endless) stream from InternetRadio and detect the XML. I am not sure what it contains exactly, but I struggle with receiving the Stream as TMemoryStream
. The program gets stuck after the Get
command.
procedure TformMain.GetUrlStream(url: string; var m: Tmemorystream);
var
IdHTTP1: TIdHTTP;
XMLStr: string;
IO : TIdSSLIOHandlerSocketOpenSSL;
begin
IdHTTP1 := TIdHTTP.Create;
try
IO := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
IO.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
IdHttp1.IOHandler := IO;
IdHttp1.ConnectTimeout := 5000;
IdHttp1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36';
IdHttp1.Request.Connection := 'close'; // Close connection after each request
IdHTTP1.Get(url,m); // --> here the program stops
finally
IdHTTP1.Free;
end;
end;
Upvotes: 1
Views: 146
Reputation: 735
I found a completly different way to get hold on the Metadata
of the radiostream with the help of wget.exe
.
Here an exerpt of the code:
function TformMain.GetMetaTitle(url: string) : string;
var
cmd: string;
search,search2: string;
p,p2 : integer;
res : string;
str :string;
begin
//Get ici-MetaData
result := '';
StringReplace(url,'https://','http://',[rfReplaceAll, rfIgnoreCase]);
cmd := 'wget --header="Icy-MetaData:1" -S -O reply.txt '+url;
Memodummy.Clear;
GetDosOutput(cmd,'',Memodummy,15); //15 erwartete metatags + 1 stream
if processExists('wget.exe') then begin
WinExec('taskkill /IM wget.exe /F', SW_HIDE);
end;
sleep(1000); //Wait for Taskkill
//Locate begin of title
search := 'icy-metaint:';
search2 := char(13);
p := pos(search,Memodummy.Text,1);
p2 := pos(search2,Memodummy.Text,p);
res := Trim(copy(Memodummy.Text,p+length(search)+1,p2 - p - (length(search)+1)));
//extract title if possible
try
str := TFile.ReadAllText('reply.txt');
search := 'StreamTitle=';
search2 := ';';
p := pos(search,str,strtoint(res));
p2 := pos(search2,str,p);
result := Trim(copy(str,p+length(search)+1,p2 - p - (length(search)+1)-1));
result := THTMLEncoding.HTML.Encode(result);
except
on e:exception do begin
memo1.lines.Append('Fehler in GetMetatitle: ' +e.Message);
end;
end;
end;
The part of Locate begin of title
could even be skipped and the outputfile (reply.txt) directly searched for StreamTitle=
. So no output of the Dos-Window (here Memodummy) has to be analyzed.
But so the structure is more clear I think.
So the short version would be: (untested)
function TformMain.GetMetaTitle(url: string) : string;
var
cmd: string;
search,search2: string;
p,p2 : integer;
str :string;
begin
//Get ici-MetaData
result := '';
StringReplace(url,'https://','http://',[rfReplaceAll, rfIgnoreCase]);
cmd := 'wget --header="Icy-MetaData:1" -S -O reply.txt '+url;
Shellexecute(cmd,........);
if processExists('wget.exe') then begin
WinExec('taskkill /IM wget.exe /F', SW_HIDE);
end;
sleep(1000); //Wait for Taskkill
//extract title if possible
try
str := TFile.ReadAllText('reply.txt');
search := 'StreamTitle=';
search2 := ';';
p := pos(search,str,strtoint(res));
p2 := pos(search2,str,p);
result := Trim(copy(str,p+length(search)+1,p2 - p - (length(search)+1)-1));
result := THTMLEncoding.HTML.Encode(result);
except
on e:exception do begin
memo1.lines.Append('Fehler in GetMetatitle: ' +e.Message);
end;
end;
end;
Upvotes: 1