Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Firemonkey (xe2) Problem mit BASS.DLL Netstream! (https://www.delphipraxis.net/166073-firemonkey-xe2-problem-mit-bass-dll-netstream.html)

felitec 28. Jan 2012 18:27

Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
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.

EWeiss 28. Jan 2012 19:56

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Hab jetzt kein Firemonkey..
Aber was mir auffällt

Delphi-Quellcode:
  if not DoRec then DoRec:=True else DoRec:=False;
  exit;
Warum nicht einfach.
Delphi-Quellcode:
DoRec := not DoRec


PS: dein Code mit Delphitags formatiert sollte besser aussehen ;)

gruss

himitsu 28. Jan 2012 20:39

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Das ist aber kein Fehler in der Funktion.
Es ist maximal unnötig/unoptimal/unschön.

Genauso wie hier:
Zitat:

Delphi-Quellcode:
if panMainOut.Enabled then panMainOut.Enabled:=False;

das if ... then kann weg, da das in dem Enable-Setter sowieso schon/nochmal geprüft wird.
oder
Zitat:

Delphi-Quellcode:
if didgit_vol >= 1 then didgit_vol:= 1;

">" reicht, denn bei Gleichheit entspricht es dem zu setzenden Wert, was dann ja unnötig wäre, es nochmals zu setzen.

Zitat:

Zitat von EWeiss (Beitrag 1148072)
PS: dein Code mit Delphitags formatiert sollte besser aussehen ;)

Einige Funktionen wären mit einer passenden Quelltextformatierung bestimmt auch übersichtlicher aussehn.



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'. :gruebel:
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. :roll:

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.

EWeiss 28. Jan 2012 21:01

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Zitat:

Das ist aber kein Fehler in der Funktion.
Habe ich auch nicht beanstandet :)

Zitat:

Es ist maximal unnötig/unoptimal/unschön.
Korrekt !

Zitat:

Mit der Windows-BASS-DLL kommt man da zumindestens nicht sehr weit.
Kann sich ja mal hier schlau machen!
Cross Platform Libraries with Firemonkey


gruss

felitec 28. Jan 2012 21:44

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
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!

himitsu 29. Jan 2012 00:29

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Zitat:

Zitat von felitec (Beitrag 1148093)
Das der Quelltext teilweise unübersichtlich und unschön ist steht außer frage

Tipp: Soo viel Arbeit muß man sich nicht machen, aber kennst du schon das neue Strg+D ? (Quellcodeformatter)

felitec 29. Jan 2012 09:31

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
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

EWeiss 29. Jan 2012 14:25

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Zitat:

Quellcode ist jetzt in Delphi Tags formatiert.
So ist es auf jedenfall besser lesbar.

Schon gesehen?
Here's a demo that works with Delphi XE2 and Firemonkey

gruss

felitec 30. Jan 2012 18:43

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich danke erstmal allen für die Ratschläge! Der Quellcode Formatierungs Assisent ist genial :D

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

EWeiss 30. Jan 2012 19:00

AW: Firemonkey (xe2) Problem mit BASS.DLL Netstream!
 
Das was zur Auswahl steht getestet und kein problem gefunden..
Streamt einwandfrei.

win7/64Bit

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:14 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz