Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi MP3-Player selbst schreiben, Grundvoraussetzungen? (https://www.delphipraxis.net/141453-mp3-player-selbst-schreiben-grundvoraussetzungen.html)

Aike 9. Okt 2009 08:55


MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Hallo, Leute,

nachdem ich über ein Jahr nicht mehr programmiert habe, möchte ich mich mal wieder mit einem Problem beschäftigen: Ich möchte mir einen MP3-Player programmieren. Seither habe ich halt Winamp benutzt, aber zum einen bin ich mit einigen Funktionen unzufrieden, zum anderen möchte ich es für meinen Gebrauch vereinfachen/umgestalten und außerdem ist es natürlich die Herausforderung des Programmierens, die mich treibt ;-)

Ich kenne mich zwar mittlerweile ziemlich gut mit Delphi aus, würde ich sagen, aber ich hab eigentlich noch nie mit Multimedia gearbeitet. Meine Probleme wären also zum Beispiel, wenn ich so drüber nachdenke, wie ich etwa in einer MP3-Datei nach vorne/zurück spulen kann (mittels Button oder Schieberegler), und wie ich systemweite Hotkeys erstellen kann (wie in Winamp: Globale Tastenkürzel). Es gibt ja eine Hotkey-Komponente, aber die funktioniert, so wie ich die Hilfe verstanden habe, nur innerhalb des Programmes und nur für Menü-Items.

Was ich auch hier schon öfter gelesen habe, waren Bemerkungen zur Bass.dll. Mit DLL-Einbindung hatte ich noch gar nichts zu tun und das würde mir wohl erstmal nicht so leicht fallen, wenn es da nicht eine gute Beschreibung dazu gäbe; also wenn's geht, würde ich das gerne umgehen. Wenn's nicht geht, sagt's mir gleich *g* Ah ja, ich hab hier übrigens D7, ist ja schon etwas älter ... vielleicht gibt es bei neuen Delphi-Versionen ja andere Komponenten :-/

Wär wie immer toll, wenn ihr mir auch dieses Mal weiterhelfen könntet :-)

Liebe Grüße!

Forlan 9. Okt 2009 08:58

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Du könntest dir mal das MP3 Player Beispiel angugen im Bei Google suchenDelphi-Treff

Ich denke mal das sollte dir helfen ;)

Schau dort mal unter "Tutorials" - "Sonstiges"

Gausi 9. Okt 2009 09:27

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Man kann natürlich auch mit der TMediaplayer-Komponente was basteln, aber was richtiges wird das dann nicht. Da ist die bass.dll (oder fmod als Alternative) deutlich besser geeignet. Es sei denn, man möchte wirklich alles selber machen.
Die Einbindung der bass.dll ist dabei das kleinste Problem. Einfach die bass.dll und bass.pas in den Projektordner kopieren und die Funktionen benutzen. Und mit Delphi7 funktioniert das auch. :D

Hier noch ein Direktlink zu dem Player-Tutorial: http://www.delphi-treff.de/tutorials...er-mp3-player/

Aike 9. Okt 2009 11:08

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ok, das waren jetzt grauenvolle 30 Minuten ;-p

Ich habe das Tutorial gelesen (Seite 1, 2 und die letzte). Teilweise leider etwas zu ungenau für mich, darum bin ich gleich zum Ende, hab mir die fertigen Dateien angeschaut und dann verstanden, was er auf Seite 2 meinte. Gut, ich hab also die erforderlichen Dateien in einen Ordner kopiert (ATL_WMAfile.pas, bass.dll, config.inc, Mp3FileUtils.pas, U_CharCode.pas), die Klasse "AudioDatei_Klasse" erstellt, den Type deklariert und die beiden procedures und die function von Seite 2 eingefügt, alles wie erklärt.

Wie auf Seite drei steht, hab ich dann auch den Test-Player erzeugen wollen. Die Klassen-Datei in die uses-Liste eingefügt, globale Variable erstellt, Create-Ereignis erzeugt => Fehler: Mp3FileUtils: File not found: TntSysUtils.dcu. Der Achim gar nicht faul, googlet TntSysUtils, lädt sich's runter. Danach hab ich noch 10 weitere Tnt-Dateien gezogen, von denen nichts beim Delphi-Treff steht und die gerne Fehlermeldungen rumwerfen. Als ich dann alle hatte, kam eine weitere "*.dcu fehlt"-Meldung, und die Datei gab es dann nicht auf dem Server. Jetzt bin ich hilflos und muss euch wieder nerven *gg*

Gausi 9. Okt 2009 11:43

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Guck dir mal die config.inc an, die bei den MP3FileUtils dabei ist. Da kann man die Verwendung der TNTs per Compilerschalter abstellen. Einzige Auswirkung: Vor D2009 kann man dann keine Dateien abspielen, die "Unicode-Zeichen" im Dateinamen haben.

Aike 9. Okt 2009 12:08

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ok, hab ich gemacht. Jetzt bekomme ich den Fehler in ATL_WMAfile:
(Code: uses Classes, SysUtils, TntClasses;)
File not found: TntClasses.dcu

Gausi 9. Okt 2009 12:14

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Hm. Vielleicht solte ich das mal überarbeiten. :?

Nimm die TntClasses da raus und lösch die Kommentarzeichen // ein paar Zeilen weiter unten bei
Delphi-Quellcode:
{If TntClasses are not available:} 
// TTntFileStream = TFileStream;
Die werden da für dieselben Zwecke benutzt. ;-)

Aike 9. Okt 2009 14:11

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
*Seufz* Nächstes Problem: Ich will gerade Version 2.0 compilieren, habe alles soweit ausgeführt mit Buttons erstellen, destructor, constructor etc. pp., aber ich bekomme wieder einen Haufen Fehlermeldungen:

Delphi-Quellcode:
[Error] Player_Klasse.pas(70): Undeclared identifier: 'Assign'
[Error] Player_Klasse.pas(73): Undeclared identifier: 'BASS_ChannelSetAttributes'
[Error] Player_Klasse.pas(115): Undeclared identifier: 'BASS_ChannelSetAttributes'
[Error] Player_Klasse.pas(137): Undeclared identifier: 'SetPosition'
[Error] Player_Klasse.pas(137): ';' expected but '(' found
[Error] Player_Klasse.pas(139): Undeclared identifier: 'fMainStream'
[Error] Player_Klasse.pas(139): Undeclared identifier: 'Value'
[Error] Player_Klasse.pas(146): Undeclared identifier: 'SetPosition'
[Error] Player_Klasse.pas(30): Unsatisfied forward or external declaration: 'TMeMPPlayer.InitBassEngine'
[Fatal Error] uPlayer.pas(7): Could not compile used unit 'Player_Klasse.pas'
Abgesehen davon, gibt es "procedure TMeMPPlayer.SetPosition(Value: Longword);" gar nicht, was auf Seite "Abspielen mit der bass.dll" eingeführt wird :-(((

Gausi 9. Okt 2009 14:50

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Naja, deswegen richtet sich das Tutorial ja auch an erfahrenere Programmierer. :stupid:

Die Methode Assign ist im Tutorial-Text nicht weiter erläutert. Die muss man (das steht da aber iirc) selber schreiben, d.h. sämtliche Eigenschaften rüberkopieren. Im Quelltext-Archiv ist die enthalten. BASS_ChannelSetAttributes ist ein Fehler vom Delphi-Treff, ich hatte eigentlich da mal ne Mail hingeschrieben, dass das ausgebessert wird. Und das war meine ich auch mal ausgebessert :gruebel:. Hat mit der Inkompatibilität von Version 2.3 und 2.4 der bass.dll zu tun. SetPosition sollte aber deklariert sein - kann sein, dass das ein Folgefehler wegen dem davor ist.

Probier mal die Version von meiner Seite, die sollte aktuell sein. ;-)

http://gausi.de/delphi/memp/

Aike 9. Okt 2009 15:22

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ich hab nirgendwo eine Assign-Methode gefunden in deinen Dateien, was mir etwas sagen würde :-(
[edit] Ok, Assign gefunden in der AudioDatei_Klasse.pas :angel: [/edit]

"BASS_ChannelSetAttribute(fMainStream, BASS_ATTRIB_VOL, fMainVolume);" steht auch in deiner Version, Zeile 255 von Player_Klasse.

Gausi 9. Okt 2009 15:50

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Bass_ChannelSetAtrritbute gibts ja auch, Bass_ChannelSetAttributes gibt es nicht mehr.

lbccaleb 9. Okt 2009 16:30

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Noch ein paar gerade neue Trheads zu dem Thema (allerdings nicht mit WinAmp sonder über DirectX) findest du hier:


OT-Small Tunes
DirectShow Player Demo
MP3 mit DX abspielen macht Fehler

Aike 9. Okt 2009 17:29

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Gut, danke euch beiden :-)

Ich bin jetzt auch sehr viel weitergekommen, allerdings bin ich auf diese Fehlermeldung gestoßen:

-->> (Error) Player_Klasse.pas: Undeclared identifier: 'Explode'

Quelltext dazu:
Delphi-Quellcode:
tmpext := Explode(';',Info.Formats[a].exts);
(Im Original Zeile 188)

Klaus01 9. Okt 2009 17:33

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Hallo,

hier findest Du explode.

Grüße
Klaus

Aike 9. Okt 2009 22:16

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
*Seufz* Ok, Explode hab ich eingefügt, gibt immer noch einen Fehler:
>> tmpext := Explode(';',Info.Formats[a].exts); << liefert der Fehler ...
"Incompatible types: 'TStringList' and 'TStringDynArray'"

Wishmaster 9. Okt 2009 22:56

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Hi

du kannst auch das open source Project NewAC :thumb: :thumb: :thumb: nehmen.


Short feature description:

* Audio recording and playback using DirectSound
* Audio recording and playback using low latency ASIO drivers
* CD-ripping
* Supported formats: wav, Ogg Vorbis, FLAC, Monkey Audio, WavPack, MP3, Windows WMA, DTS, AC-3, TTA, OptimFROG, TAK, Musepack
* Sound mixing, concatenation, cutting and insertion of audio fragments.
* Audio resampling
* 8, 16, 24, 32 bit sound support
* Multi-channel sound
* Id3v*, Ape, Vorbis tags support
* Ready for Delphi 2009..2010
* License: NewAC is free for both open source and commercial use


http://symmetrica.net/newac/

Gausi 10. Okt 2009 09:02

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ja, ich verwende da wohl eine etwas andere Explode-Funktion. Die wird aber auch mitgeliefert in der Player_Klasse.pas. Da sie in dem Beispiel-Projekt nur dort benötigt wird, steht sie nicht im Interface-Teil, sondern am Anfang von implementation.

Aike 10. Okt 2009 17:21

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Gut, gut. Ich bin fertig mit dem Tutorial (*schnauf*), danke nochmals.

Leider funktioniert nicht alles wie gewünscht:
Weder "OnMeMPChange" noch "OnMeMPEndFile" werden jemals aktiviert. "OnMeMPEndFile" konnte ich aber überbrücken, indem ich die Position des Schiebereglers abgefragt habe. Bei dem Change ist mir nichts eingefallen. "OnMeMPPlay" funktioniert komischerweise auch nicht richtig, sondern erst wenn ich das Abspielen angehalten und dann wieder auf Play gedrückt habe. Kannst du dir da einen Reim drauf machen? Ggf. kann ich den Code posten, aber ich wollte hier nichts fluten *g*

[edit]Das mit Play passiert auch immer, wenn ich Stopp drück, zu einem anderen Titel gehe und dort Play drücke :-( [/edit]
[edit2]Mir fällt auch grade auf, dass Titellängen mit mehr als 37 Zeichen abgekürzt werden. Warum das denn? *G*[/edit]
[edit3]Der Stopp-Button bzw. das Event geht bei mir auch nicht o.O[/edit]

StevenArt 10. Okt 2009 20:07

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
@ gausi: Beim Komplitieren von 'MeMP (Zip-Archiv mit PDF und Quellcode)' kommt bei mir der Fehler: '[Fataler Fehler] AudioDatei_Klasse.pas(16): Datei nicht gefunden: 'Mp3FileUtils.dcu' ' wie mach ichs dass der Player geht?

Aike 11. Okt 2009 08:43

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Na ja, du musst die Mp3FileUtils.pas halt runterladen und einbinden.

Aike 13. Okt 2009 09:15

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ich habe Punkt 1 und 3 meines Edits fixen können, indem ich meine Version mit dem (original) Source Code verglichen und kopiert hab. Leider weiß ich überhaupt nicht, was schiefgegangen sein könnte *g* OnEndFile etc. geht auch.

Allerdings gibt es immer noch das 27-Zeichen-Problem.

Ich hab ein bisschen weiterprogrammiert und bin jetzt zu einem weiteren Problem gekommen: Ich möchte gerne die Soundkarte für die Ausgabe zur Laufzeit ändern. Um die Soundkarten rauszubekommen, benutze ich diesen Code, der auch funktioniert:

Delphi-Quellcode:
const
  DRVM_MAPPER_PREFERRED_SET = $2000+22;

implementation

{$R *.dfm}

function ChangePrimarySndOutDevice(dev: cardinal): integer;
{dev Bereich: 0 bis waveOutGetNumDevs - 1} 
begin
  result := waveOutMessage(HWAVEOUT(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_SET, dev, 0);
end;

//Listet alle verfügbaren Ausgabekarten
procedure TfrmSoundkarte.GetOutDevices;
var
  dev: Integer;
  caps: TWaveOutCaps;
begin
  ComboBox1.Clear;
  for dev := 0 to waveOutGetNumDevs - 1 do
  begin
    waveOutGetDevCaps(dev, @caps, sizeof(TWaveOutCaps));
    ComboBox1.Items.Add(caps.szPname);
  end;
  ComboBox1.ItemIndex := 0; //Die jetzige primäre Soundkarte auswählen
end;

//Alle Comboboxen füllen
procedure TfrmSoundkarte.FormCreate(Sender: TObject);
begin
  GetOutDevices;
end;

procedure TfrmSoundkarte.Button1Click(Sender: TObject);
begin
  if ChangePrimarySndOutDevice(Combobox1.ItemIndex) = MMSYSERR_NOERROR then
  begin
    GetOutDevices; //Windows setzt immer die primäre Karte als 0, daher müssen wir die Liste neu holen
    MessageDlg('Primäres Ausgabegerät wurde erfolgreich geändert', mtInformation, [mbOK], 0);
    close
  end
  else
    MessageDlg('Fehler beim Setzen des primären Ausgabegerätes', mtError, [mbOK], 0);
end;
Den Code hab ich hier gefunden, weiß leider den Thread nicht mehr, sonst würd ich ihn verlinken. Jedenfalls, schön und gut, das funktioniert, aber natürlich nicht zur Laufzeit des Programmes. Da es bei Winamp geht, muss es aber irgendwie gehen ;-p Ich habe mir überlegt, dass die Soundkarte vielleicht beim Create von MeMPPlaylist zugewiesen wird und habe versucht, nach dem ändern der Soundkarte MeMPPlaylist freizugeben und neu zu erzeugen, aber dann geht der Player nicht mehr (stürzt nicht ab, spielt aber auch nicht).

Hat jemand Vorschläge? *g*

Gausi 13. Okt 2009 09:51

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Vergiss den Code da oben erstmal.

Schau dir mal die Hilfe-Datei zur Bass.dll an. Auf welcher Karte die Wiedergabe läuft, kann man darüber steuern. Da muss man nicht die Systemeinstellungen für ändern. Auswendig weiß ich die nötigen Befehle jetzt nicht, aber die Hilfe zur Bass ist recht übersichtlich. :D

Aike 13. Okt 2009 10:55

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ok, ich werd mir das gleich ansehen.

Zwischenfrage: Internet-Radio? *g* Ich dachte an sowas wie "http://62.26.214.248:80/swr1bwlive/livestream.mp3", "http://stream-1.ssatr.ch:80/rsp/mp3" oder "http://cdn-two.977music.com/classic64?.wma". Das sind die drei, die ich grade gespeichert habe, und sie haben alle 'n anderes Format. Wie könnte ich denn sowas mit einbinden? *g*

[edit]gibt ja genug hier im Forum dazu, also weiterlesen ... *g*[/edit]

Aike 13. Okt 2009 11:20

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Hm, also ... Mir scheint, als wäre BASS_GetDevice bzw BASS_SetDevice das richtige, aber ...
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  showmessage(inttostr(BASS_GetDevice()));
  BASS.BASS_SetDevice(0);
  showmessage(inttostr(BASS_GetDevice()));
end;
... macht gar nichts, bzw. es kommt immer "1", wobei "0" eigentlich sogar gemutet sein sollte :-/

[edit]Mein Radiostream funktioniert ganz gut, leider gibt es ein Problem: Der Stream wird mit einem Thread eröffnet:
Delphi-Quellcode:
cthread := BeginThread(nil, 0, @OpenURL, PChar(URL), 0, ThreadId);
Da geht mein Lautstärken-Regler nicht mehr für den Stream :-(
Und wie kann ich den Stream wieder schließen? EndThread(ThreadID) und ExitThread(ThreadID) schließen mir mein Programm und nicht den Stream *gg*

Aike 19. Okt 2009 14:09

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Ok, ich konnte die Lautstärke anpassen, indem ich im OnScroll-Event das hier eingefügt habe:
Delphi-Quellcode:
Lautstaerke:=(100 - Scrollpos) / 100;
MeMPPlaylist.Volume := Lautstaerke;
BASS_ChannelSetAttribute(chan, BASS_ATTRIB_VOL,Lautstaerke);
Den Stream zum Halt bringen konnte ich mit
Delphi-Quellcode:
BASS_ChannelPause(chan);
beim Stopp-Button. :hello:

Allerdings habe ich immer noch das Problem, dass ich die Ausgabe-Soundkarte nicht ändern kann, s.o.
Außerdem ist mir grade aufgefallen, dass ich keine Titel aus der MeMPPlaylist löschen kann. Ich kann sie zwar aus der Listview entfernen, aber intern wird es nicht gelöscht. Gibt es da schon Code, ein Beispiel oder so? Ich stell mir das ziemlich schwierig vor und ich will ungern einfach in der MeMPPlaylist rumpfuschen. Am Ende geht gar nichts mehr, oder meine Lösung ist 4x so lang :glaskugel:

Oliver1983 13. Nov 2009 09:59

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
@Gausi,

also beim besten willen bekomme ich dein Projekt nicht zum laufen, Compilieren kann ich es ohne Fehler meldungen, aber sobald ich eine mp3 datei ausgewählt habe und auf play drücke passiert nichts!!! Ich bekomme nicht mal eine Fehler meldung oder dergleichen, kannst du mal den source inkl der anderen klassen units bereit stellen nicht das es versions unterschiede gibt? und auch bitte nicht die bass.dll vergessen, das wäre prima

gruss olli

Gausi 13. Nov 2009 10:39

Re: MP3-Player selbst schreiben, Grundvoraussetzungen?
 
Laut Profil hast du Delphi 2009.

Das Tutorial ist noch nicht auf D2009 portiert, werde ich mal in Angriff nehmen. Man bekommt es zum Laufen, wenn man in der Methode TMeMPPlayer.MeMP_CreateStream die Flags um BASS_UNICODE erweitert. Also

Delphi-Quellcode:
function TMeMPPlayer.MeMP_CreateStream(aFilename: String): DWord;
var flags: DWORD;
begin
  if (AnsiLowerCase(ExtractFileExt(aFilename)) = '.mp3') then
    flags := BASS_STREAM_PRESCAN or BASS_UNICODE
  else
    flags := BASS_UNICODE;
  result := BASS_StreamCreateFile(False, PChar(aFilename), 0, 0, flags);
end;
Dadruch wird der Parameter Filename von der bass.dll als WideChar interpretiert, was ja ein Char unter D2009 ist. Das müsste ich mal über Compiler-Schalter sauber einbauen. Auch das Laden der Plugins könnte noch Schwierigkeiten machen - stört aber nicht für die Basisfunktion.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:19 Uhr.

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