Make(delphi) Add(MainForm,16107315,63,133) { Left=20 Top=105 } Add(Button,16530932,63,175) { Left=165 Top=90 link(onClick,16285157:doEvent1,[]) } Add(BASS_Global,16072203,189,133) { } Add(Hub,16285157,126,175) { OutCount=4 link(onEvent1,16072203:doInit,[(170,181)(170,139)]) link(onEvent2,16072203:doStart,[(170,188)(170,146)]) link(onEvent3,16713139:doRead,[]) } Add(InlineCode,16713139,245,189) { WorkPoints=#6:doRead| EventPoints=#6:onRead|10:onProgress|8:onStatus|7:onError| DataPoints=#3:URL|8:StrProxy| Code=#1:{|11:unit Unit1;|0:|9:interface|0:|4:uses|75: Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,|27: StdCtrls, Bass, ExtCtrls;|0:|5:const|33: WM_INFO_UPDATE = WM_USER + 101;|0:|4:type|2: |23: TForm1 = class(TForm)|19: Panel1: TPanel;|25: GroupBox1: TGroupBox;|19: Label1: TLabel;|19: Label2: TLabel;|21: Button1: TButton;|21: Button2: TButton;|21: Button3: TButton;|21: Button4: TButton;|21: Button5: TButton;|21: Button6: TButton;|21: Button7: TButton;|21: Button8: TButton;|21: Button9: TButton;|22: Button10: TButton;|25: GroupBox2: TGroupBox;|19: Label3: TLabel;|19: Label4: TLabel;|19: Label5: TLabel;|25: GroupBox3: TGroupBox;|19: Label6: TLabel;|26: ed_ProxyServer: TEdit;|34: cbDirectConnection: TCheckBox;|42: procedure FormCreate(Sender: TObject);|43: procedure FormDestroy(Sender: TObject);|44: procedure Button1Click(Sender: TObject);|55: procedure cbDirectConnectionClick(Sender: TObject);|9: private|0:|8: public|0:|51: procedure WndProc(var Msg: TMessage); override;|0:|0:|6: end;|0:|3:var|16: Form1: TForm1;|46: Proxy: array [0..99] of char; //proxy server|0:|21: cthread: DWORD = 0;|20: chan: HSTREAM = 0;|12: win: hwnd;|14:implementation|0:|5:const|48: urls: array[0..9] of string = ( // stream URLs|108: 'http://www.radioparadise.com/musiclinks/rp_128-9.m3u','http://www.radioparadise.com/musiclinks/rp_32.m3u',|81: 'http://www.sky.fm/mp3/classical.pls','http://www.sky.fm/mp3/classical_low.pls',|75: 'http://www.sky.fm/mp3/the80s.pls','http://www.sky.fm/mp3/the80s_low.pls',|98: 'http://bassdrive.com/v2/streams/BassDrive.m3u','http://bassdrive.com/v2/streams/BassDrive3.m3u',|74: 'http://somafm.com/secretagent.pls','http://somafm.com/secretagent24.pls'|6: );|0:|28:procedure Error(es: string);|5:begin|85: MessageBox(win, PChar(es + #13#10 + '(error code: ' + IntToStr(BASS_ErrorGetCode) +|18: ')'), nil, 0);|4:end;|0:|19:procedure DoMeta();|3:var|14: meta: PChar;|13: p: Integer;|5:begin|51: meta := BASS_ChannelGetTags(chan, BASS_TAG_META);|23: if (meta <> nil) then|7: begin|35: p := Pos('StreamTitle=', meta);|19: if (p = 0) then|11: Exit;|16: p := p + 13;|93: SendMessage(win, WM_INFO_UPDATE, 7, DWORD(PChar(Copy(meta, p, Pos(';', meta) - p - 1))));|6: end;|4:end;|0:|71:procedure MetaSync(handle: HSYNC; channel, data, user: DWORD); stdcall;|5:begin|11: DoMeta();|4:end;|0:|65:procedure StatusProc(buffer: Pointer; len, user: DWORD); stdcall;|5:begin|39: if (buffer <> nil) and (len = 0) then|62: SendMessage(win, WM_INFO_UPDATE, 8, DWORD(PChar(buffer)));|4:end;|0:|38:function OpenURL(url: PChar): Integer;|3:var|13: icy: PChar;|23: Len, Progress: DWORD;|5:begin|14: Result := 0;|44: BASS_StreamFree(chan); // close old stream|16: progress := 0;|83: SendMessage(win, WM_INFO_UPDATE, 0, 0); // reset the Labels and trying connecting|0:|75: chan := BASS_StreamCreateURL(url, 0, BASS_STREAM_STATUS, @StatusProc, 0);|20: if (chan = 0) then|7: begin|0:|57: SendMessage(win, WM_INFO_UPDATE, 1, 0); // Oops Error|5: end|6: else|7: begin|15: // Progress|10: repeat|64: len := BASS_StreamGetFilePosition(chan, BASS_FILEPOS_END);|30: if (len = DW_Error) then|64: break; // something's gone wrong! (eg. BASS_Free called)|76: progress := (BASS_StreamGetFilePosition(chan, BASS_FILEPOS_DOWNLOAD) -|78: BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT)) * 100 div len;|36: // percentage of buffer filled|91: SendMessage(win, WM_INFO_UPDATE, 2, progress); // show the Progess value in the label|0:|9: until|20: progress > 75;|0:|41: // get the broadcast name and bitrate|51: icy := BASS_ChannelGetTags(chan, BASS_TAG_ICY);|23: if (icy = nil) then|79: icy := BASS_ChannelGetTags(chan, BASS_TAG_HTTP); // no ICY tags, try HTTP|24: if (icy <> nil) then|27: while (icy^ <> #0) do|11: begin|47: if (Copy(icy, 1, 9) = 'icy-name:') then|82: SendMessage(win, WM_INFO_UPDATE, 3, DWORD(PChar(Copy(icy, 10, MaxInt))))|0:|50: else if (Copy(icy, 1, 7) = 'icy-br:') then|0:|96: SendMessage(win, WM_INFO_UPDATE, 4, DWORD(PChar('bitrate: ' + Copy(icy, 8, MaxInt))));|37: icy := icy + Length(icy) + 1;|10: end;|62: // get the stream title and set sync for subsequent titles|13: DoMeta();|63: BASS_ChannelSetSync(chan, BASS_SYNC_META, 0, @MetaSync, 0);|15: // play it!|34: BASS_ChannelPlay(chan, FALSE);|6: end;|15: cthread := 0;|4:end;|0:|22: |44:procedure TForm1.WndProc(var Msg: TMessage);|81:// to be threadsave we are passing all Canvas Stuff(e.g. Labels) to this messages|5:begin|12: inherited;|34: if Msg.Msg = WM_INFO_UPDATE then|22: case msg.WParam of|8: 0:|13: begin|44: Label4.Caption := 'connecting...';|31: Label3.Caption := '';|31: Label5.Caption := '';|12: end;|8: 1:|13: begin|42: Label4.Caption := 'not playing';|42: Error('Can''t play the stream');|12: end;|69: 2: Label4.Caption := Format('buffering... %d%%', [msg.LParam]);|45: 3: Label4.Caption := PChar(msg.LParam);|45: 4: Label5.Caption := PChar(msg.LParam);|45: 5: Label5.Caption := PChar(msg.LParam);|45: 6: Label3.Caption := PChar(msg.LParam);|45: 7: Label3.Caption := PChar(msg.LParam);|45: 8: Label5.Caption := PChar(msg.LParam);|8: end;|27:end; |0:|45:procedure TForm1.FormCreate(Sender: TObject);|5:begin|38: // check the correct BASS was loaded|16: win := handle;|50: if (HIWORD(BASS_GetVersion) <> BASSVERSION) then|7: begin|84: MessageBox(0, 'An incorrect version of BASS.DLL was loaded', nil, MB_ICONERROR);|9: Halt;|6: end;|52: if (not BASS_Init(-1, 44100, 0, Handle, nil)) then|7: begin|38: Error('Can''t initialize device');|9: Halt;|6: end;|76: BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1); // enable playlist processing|122: BASS_SetConfig(BASS_CONFIG_NET_PREBUF, 0); // minimize automatic pre-buffering, so we can do it (and display it) instead|85: BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, @proxy[0]); // setup proxy server location|0:|4:end;|0:|46:procedure TForm1.FormDestroy(Sender: TObject);|5:begin|12: BASS_Free;|4:end;|0:|47:procedure TForm1.Button1Click(Sender: TObject);|3:var|21: ThreadId: Cardinal;|5:begin|80: StrPCopy(proxy,ed_ProxyServer.Text); // copy the Servertext to the Proxy array|24: if (cthread <> 0) then|18: MessageBeep(0)|6: else|92: cthread := BeginThread(nil, 0, @OpenURL, PChar(urls[TButton(Sender).Tag]), 0, ThreadId);|4:end;|0:|58:procedure TForm1.cbDirectConnectionClick(Sender: TObject);|5:begin|39: if not TCheckbox(Sender).Checked then|71: BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, @proxy[0]) // enable proxy|6: else|67: BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, nil); // disable proxy|4:end;|0:|4:end.|1:}|0:|15:unit HiAsmUnit;|0:|9:interface|0:|34:uses Windows,kol,Share,Debug,Bass;|0:|5:const|48: // BASS_ChannelGetTags types : what's returned|57: BASS_TAG_ID3 = 0; // ID3v1 tags : 128 byte block|64: BASS_TAG_ID3V2 = 1; // ID3v2 tags : variable length block|78: BASS_TAG_OGG = 2; // OGG comments : series of null-terminated strings|78: BASS_TAG_HTTP = 3; // HTTP headers : series of null-terminated strings|77: BASS_TAG_ICY = 4; // ICY headers : series of null-terminated strings|67: BASS_TAG_META = 5; // ICY metadata : null-terminated string|66: BASS_TAG_VENDOR = 9; // OGG encoder : null-terminated string|58: BASS_TAG_LYRICS3 = 10; // Lyric3v2 tag : ASCII string|88: BASS_TAG_RIFF_INFO = $100; // RIFF/WAVE tags : series of null-terminated ANSI strings|63: BASS_TAG_MUSIC_NAME = $10000; // MOD music name : ANSI string|63: BASS_TAG_MUSIC_MESSAGE = $10001; // MOD message : ANSI string|84: BASS_TAG_MUSIC_INST = $10100; // + instrument #, MOD instrument name : ANSI string|78: BASS_TAG_MUSIC_SAMPLE = $10300; // + sample #, MOD sample name : ANSI string|0:|30: // BASS_SetConfigPtr options|33: BASS_CONFIG_NET_AGENT = 16;|33: BASS_CONFIG_NET_PROXY = 17;|0:|37: // BASS_StreamGetFilePosition modes|30: BASS_FILEPOS_CURRENT = 0;|49: BASS_FILEPOS_DECODE = BASS_FILEPOS_CURRENT;|30: BASS_FILEPOS_DOWNLOAD = 1;|30: BASS_FILEPOS_END = 2;|30: BASS_FILEPOS_START = 3;|30: BASS_FILEPOS_CONNECTED = 4;|30: BASS_FILEPOS_BUFFER = 5;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|16: th:PThread;|20: StrURL: string;|19: procedure Err;|46: function _OnExec(Sender:PThread):Integer;|24: procedure SyncExec;|9: public|23: onRead: THI_Event;|27: onProgress: THI_Event;|25: onStatus: THI_Event;|24: onError: THI_Event;|20: URL: THI_Event;|25: StrProxy: THI_Event;|0:|34: destructor Destroy; override;|51: procedure doRead(var _Data:TData; Index:word);|0:|5: end;|0:|3:var|46: Proxy: array [0..99] of char; //proxy server|21: cthread: DWORD = 0;|20: chan: HSTREAM = 0;|0:|14:implementation|0:|96:function BASS_ChannelGetTags(handle: HSTREAM; tags: DWORD): PChar; stdcall; external 'bass.dll';|94:function BASS_SetConfigPtr(option: DWORD; value: Pointer): BOOL; stdcall; external 'bass.dll';|0:|5:const|48: urls: array[0..9] of string = ( // stream URLs|108: 'http://www.radioparadise.com/musiclinks/rp_128-9.m3u','http://www.radioparadise.com/musiclinks/rp_32.m3u',|81: 'http://www.sky.fm/mp3/classical.pls','http://www.sky.fm/mp3/classical_low.pls',|75: 'http://www.sky.fm/mp3/the80s.pls','http://www.sky.fm/mp3/the80s_low.pls',|98: 'http://bassdrive.com/v2/streams/BassDrive.m3u','http://bassdrive.com/v2/streams/BassDrive3.m3u',|74: 'http://somafm.com/secretagent.pls','http://somafm.com/secretagent24.pls'|6: );|0:|31:destructor THiAsmClass.Destroy;|5:begin|38: if th <> nil then free_and_nil(th);|13: BASS_Free;|13: inherited;|4:end;|0:|26:procedure THiAsmClass.Err;|5:begin|3:TRY|38: if BASS_ErrorGetCode = 0 then exit;|13: BASS_Free;|7:FINALLY|51: _hi_OnEvent(onError,integer(BASS_ErrorGetCode));|7:END; |4:end;|0:|30:procedure DoMeta(user: DWORD);|18:var meta: PChar;|17: p: Integer;|5:begin|52: meta := BASS_ChannelGetTags(chan, BASS_TAG_META);|22:_debug(integer(meta));|30: if (meta <> nil) then begin|37: p := Pos('StreamTitle=', meta);|27: if (p = 0) then Exit;|18: p := p + 13;|94: _hi_onEvent(THiAsmClass(user).onRead, PChar(Copy(meta, p, Pos(';', meta) - p - 1))); |6: end;|4:end;|0:|71:procedure MetaSync(handle: HSYNC; channel, data, user: DWORD); stdcall;|5:begin|15: DoMeta(user);|4:end;|0:|65:procedure StatusProc(buffer: Pointer; len, user: DWORD); stdcall;|5:begin|39: if (buffer <> nil) and (len = 0) then|59: _hi_onEvent(THiAsmClass(user).onStatus, PChar(buffer));|4:end;|0:|29:function THiAsmClass._OnExec;|5:begin|39: while not Sender.Terminated do begin|48: BASS_StreamFree(chan); // close old stream|101: chan := BASS_StreamCreateURL(PChar(StrURL), 0, BASS_STREAM_STATUS, @StatusProc, LongInt(Self));|35: Sender.Synchronize(SyncExec);|7: end;|15: Result := 0;|4:end;|0:|31:procedure THiAsmClass.SyncExec;|17:var icy: PChar;|27: Len, Progress: DWORD;|5:begin|3:TRY|17: progress := 0;|47:// BASS_StreamFree(chan); // close old stream|100:// chan := BASS_StreamCreateURL(PChar(StrURL), 0, BASS_STREAM_STATUS, @StatusProc, LongInt(Self));|13:_debug(chan);|27: if (chan = 0) then begin|10: Err;|11: exit;|17: end else begin|12: repeat|67: len := BASS_StreamGetFilePosition(chan, BASS_FILEPOS_END);|90: if (len = DW_Error) then break; // something's gone wrong! (eg. BASS_Free called)|79: progress := (BASS_StreamGetFilePosition(chan, BASS_FILEPOS_DOWNLOAD) -|89: BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT)) * 100 div len;|19://_debug(progress);|52: _hi_onEvent(onProgress, integer(progress));|32: Applet.ProcessMessages;|26: until progress > 75;|27:// until progress > 2;|43: // get the broadcast name and bitrate|53: icy := BASS_ChannelGetTags(chan, BASS_TAG_ICY);|25: if (icy = nil) then|82: icy := BASS_ChannelGetTags(chan, BASS_TAG_HTTP); // no ICY tags, try HTTP|29: if (icy <> nil) then|36: while (icy^ <> #0) do begin|51: if (Copy(icy, 1, 9) = 'icy-name:') then|44: _debug(Copy(icy, 10, MaxInt))|84:// SendMessage(win, WM_INFO_UPDATE, 3, DWORD(PChar(Copy(icy, 10, MaxInt))))|54: else if (Copy(icy, 1, 7) = 'icy-br:') then|98:// SendMessage(win, WM_INFO_UPDATE, 4, DWORD(PChar('bitrate: ' + Copy(icy, 8, MaxInt))));|58: _debug('bitrate: ' + Copy(icy, 8, MaxInt));|41: icy := icy + Length(icy) + 1;|13: end;|62: // get the stream title and set sync for subsequent titles|26: DoMeta(LongInt(Self));|63: BASS_ChannelSetSync(chan, BASS_SYNC_META, 0, @MetaSync, 0);|15: // play it!|34: BASS_ChannelPlay(chan, FALSE);|6: end;|7:FINALLY|40: if Assigned(th) then free_and_nil(th);|4:END;|0:|4:end;|0:|29:procedure THiAsmClass.doRead;|19:var str : string;|5:begin|0:|64:// if (not BASS_Init(-1, 44100, 0, ReadHandle, nil)) then begin|11:// Err;|45:// if Assigned(th) then free_and_nil(th);|12:// exit;|11:// end; |0:|36: StrURL := ReadString(_Data, URL); |0:|38: str := ReadString(_Data, StrProxy); |25: if str <> '' then begin|68: StrPCopy(proxy, str); // copy the Servertext to the Proxy array|74: BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, @proxy[0]) // enable proxy |10: end else|70: BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, nil); // disable proxy |0:|33: if not Assigned(th) then begin |63: th := {$ifdef F_P}NewThreadforFPC{$else}NewThread{$endif};|29: th.OnExecute := _OnExec;|15: th.Resume;|6: end;|2: |4:end;|0:|4:end.| link(URL,5897771:Value,[]) } Add(Memory,5897771,245,133) { @Hint=#11:mp3 -- File| Default=String(http://slil.ru/25901566/41cee41a.4858e470/John_B_-_03_-_Concord_Dawn_-_Morning_Light.mp3) } Add(Memory,14181987,294,133) { @Hint=#11:m3u -- List| Default=String(http://www.radioparadise.com/musiclinks/rp_128-9.m3u) }