|
Antwort |
Registriert seit: 2. Mär 2010 7 Beiträge |
#1
Hallo liebe Community!
Ich bin dabei mein Delphi Streamplayer für eine Internetradio-Kette im Delphi XE2 Firemonkey zu überarbeiten. Soweit alles okay, bis auf ein riesiges Problem. Die Wiedergabe des Internet Streams funktioniert nicht zuverlässig. Am Anfang lief alles ohne Probleme. Später funktionierte es nur, nachdem ich die config.cfg meines Programms gelöscht habe und nach einem Neustart eine neue generiert wurde. Es geht um folgendes Problem: Streamwiedergabe bei einem klick auf Play. Thread startet und Streamname und Bitrate können erfolgreich ausgelesen werden. ABER: Ich bekomme keinen Sound! Das macht mich bald wahnsinnig, ich bin gefüllte 3 Wochen am Debuggen und finde das Problem nicht. Hier der Quellcode der Mainform: CARE: Es ist reichlich Trash dazwischen die mit dem FMX zusammenhängen. Aber da es scheinbar nicht an der Play "OpenURL" Funktion liegt, poste ich lieber alles.
Delphi-Quellcode:
unit main;
interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts, FMX.Ani, FMX.Objects, Windows, Messages, WinInet, ShellAPI, IdBaseComponent, IdComponent, IdTCPConnection, IdHTTP, Bass, GetXML, XMLIntf, XMLDoc, IdTCPClient, FMX.Grid; type TfrmMain = class(TForm) StyleUnit: TStyleBook; panDisplay: TPanel; pbVolumeWheel: TArcDial; btPlay: TButton; btStop: TButton; btMute: TButton; btRec: TButton; btConfig: TButton; btTracklist: TButton; btOverview: TButton; lbLcdName: TLabel; lbInfoStream: TLabel; lbLcdArtist: TLabel; bg_tile: TBrushObject; panNavi: TImageControl; panPlayer: TLayout; glyphPlay: TImage; glyphStop: TImage; glyphMute: TImage; glyphRec: TImage; imgControlBackground: TImage; imgHeader: TImage; panMain: TLayout; imgPortBG: TImage; imgPort: TImage; IdHTTP1: TIdHTTP; TtUpdate: TTimer; panOverview: TLayout; imgPort1: TImageControl; imgPort2: TImageControl; imgPort3: TImageControl; imgPort4: TImageControl; imgPort5: TImageControl; imgPort6: TImageControl; lbVolMax: TLabel; lbVolMin: TLabel; lbStreamBit: TLabel; Label1: TLabel; sgOverview: TStringGrid; sgCell1: TStringColumn; sgCell2: TStringColumn; sgCell3: TStringColumn; sgCell4: TStringColumn; sgCell5: TStringColumn; sgCell6: TStringColumn; panMainOut: TFloatAnimation; panOverviewOut: TFloatAnimation; panMainIn: TFloatAnimation; panOverviewIn: TFloatAnimation; imgHeaderIn: TFloatAnimation; imgHeaderOut: TFloatAnimation; btClose: TButton; lbStreamDuration: TLabel; lbStreamListener: TLabel; pbDuration: TProgressBar; lbStreamTime: TLabel; aniIndicator: TAniIndicator; aniIndicatorFadeOut: TFloatAnimation; aniIndicatorFadeIn: TFloatAnimation; procedure FormCreate(Sender: TObject); procedure btCloseClick(Sender: TObject); procedure btStopClick(Sender: TObject); procedure btTracklistClick(Sender: TObject); procedure imgPortClick(Sender: TObject); procedure TtUpdateTimer(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btMuteClick(Sender: TObject); procedure btConfigClick(Sender: TObject); procedure btPlayClick(Sender: TObject); procedure imgPort1Click(Sender: TObject); procedure btRecClick(Sender: TObject); procedure pbVolumeWheelChange(Sender: TObject); procedure btOverviewClick(Sender: TObject); procedure panMainInFinish(Sender: TObject); procedure imgHeaderOutFinish(Sender: TObject); // -- procedure InitBassPlugin; procedure RegisterHotkeys; procedure LoadConfig; procedure LoadTracklist; procedure InsertIntoTracklist(radio:integer; artist, song:string); private { Private-Deklarationen } //procedure WmHotkey(var Msg: TMessage); message WM_HOTKEY; public { Public-Deklarationen } end; type TAccount = record email, password : string[100]; end; type THotkey = record key : integer; modifier : string[5]; end; type TCfg = record // Allg Opt progcheck, hotkeys, profilelink, visualize, // Stream Opt autoupdate, short_tracklist, nowplaying, // Autostart Opt autostart, autoplay, showsplash, minimized : boolean; // Arrays/Records/Misc account : TAccount; hotkeylist : array[0..100] of THotkey; autoplradio, volume, metaintervall : integer; logdir, recdir : string[255]; stream_codec : string[3]; end; type TProgramm = record version, build : string[5]; end; type TTracklist = record moderator, show, artist, song, time, date : string[50]; end; type TRadio = record name, moderator, show, start, stop, artist, song, listener : string[50]; modpicurl, profileurl : string; tracklist : array of TTracklist; end; var // Multithreading cthread : DWORD = 0; mthread : DWORD = 0; // Form frmMain : TfrmMain; mHandle : THandle; // Radiodata playID : integer = 0; showID : integer = 1; // Saving the actual playing Radio Infos cfg : TCfg; temp : string; rdata : array[1..6] of TRadio; { 1. Technobase.FM 2. HouseTime.FM 3. HardBase.FM 4. TranceBase.FM 5. CoreTime.FM 6. ClubBase.FM 0. NO RADIO PLAYING} // Visual portrait : array [1..6] of TImageControl; // -- chan : HSTREAM = 0; fRec : TFileStream; DoRec : boolean = False; IsMute : boolean = False; const WM_INFO_UPDATE = WM_USER + 101; dax: string = ('http://tray.technobase.fm/radio.xml'); // URL to Datafile tlx: array[1..6] of string = ( 'http://tray.technobase.fm/tracklist-5.xml', 'http://tray.technobase.fm/tracklist-6.xml', 'http://tray.technobase.fm/tracklist-7.xml', 'http://tray.technobase.fm/tracklist-8.xml', 'http://tray.technobase.fm/tracklist-10.xml', 'http://tray.technobase.fm/tracklist-11.xml'); prog: TProgramm = (version : '2.20'; build : '1250'); // --- hq_mp3_url: array[1..6] of AnsiString = ( // URLs to NetRadio Stream -> HD Quality MP3 Codec 'http://listen.technobase.fm/dsl.pls', 'http://listen.housetime.fm/dsl.pls', 'http://listen.hardbase.fm/dsl.pls', 'http://listen.trancebase.fm/dsl.pls', 'http://listen.coretime.fm/dsl.pls', 'http://listen.clubtime.fm/dsl.pls'); hq_aac_url: array[1..6] of AnsiString = ( // URLs to NetRadio Stream -> HD Quality AAC Codec 'http://listen.technobase.fm/aacplus.pls', 'http://listen.housetime.fm/aacplus.pls', 'http://listen.hardbase.fm/aacplus.pls', 'http://listen.trancebase.fm/aacplus.pls', 'http://listen.coretime.fm/aacplus.pls', 'http://listen.clubtime.fm/aacplus.pls'); implementation {$R *.fmx} uses config, error, splash, minimode, tracklist; {--- -- Section for Playing & Recording the Internet Streams -- ---} function GetRecFileName:string; var stream:string; begin case playID of 1: stream:='tb'; 2: stream:='ht'; 3: stream:='hb'; 4: stream:='trb'; 5: stream:='ct'; 6: stream:='clt'; else stream:='none'; end; // Create Record Dir in case its not already there if not DirectoryExists(cfg.recdir) then CreateDir(cfg.recdir); // Callback the Filename Result:=cfg.recdir+FormatDateTime('yyyy.mm.dd', Now)+'_'+FormatDateTime('hh-nn', Now)+'_'+stream+'.mp3' end; function CalculateDurationLeft(start, stop: string):string; var sto_int, now_h_int, now_m_int, h_left, m_left:integer; begin sto_int:=strtoint(stop); now_h_int:=strtoint(FormatDateTime('hh', Now)); now_m_int:=strtoint(FormatDateTime('nn', Now)); h_left:=(sto_int-now_h_int) - 1; m_left:=60-now_m_int; Result:=inttostr(h_left)+':'+inttostr(m_left); end; function CalculateDurationPercent(start, stop: string):integer; var sto_int, sta_int, dura, now_h_int, now_m_int, h_left, m_left:integer; begin sto_int:=strtoint(stop); sta_int:=strtoint(start); now_h_int:=strtoint(FormatDateTime('hh', Now)); now_m_int:=strtoint(FormatDateTime('nn', Now)); dura:=(sto_int-sta_int)*60; h_left:=(sto_int-now_h_int) - 1; m_left:=(h_left*60)+(60-now_m_int); Result:=round((1-(m_left / dura))*100); end; procedure StatusProc(buffer: Pointer; len, user: DWORD); stdcall; begin {--- Recording the Internet Streams ---} if not DoRec then begin fRec.Free; fRec:=nil; // change Button skin frmMain.btRec.StaysPressed:=False; exit; end else begin // change Button skin frmMain.btRec.StaysPressed:=True; end; if (fRec = nil) then fRec:= TFileStream.Create(GetRecFileName, fmCreate); // create the file if (buffer = nil) then begin fRec.Free; // finished recording fRec:=nil; end else fRec.Write(buffer^, len); end; function OpenURL(url: PAnsiChar): Integer; var icy: PAnsiChar; Len, Progress: DWORD; i: integer; radname:string; begin // frmMain.pgBufferBar.Enabled:=False; Result := 0; progress := 0; // frmMain.lbInfosend.Caption := 'Status: -'; chan := BASS_StreamCreateURL(url, 0, BASS_STREAM_STATUS, @StatusProc, NIL); if (chan = 0) then begin //lets catch the error here inside the Thread // frmMain.lbInfosend.Caption := 'Status: -'; end else begin // Progress repeat len := BASS_StreamGetFilePosition(chan, BASS_FILEPOS_END); if (len = DW_Error) then break; progress := (BASS_StreamGetFilePosition(chan, BASS_FILEPOS_DOWNLOAD) - BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT)) * 100 div len; // percentage of buffer filled until progress > 99; // get the broadcast name and bitrate icy := BASS_ChannelGetTags(chan, BASS_TAG_ICY); while (icy^ <> #0) do begin if (Copy(icy, 1, 9) = 'icy-name:') then begin RadName:=StringReplace(Copy(icy, 10, MaxInt),'&','and',[rfReplaceAll, rfIgnoreCase]); // frmMain.lbInfosend.Caption := 'Status: '+RadName; end else if (Copy(icy, 1, 7) = 'icy-br:') then frmMain.lbStreamBit.Text :='Bitrate: '+Copy(icy, 8, MaxInt)+'k'; icy := icy + Length(icy) + 1; end; // frmMain.pgBufferBar.Position:=volpeak; // play it! BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, 0); BASS_ChannelPlay(chan, FALSE); BASS_ChannelSlideAttribute(chan, BASS_ATTRIB_VOL, (0.5), 3000); end; cthread := 0; // frmMain.pgBufferBar.Enabled:=True; end; {--- -- Collecting Information from radio.xml -- ---} procedure TfrmMain.InsertIntoTracklist(radio: integer; artist, song:string); var pos : integer; begin if (artist = '-') and (song = '-') then exit; if rdata[radio].tracklist = nil then SetLength(rdata[radio].tracklist, 1); pos:=length(rdata[radio].tracklist); if (rdata[radio].tracklist[pos-1].artist <> artist) or (rdata[radio].tracklist[pos-1].song <> song) then begin setlength(rdata[radio].tracklist, pos+1); rdata[radio].tracklist[pos].moderator:=rdata[radio].moderator; rdata[radio].tracklist[pos].show:=rdata[radio].show; // --- rdata[radio].tracklist[pos].artist:=artist; rdata[radio].tracklist[pos].song:=song; rdata[radio].tracklist[pos].time:=FormatDateTime('hh:mm', Time); rdata[radio].tracklist[pos].date:=FormatDateTime('dd.mm.yyyy', Date); end; // Versuche die Tracklist automatisch zu aktualisieren, wenn geöffnet try // if frmTracklist.Visible then frmTracklist.LoadTracklist; except end; end; procedure UrlToImage(Img: TImageControl; URL: string); var mStr: TMemoryStream; begin try DeleteUrlCacheEntry(PWideChar(url)); mStr := TMemoryStream.Create; frmMain.IdHTTP1.Get(PWideChar(url), mStr); mStr.Seek(0, soFromBeginning); Img.Bitmap.LoadFromStream(mStr); finally mStr.Free; end; end; procedure SetHeaderImage(Img: TImage; Radio: integer); var rStr: TResourceStream; begin try case radio of 1: rStr := TResourceStream.Create(hInstance, 'TB_logo', RT_RCDATA); 2: rStr := TResourceStream.Create(hInstance, 'HT_logo', RT_RCDATA); 3: rStr := TResourceStream.Create(hInstance, 'HB_logo', RT_RCDATA); 4: rStr := TResourceStream.Create(hInstance, 'TRB_logo', RT_RCDATA); 5: rStr := TResourceStream.Create(hInstance, 'CT_logo', RT_RCDATA); 6: rStr := TResourceStream.Create(hInstance, 'CLT_logo', RT_RCDATA); end; rStr.Position:=0; Img.Bitmap.LoadFromStream(rStr); finally rStr.Free; end; end; procedure UpdateDisplay(id: integer); var I : integer; begin // Displaying fetched Information for i := 1 to 6 do begin frmMain.sgOverview.Columns[i-1].Header:=rdata[i].name; frmMain.sgOverview.Cells[i-1,0]:=rdata[i].moderator; frmMain.sgOverview.Cells[i-1,1]:=rdata[i].show; frmMain.sgOverview.Cells[i-1,2]:=rdata[i].artist; frmMain.sgOverview.Cells[i-1,3]:=rdata[i].song; frmMain.sgOverview.Cells[i-1,4]:='von '+rdata[i].start+':00 bis '+rdata[i].stop+':00'; end; SetHeaderImage(frmMain.imgHeader, id); frmMain.imgPort.Bitmap:=portrait[id].Bitmap; frmMain.lbLcdName.Text:=rdata[id].moderator+' - '+rdata[id].show; frmMain.lbLcdArtist.Text:=rdata[id].artist+' - '+rdata[id].song; if (rdata[id].start = '0') and (rdata[id].stop = '0') then frmMain.lbStreamDuration.Text:='Dauer: nicht vorhanden' else begin frmMain.lbStreamTime.Text:=rdata[id].start+':00 Uhr bis '+rdata[id].stop+':00 Uhr'; frmMain.lbStreamDuration.Text:='Restzeit: '+CalculateDurationLeft(rdata[id].start, rdata[id].stop); frmMain.pbDuration.Value:=CalculateDurationPercent(rdata[id].start, rdata[id].stop); end; frmMain.lbStreamListener.Text:='Listener: '+rdata[id].listener; end; function UpdateMetatags : integer; var i : integer; mStr : TStream; xmldoc : IXMLDocument; begin xmldoc := newXMLDocument; try frmMain.IdHTTP1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0'; except frmMain.IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)'; end; try try DeleteUrlCacheEntry(PWideChar(dax)); mStr := TMemoryStream.Create; frmMain.IdHTTP1.Get(PWideChar(dax), mStr); // --- xmldoc.LoadFromStream(mStr); finally mStr.Free; end; except // Integratet GetXML Tool (collect Info by each WeaReoNe Radio Site) written by Felix Rudat ;) if not GetMetatagsXML then begin //Abbruch Download & Data Parsing frmMain.TtUpdate.Enabled:=False; // Deaktivieren des Autoupdates frmMain.lbInfoStream.Text:='Datenquellen nicht erreichbar und Direktabfrage über Hompage fehlgeschlagen.'; exit; end else try xmldoc.LoadFromFile(temp+xml); except //Abbruch Download & Data Parsing frmMain.TtUpdate.Enabled:=False; // Deaktivieren des Autoupdates frmMain.lbInfoStream.Text:='Datenquellen nicht erreichbar und Direktabfrage über Hompage fehlgeschlagen.'; exit; end; end; // Data Parsing xmldoc.Active:=True; for i := 1 to 6 do begin rdata[i].name:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['name'].Text; rdata[i].moderator:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['moderator'].Text; rdata[i].show:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['show'].Text; rdata[i].start:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['starttime'].Text; rdata[i].stop:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['endtime'].Text; rdata[i].profileurl:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['link'].Text; rdata[i].modpicurl:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['picture'].Text; rdata[i].artist:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['artist'].Text; rdata[i].song:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['song'].Text; rdata[i].listener:=xmldoc.DocumentElement.ChildNodes[i-1].ChildNodes['listener'].Text; if rdata[i].moderator = '' then rdata[i].moderator:='Playlist'; if rdata[i].show = '' then rdata[i].show:='Mixed Styles'; if rdata[i].artist = '' then rdata[i].artist:='-'; if rdata[i].song = '' then rdata[i].song:='-'; end; for i := 1 to 6 do UrlToImage(portrait[i], rdata[i].modpicurl); // Update Display UpdateDisplay(showID); // Insert Song in Tracklist if not cfg.short_tracklist then begin for i := 1 to 6 do frmMain.InsertIntoTracklist(i, rdata[i].artist, rdata[i].song); end else frmMain.InsertIntoTracklist(playID, rdata[playID].artist, rdata[playID].song); // Updating the Minitray Infos try // frmMinimode.Update; except exit; end; if mthread <> 0 then mthread:=0; end; procedure TfrmMain.TtUpdateTimer(Sender: TObject); var ThreadId : cardinal; begin if (mthread <> 0) then exit else mthread := BeginThread(nil, 0, @UpdateMetatags, nil, 0, ThreadId); end; {--- -- Programm loading Stage! -- ---} procedure TfrmMain.FormCreate(Sender: TObject); begin temp:=GetEnvironmentVariable('TEMP')+'\'; portrait[1]:=frmMain.imgPort1; portrait[2]:=frmMain.imgPort2; portrait[3]:=frmMain.imgPort3; portrait[4]:=frmMain.imgPort4; portrait[5]:=frmMain.imgPort5; portrait[6]:=frmMain.imgPort6; // little predefined Trash panMain.Position.X:=-1000; imgHeader.Opacity:=0; sgOverview.Selected:=5; aniIndicator.Opacity:=0; try // load the Config and Hotkeys LoadConfig; // load Tracklist LoadTracklist; finally // init the netstream playing plugin BASS InitBassPlugin; // register all nescesary hotkeys RegisterHotkeys; // Fetching first Streamtags UpdateMetatags; // Set last Infos pbVolumeWheel.value:=cfg.volume; // Setting up Configs { Autoupdate } TtUpdate.Interval:=cfg.metaintervall; TtUpdate.Enabled:=cfg.autoupdate; { Autoplay } if cfg.autoplay then begin case cfg.autoplradio of 1: begin imgPort1Click(imgPort1); btPlayClick(btPlay); end; 2: begin imgPort1Click(imgPort2); btPlayClick(btPlay); end; 3: begin imgPort1Click(imgPort3); btPlayClick(btPlay); end; 4: begin imgPort1Click(imgPort4); btPlayClick(btPlay); end; 5: begin imgPort1Click(imgPort5); btPlayClick(btPlay); end; 6: begin imgPort1Click(imgPort6); btPlayClick(btPlay); end; end; end; end; end; procedure TfrmMain.LoadConfig; var f: File of TCfg; begin try AssignFile(f, 'config.cfg'); { READ CONFIG FILE AND ADD } Reset(f); read(f, cfg); CloseFile(f); except // Allg Opt cfg.progcheck:=True; { FAIL SAVE DEFAULTS } cfg.hotkeys:=False; cfg.profilelink:=True; cfg.visualize:=False; cfg.volume:=15; // Stream Opt cfg.autoupdate:=True; cfg.metaintervall:=90000; cfg.short_tracklist:=False; cfg.nowplaying:=True; cfg.stream_codec:='mp3'; cfg.logdir:=ExtractFilePath(ParamStr(0))+'log\'; cfg.recdir:=ExtractFilePath(ParamStr(0))+'record\'; // Account Opt cfg.account.email:=''; cfg.account.password:=''; // Autostart Opt cfg.autostart:=False; cfg.autoplay:=False; cfg.minimized:=False; cfg.showsplash:=True; AssignFile(f, 'config.cfg'); Rewrite(f); write(f, cfg); CloseFile(f); ShowMessage('Keine oder fehlerhafte Konfigurationsdatei gefunden! Standart Datei wurde erstellt.'); end; end; procedure TfrmMain.LoadTracklist; var f : File of TTracklist; flist : TStrings; j,i : integer; begin try try flist:= TStringList.Create; flist.Add(#0); flist.Add(temp+'tracklist_tb.tmp'); flist.Add(temp+'tracklist_ht.tmp'); flist.Add(temp+'tracklist_hb.tmp'); flist.Add(temp+'tracklist_trb.tmp'); flist.Add(temp+'tracklist_ct.tmp'); flist.Add(temp+'tracklist_clt.tmp'); for j := 1 to 6 do begin if FileExists(flist[j]) then begin i:=0; AssignFile(f, flist[j]); Reset(f); while not EoF(f) do begin SetLength(rdata[j].tracklist, i+1); read(f, rdata[j].tracklist[i]); inc(i); end; if rdata[j].tracklist[1].date <> datetostr(Date) then // Erster Datensatz vom gleichen Tag? begin rdata[j].tracklist:= nil; break; // Nein? Neue Tracklist! end; CloseFile(f); DeleteFile(PWideChar(flist[j])); end; end; finally flist.Free end; except // Lade 50 Tracks von WeaReoNe Servern // frmTracklist.SyncTracklist; end; end; procedure TfrmMain.InitBassPlugin; begin // check the correct BASS was loaded if (HIWORD(BASS_GetVersion) <> BASSVERSION) then begin MessageBox(0, 'Falsche Version der BASS.DLL, eine Neuinstallation könnte das Problem beheben.', nil, MB_ICONERROR); Halt; end; if (not BASS_Init(-1, 44100, 0, Handle, nil)) then begin MessageBox(0, 'Audioausgabegerät konnte nicht initialisiert werden!', nil, MB_ICONERROR); Halt; end; BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1); // enable playlist processing BASS_SetConfig(BASS_CONFIG_NET_PREBUF, 0); // minimize automatic pre-buffering, so we can do it (and display it) instead BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, nil); // setup proxy server location end; procedure TfrmMain.RegisterHotkeys; var i : integer; begin if cfg.hotkeys then begin for i := 0 to length(cfg.hotkeylist) - 1 do begin if (cfg.hotkeylist[i].modifier <> '') and (cfg.hotkeylist[i].key <> 0) then begin if LowerCase(cfg.hotkeylist[i].modifier) = 'kein' then RegisterHotKey(Handle, i, 0, cfg.hotkeylist[i].key); if LowerCase(cfg.hotkeylist[i].modifier) = 'shift' then RegisterHotKey(Handle, i, MOD_SHIFT, cfg.hotkeylist[i].key); if LowerCase(cfg.hotkeylist[i].modifier) = 'strg' then RegisterHotKey(Handle, i, MOD_CONTROL, cfg.hotkeylist[i].key); if LowerCase(cfg.hotkeylist[i].modifier) = 'alt' then RegisterHotKey(Handle, i, MOD_ALT, cfg.hotkeylist[i].key); end; end; end; end; {--- -- Object Programming - Hotkeys and its functions -- ---} {procedure TfrmMain.WmHotkey(var Msg: TMessage); begin // Play TechnoBase.FM if (Msg.WParam = 0) then begin btPlayClick(btPlay); end; // Play HouseTime.FM if (Msg.WParam = 1) then begin btPlayClick(btPlay); end; // Play HardBase.FM if (Msg.WParam = 2) then begin btPlayClick(btPlay); end; // Play TranceBase.FM if (Msg.WParam = 3) then begin btPlayClick(btPlay); end; // Play CoreTime.FM if (Msg.WParam = 4) then begin btPlayClick(btPlay); end; // Play ClubTime.FM if (Msg.WParam = 5) then begin btPlayClick(btPlay); end; // Switch to Minimized / TrayIcon if (Msg.WParam = 6) then begin if not IsIconic(Application.Handle) then begin frmTrayInfo.spTrayIcon.Visible:=True; Application.MainForm.Hide; // fix minitray bug Application.Minimize; end else begin frmTrayInfo.spTrayIcon.Visible:=False; Application.MainForm.Show; // fix minitray bug Application.Restore; ForceForegroundWindow(frmMain.Handle); end; end; // Stop Stream if (Msg.WParam = 7) then begin //btStopClick(btStop); end; // Controll - Vol louder if (Msg.WParam = 8) then begin if pbVolumeWheel.Enabled then begin if cfg.volume <= 95 then begin cfg.volume:=cfg.volume+5; pbVolumeWheel.value:=cfg.volume; BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (cfg.volume / 100)); end; end; end; // Controll - Vol quiter if (Msg.WParam = 9) then begin if pbVolumeWheel.Enabled then begin if cfg.volume >= 5 then begin cfg.volume:=cfg.volume-5; pbVolumeWheel.value:=cfg.volume; BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (cfg.volume / 100)); end; end; end; // Show Tracklist if (Msg.WParam = 10) then begin if frmTracklist.Visible then frmTracklist.Hide else frmTracklist.Show; end; // Start / Stop Recording if (Msg.WParam = 11) then begin if not DoRec then DoRec:=True else DoRec:=False; end; end; } {--- -- Object Programming - Buttons and its functions -- ---} procedure TfrmMain.btConfigClick(Sender: TObject); begin frmConfig.ShowModal; end; procedure TfrmMain.btMuteClick(Sender: TObject); begin // mute if IsMute then begin BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, (cfg.volume / 100)); btMute.StaysPressed:=True; pbVolumeWheel.Enabled:=True; IsMute:=False; end else begin BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, 0); btMute.StaysPressed:=False; pbVolumeWheel.Enabled:=False; IsMute:=True; end; end; procedure TfrmMain.btStopClick(Sender: TObject); begin if playID <> 0 then begin // Free Channel BASS_StreamFree(chan); lbInfoStream.Text:='Wiedergabe beendet...'; lbStreamBit.Text:='Bitrate: -'; playID:=0; end; end; procedure TfrmMain.btTracklistClick(Sender: TObject); begin //if frmTracklist.Visible then frmTracklist.Hide else frmTracklist.Show; end; procedure TfrmMain.btPlayClick(Sender: TObject); var ThreadId: Cardinal; stream : PAnsiChar; begin // Double selected? Record! if showID = playID then begin if not DoRec then DoRec:=True else DoRec:=False; exit; end; // Stoppe Record wenn Streamswitch und Record aktiv if showID <> playID then begin if DoRec then DoRec:=False; end; // Set the Stream declaired in Config if cfg.stream_codec = 'mp3' then stream:=PAnsiChar(hq_mp3_url[showID]) else stream:=PAnsiChar(hq_aac_url[showID]); // Close old Stream if playID <> 0 then btStopClick(Sender); if (cthread <> 0) then exit else cthread := BeginThread(nil, 0, @OpenURL, stream, 0, ThreadId); playID:=showID; // Setting Up playing Radio end; procedure TfrmMain.btRecClick(Sender: TObject); begin if DoRec then DoRec:=False else DoRec:=True; end; { --- Overview Panel <3 FireMonkey --- } procedure TfrmMain.imgPort1Click(Sender: TObject); begin showID:=TImage(Sender).Tag; UpdateDisplay(showID); if panOverviewOut.Enabled then panOverviewOut.Enabled:=False; if panMainIn.Enabled then panMainIn.Enabled:=False; panOverviewOut.Enabled:=True; panMainIn.Enabled:=True; end; procedure TfrmMain.btOverviewClick(Sender: TObject); begin if imgHeaderOut.Enabled then imgHeaderOut.Enabled:=False; imgHeaderOut.Enabled:=True; end; procedure TfrmMain.panMainInFinish(Sender: TObject); begin if imgHeaderIn.Enabled then imgHeaderIn.Enabled:=False; imgHeaderIn.Enabled:=True; end; procedure TfrmMain.imgHeaderOutFinish(Sender: TObject); begin if panMainOut.Enabled then panMainOut.Enabled:=False; if panOverviewIn.Enabled then panOverviewIn.Enabled:=False; panMainOut.Enabled:=True; panOverviewIn.Enabled:=True; end; // Portrait Links -> Open in Favorite Browser procedure TfrmMain.imgPortClick(Sender: TObject); begin if cfg.profilelink then ShellExecute(handle, 'open', PWideChar(rdata[showID].profileurl), nil, nil, SW_Show); end; {--- -- volpeak Stuff - Statusbar / Trackerbar -- ---} procedure TfrmMain.pbVolumeWheelChange(Sender: TObject); var didgit_vol:real; didgit_val:single; begin didgit_val:=pbVolumeWheel.Value; if didgit_val <= -120 then pbVolumeWheel.Value:= -120; if didgit_val >= 120 then pbVolumeWheel.Value:= 120; didgit_vol:= (didgit_val / 240) + 0.5; if didgit_vol >= 1 then didgit_vol:= 1; if didgit_vol <= 0 then didgit_vol:= 0; //BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL, didgit_vol); cfg.volume:=round(didgit_vol * 100); end; {--- -- Close and Stop Threads! -- ---} procedure TfrmMain.FormDestroy(Sender: TObject); var i,j :integer; f : File of TTracklist; flist : TStrings; begin // unleash Bass.dll Bass_Free; // Write Tracklists try flist:= TStringList.Create; flist.Add(#0); flist.Add(temp+'tracklist_tb.tmp'); flist.Add(temp+'tracklist_ht.tmp'); flist.Add(temp+'tracklist_hb.tmp'); flist.Add(temp+'tracklist_trb.tmp'); flist.Add(temp+'tracklist_ct.tmp'); flist.Add(temp+'tracklist_clt.tmp'); for j := 1 to 6 do begin AssignFile(f, flist[j]); Rewrite(f); if rdata[j].tracklist <> nil then begin for i := 0 to length(rdata[j].tracklist) - 1 do write(f, rdata[j].tracklist[i]); end; CloseFile(f); end; finally flist.Free end; // Free Hotkeys if cfg.hotkeys then begin for i := 0 to length(cfg.hotkeylist) - 1 do UnRegisterHotkey(Handle, i); end; close; end; procedure TfrmMain.btCloseClick(Sender: TObject); begin Bass_Free; close; end; // Handle all Exceptions {procedure TfrmMain.AppEventsException(Sender: TObject; E: Exception); var f : textfile; begin try AssignFile(f, ExtractFilePath(ParamStr(0))+'errors.log'); if FileExists(ExtractFilePath(ParamStr(0)+'errors.log')) then Append(f) else Rewrite(f); writeln(f, '['+FormatDateTime('dd.mm.yyyy', Date)+' '+FormatDateTime('hh:mm:ss', Time)+'] '+E.ToString+' ('+SysErrorMessage(GetLastError)+')'); CloseFile(f); finally //frmError.RaiseErrorCode(E.ToString, SysErrorMessage(GetLastError)); end; end; } // Doppelstarts verhindern initialization mHandle:=CreateMutex(nil,True,'Programmname'); if GetLastError=ERROR_ALREADY_EXISTS then begin showmessage('Eine andere Instanz des Programms läuft bereits!'); Halt; end; finalization if mHandle <> 0 then CloseHandle(mHandle) end. Geändert von felitec (29. Jan 2012 um 10:24 Uhr) |
Zitat |
EWeiss
(Gast)
n/a Beiträge |
#2
Hab jetzt kein Firemonkey..
Aber was mir auffällt
Delphi-Quellcode:
Warum nicht einfach.
if not DoRec then DoRec:=True else DoRec:=False;
exit; DoRec := not DoRec PS: dein Code mit Delphitags formatiert sollte besser aussehen gruss |
Zitat |
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.056 Beiträge Delphi 12 Athens |
#3
Das ist aber kein Fehler in der Funktion.
Es ist maximal unnötig/unoptimal/unschön. Genauso wie hier:
Zitat:
if panMainOut.Enabled then panMainOut.Enabled:=False;
oder
Zitat:
if didgit_vol >= 1 then didgit_vol:= 1;
PS: dein Code mit Delphitags formatiert sollte besser aussehen
Ansonsten hab ich mir den unübersichtlichen Code jetzt nicht genauer angesehn, aber hab bis jetzt nichts wirklich Schlimmes entdeckt. Aber wäre es nicht besser, hier mal eine Testanwendung anzuhängen? Damit man es auch mal praktisch ausprobieren zu können? OK, abgesehn von 'Programmname'. Rate mal, was man dort reinschreiben sollte? Man sollte eben nicht immer alles nur blind kopieren. Denn wenn das alle machen würden, dann hättst du Probleme, da du dann dein Programm nicht gleichzeitig laufen lassen könntest, wenn schon ein Programm eines anderen C&P-Programmieres läuft. Ach ja, du willst aber jetzt nicht auf Firemonkey wechseln, um später mal später mal MAC, Linux und Co. unterstützen zu können? Mit der Windows-BASS-DLL kommt man da zumindestens nicht sehr weit.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat, wird PoSex im Delphi viel seltener praktiziert. Geändert von himitsu (28. Jan 2012 um 21:42 Uhr) |
Zitat |
EWeiss
(Gast)
n/a Beiträge |
#4
Zitat:
Das ist aber kein Fehler in der Funktion.
Zitat:
Es ist maximal unnötig/unoptimal/unschön.
Zitat:
Mit der Windows-BASS-DLL kommt man da zumindestens nicht sehr weit.
Cross Platform Libraries with Firemonkey gruss Geändert von EWeiss (28. Jan 2012 um 22:06 Uhr) |
Zitat |
Registriert seit: 2. Mär 2010 7 Beiträge |
#5
Das der Quelltext teilweise unübersichtlich und unschön ist steht außer frage, ich habe mit dem Programm vor circa 6 Jahren in Delphi 6 begonnen als ich 13 Jahre alte war ^^
Firemonkey möchte ich Hauptsächlich wegen der Grafischen spielerreien nutzen, so blöd wie das auch klingt. Falls wirklich keiner irgend nen Fehler findet, werde ich entweder noch ne "Probe-Exe" anhängen oder nen kompletten rewrite machen müssen :/ MfG und danke schonmal! |
Zitat |
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.056 Beiträge Delphi 12 Athens |
#6
Das der Quelltext teilweise unübersichtlich und unschön ist steht außer frage
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat, wird PoSex im Delphi viel seltener praktiziert. |
Zitat |
Registriert seit: 2. Mär 2010 7 Beiträge |
#7
Quellcode ist jetzt in Delphi Tags formatiert. Zusätzlich möchte ich noch sagen, das die folgenden Funktionen für das Wiedergeben eines Streams zuständig sind:
- InitBassPlugin - StatusProc - OpenUrl - btPlayClick MfG |
Zitat |
EWeiss
(Gast)
n/a Beiträge |
#8
Zitat:
Quellcode ist jetzt in Delphi Tags formatiert.
Schon gesehen? Here's a demo that works with Delphi XE2 and Firemonkey gruss |
Zitat |
Registriert seit: 2. Mär 2010 7 Beiträge |
#9
Ich danke erstmal allen für die Ratschläge! Der Quellcode Formatierungs Assisent ist genial
Jedoch... ich habe immer noch keine Lösung für DAS Problem :/ Im folgenden häng ich die Anwendung und Bass.DLL an. Bitte bedenkt, dass im Moment gerade einmal 5% des kompletten Programms "überarbeitet" wurden und es natürlich zu unzähligen Fehlern neben dem eigentlichen Problem kommen kann. MfG |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |