![]() |
MP3 in Cache "zwischenspeichern"
Ist es irgendwie möglich einen Teil einer MP3 Datei (die letzten 2 Sekunden) einzulesen (Stream oder sowas ähnliches), und diese dann abzuspielen?
(Außerdem müsste ich dann noch die Lautstärke des Abspielens ändern können) |
Re: MP3 in Cache "zwischenspeichern"
Hmm... Kommt darauf an, wie. Du könntest die Datei öffnen und dann soweit vorspulen, bis du bei (Gesamtzeit - 2 Sekunden) angekommen bist,
oder du liest die Datei halt mit TFileStream aus, wobei du dann natürlich auch den Header entsprechend verarbeiten musst. (Nein, das ist sicher nicht einfach, vor allem bei VBR) |
Re: MP3 in Cache "zwischenspeichern"
Zitat:
|
Re: MP3 in Cache "zwischenspeichern"
Zitat:
MP3-Formatspezifikationen gibt es auf ![]() |
Re: MP3 in Cache "zwischenspeichern"
Zitat:
|
Re: MP3 in Cache "zwischenspeichern"
Moin,
ich habe so etwas gerade erstellt. Auf Basis des BASS-Systems. Ich nehme allerdings nicht die letzten 2 Sekunden, sondern messe die letzten 20 Sekunden des Liedes aus. Wenn das Lied gestartet wird, starte ich es in einem zweiten Programm-Thread, in einem lautlosen Kanal parallel. Dort springe ich an die letzten 20 Sekunden, spiele das Lied ab und speichere die Pegel. Dann gehe ich vom Ende zurück und suche eine bestimmte (selbst definierte) Pegelstelle, bei der das Lied enden soll. Man erhält so nach 20 Sekunden die Abbruchzeit für das aktuelle Lied. Diese Vorgehensweise ist lieder notwendig, weil man nur dann die Pegel auslesen kann, wenn der Stream abgespielt wird (beim BASS-System). Wenn du das allerdings mit eigenen Mitteln berechnen willst, dass würde mich dann auch mal interessieren. Die Endzeit des aktuellen Liedes ist die Startzeit des nächsten Liedes. Jedes Lied wird bis zum Ende abgespielt. Es entsteht also kein abrupter Wechsel, sondern ein sauberes Überblenden. MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
Ja wigentlich wollte ich genau das selbe coden.
Mit Bass sollen "einfach" 2 Lieder übergeblendet werden. Ich habe mein Programm jedoch auf Basis der Bass Komponente erstellt, und wollte zunächst 2 Player für die Realisierung des Fadings nehmen, bis ich erkennen musste, dass die Komponente nur einmal im Programm verwendet werden kann. Daher suche ich nach Alternativen das fading zu coden... |
Re: MP3 in Cache "zwischenspeichern"
Du brauchst doch das BASS-System nur einmal, dir stehen doch dann mehrere Kanäle zur Verfügung.
Ich habe sogar zwei Soundkarten und habe durch einen Trick (DLL wird zweimal geladen) in einer Anwendung das BASS-System zweimal gestartet, für jede Soundkarte. Damit kann man auf der einen Soundkarte abspielen (mehrere Kanäle mischen) und die anderen Soundkarte kann als Monitor benutzt werden. Ich verstehe also nicht ganz, wo dein Problem liegt. MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
ok das klingt alles super.
Mein "Problem" ist, dass ich diese Komponente benutze: ![]() Um deine Idee zu realisieren, müsste ich ja wahrscheinlich direkt die bass.dll verwenden.. |
Re: MP3 in Cache "zwischenspeichern"
Ja, ich habe das BASS-System direkt benutzt.
Das ist eigentlich auch nicht sehr schwer. Der Code der Komponente ist ja auch gegeben. Mich juckte das gerade, denn die Komponente ist eigentlich noch sehr gut ausbaufähig. Besonders das dynamische Laden der DLL gefällt mir. Nur leider funktioniert diese Komponente bei mir überhaupt nicht. Schade. Nicht als Normaler Benutzer und auch nicht als Administrator. Beim Starten des Beispielplayers bekomme ich einen Integer-Überlauf. Nja, dann eben nicht. Kann dir leider mit dieser Komponente nicht weiterhelfen. MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
Hast du vielleicht irgendwo einen Beispiel -Player in dem du direkt mit der bass.dll arbeitest?
|
Re: MP3 in Cache "zwischenspeichern"
Ja diese Komponente.
Du schaust dir den Sourcecode an und baust deine Sachen da ein und soweit sie Sinnvoll sind veröffentlicht du sie wieder. Was du willst heisst übrigens crossfade. Ich hab das selber übrigens schon integriet muss mir aber erstmal überlegen ob ich das veröffentliche. |
Re: MP3 in Cache "zwischenspeichern"
Moin,
habe mich nochmal mit dieser Komponente beschäftigt. Und das darf ja wohl nicht war sein! Jeder, der ein Programm mit dieser Komponente fehlerfrei starten kann, hat seine Bereichs- und Überlaufs-Fehlerprüfung nicht eingeschaltet! Das heisst alle die so programmieren, programmieren unsicher. Ich bin zur zeit dabei diese Komponente und alles was damit zusammenhängt zu überarbeiten. Böse Befehle wie Exit und Halt werden entfernt. Fehlermeldungen, die einfach durch eine MessageBox ausgegeben werden werden in Exceptions gewandelt. Leider enthält der DLL-Loader auch noch ein Speicherleck. Die Komponente schränkt die Benutzung das BASS-System unnötig ein, dies möchte ich eingentlich beheben. Also ich arbeite noch dran... MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
Ich habe schon mit dem User "turboPASCAL", der die Bass Komponente zu der oben der Link steht, gecodet hat gesprochen (wegen dem Crossfaden):
Er sagt dazu: "1. Im constructor TBassdllPlayer.Create wird schon ein Recording Device inizialisiert... Quellcode: markieren if not BASS_RecordInit(0) then begin BASS_RecordFree; BASS_Free(); MessageDlg('Cannot start default recording device!', mtError, [mbOk], 0); halt; end; ...und zweimal das gleiche Gerät öffnen geht einfach nicht. Also kann man nicht 2 oder mehr BassdllPlayer in einem Prg. verwenden. 2. Es darf nur eine BASS.DLL in den Speicher geladen werden sonst gibt das eventuell einen Konflikt. Man müsste das gesamte Ding fast komplett umschreiben auf "Mehrfachbenutzung". Wenn Du mehrere Sounds gleichzeitig abspielen möchtest ist die BassdllPlayer-Kompo. (leider) nicht geeignet. " |
Re: MP3 in Cache "zwischenspeichern"
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mir das Ganze noch mal durch den Kopf gehen lassen, das einfachste um ein Crossfade zu realisieren ist wohl ein simples "Channelblending".
dazu im Demo verwendet:
Delphi-Quellcode:
BASS_ChannelSlideAttributes eignet sich nur zum Ausblenden.
BASS_ChannelSetAttributes(DWORD handle, int freq, int volume, int pan);
Im Anhang ist dazu eine einfache Demo (Source) es benötigt die Bass.pas und Bass.Dll. Man kann dies auch umgehen und von der TBassDLLPlayer Komponente die Dateien Bass_Dynamic.pas und DLLLoader.pas in das Verzeichnis kopieren, und in der uMain.pas die Unit Bass(.pas) in der Uses-Klausel durch die Bass_Dynamic(.pas) zu ersetzen damit die Bass.Dll in das Programm mit eingebunden wird. Die MP3-Dateinamen müssen im Code angepasst werden (kein OpenDialog...) und sie sollten ungefähr gleichlang sein, weiterhin ist das Crossfade nur manuell. Will man nun Song1 automatisch zu Song2 blenden gibt es eine einfache Lösung im Forum von ![]() ![]() Leider konnte ich wegen Zeitmangel momentan kein besseres Demo schreiben, Sorry. |
Re: MP3 in Cache "zwischenspeichern"
Das Beispiel ist 1A!!
Und wenn man dies jetzt noch "benutzer/anfängerfreundlich" machen könnte, sprich in die Komponente integrieren, dass man 2 Tonspuren gleichzeitig spielen kann, dann wäre das absolut TOP! |
Re: MP3 in Cache "zwischenspeichern"
Ich weiß nicht, ob du inzwischen zu einem Ergebnis gekommen bist, jedoch habe ich vor kurzem mal eine Komponente erstellt, die Crossfading betreiben kann.
Ein Beispielproggi, das sämtliche Funktionen beschreibt, liegt bei... ![]() Die Komponente ist noch nicht komplett fertig. Zum Beispiel fehlt die Lautstärkeregelung. Diese Features dürften aber nicht allzu schwer zu implementieren sein. Falls verständnisschwierigkeiten aufkommen sollten, helfe ich natürlich gerne :) ![]() Zur weiteren Erklärung der Funktionsweise: Ich erstelle zwei Streams die parallel Laufen (hiervon kann man im Prinzip beliebig viele erstellen, wenn man "zuviel" Speicher hat :wink: ). Mit BASS_ChannelSetSync erstelle ich dann eine Callback Prozedur, die automatisch aufgerufen wird, sobald eine bestimmte Stelle im vorangegangenen Track erreicht wurde. Dann wird mit BASS_ChannelSlideAttributes das Fading initialisiert. Eigentlich ganz simpel :) |
Re: MP3 in Cache "zwischenspeichern"
Liste der Anhänge anzeigen (Anzahl: 1)
So,
hat einen Moment gedauert... ich habe jetzt alles überarbeitet und die Begrenzungen, die einem die BassDllPlayer-Komponente auferlegt hat beseitigt. Das Speicherleck der DllLoader-Unit konnte ich leider noch nicht stopfen! (aber das habt ihr ja bei der alten Komponente auch nicht gemerkt) Trotzdem, vielleicht findet ja irgendwer den Fehler bzw. kann ihn beheben. Das Problem ist das die vier erstellen Sections.Base-Elemente durch VirtualFree nicht freigegeben werden. Die Unit ist richtig programmiert (so weit ich das sehen konnte). Der Speicher wird freigegeben aber MemProof sagt mir, dass bei dieser Freigabe ein Fehler passiert ist. Ich habe keine Ahnung, was da los ist (eventuell liegt es an SP2) Naja, egal kommen wir jetzt zur Komponente... Jetzt kann man endlich die Bereichs- und Überlauf- Fehlerprüfungen eingeschaltet lassen. hurra! Es können jetzt unendlich viele Komponenten (BassDllPlayerEx) in einem Programm verwendet werden. Jeder Komponente wird dabei eine Soundkarte zugewiesen. Bei neueren Soundsystemen kann man auch einfach mehrere Komponenten der gleichen Soundkarte zuordnen. Dies ist aber nicht erforderlich, da in jeder Komponente jetzt unendlich viele Kanäle definiert werden können. (Um Probleme mit älteren Soundsystemen zu vermeiden sollte man nur eine Komponente pro Soundkarte einsetzen - das geht dann immer!) Ich habe mal ein kleines Beispiel angehängt. Es existiert keine Playlist mehr, sorry hatte ich jetzt keine Lust mehr drauf. Die Komponente muss nicht installiert werden, einfach entpacken, kompilieren und wohlfühlen... Das Programm testet fünf Soundkarten und legt für jede in einem PageControl eine Seite an. Wenn man nur eine Soundkarte hat, werden (in der IDE) vier Exceptions ausgelöst (also einfach weiterausführen). Wenn die Exe läuft bekommt man natürlich nichts davon mit. Ich breche die Schleife der Soundkarten nicht mit EXIT ab (weil: ich hasse exit, halt, break, goto). Auf jeder Soundkartenseite im PageControl können dann über die rechte Maustaste Kanäle hinzugefügt bzw. entfernt werden. Auf die Aufnahmemöglichkeiten der BassDllPlayer-Komponente bin ich nicht weiter eingegangen. Ich habe einfach die Vorgaben von der BassDllPlayer-Komponente übernommen. Ob das alles so funktioniert weiss ich nicht, mich interresierte nur das Abspielen - vielleicht kann das ja mal einer testen. Ich möchte mich hier ausdrücklich bei meinen Vorgängern (Gandalfus & turboPascal) bedanken. Eure Vorarbeit (im Besonderen das Einbetten der DLL in die EXE) hat mir sehr gefallen. Ich hoffe euch beiden (und natürlich jeden den es interessiert) gefallen meine Erweiterungen. Ich bin einfach konsequent den Weg weitergegangen, den Ihr beiden angefangen seit zugehen. Also nochmal danke für die Möglichkeit. MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
@omata
Ich finde es nicht so glücklch, die Bass dll mehrfach zu laden. Dafür gibt es doch die Möglichkeit innerhalb von Bass weitere Streams zu erzeugen. |
Re: MP3 in Cache "zwischenspeichern"
ja, schade dass du es nicht verstanden hast.
Man kann mit der Bass.dll nur eine Soundkarte ansprechen und auf dieser dann mehrere Channel miteinander mischen. Wenn man aber mehr als eine Soundkarte hat, dann braucht man für jede Soundkarte eine eigene Dll. Und dann muss man eben die Dll mehrfach (so oft wie Soundkarten vorhanden sind) laden. MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
Zitat:
|
Re: MP3 in Cache "zwischenspeichern"
@omata:
Das Demo ist ja einfach ein Wahnsinn!! *Respekt* |
Re: MP3 in Cache "zwischenspeichern"
Vielen Dank,
aber habe gerade eine unschöne Kleinigkeit entdeckt. Auf der Suche nach dem Speicherleck, habe ich testweise eine Zeile auskommentiert. Also, bitte das Kommentar löschen: Datei: DllLoaderEx - Zeile: 1011 dort steht zur Zeit:
Delphi-Quellcode:
bitte ändern in:
FOR I:=0 TO LENGTH(Sections)-1 DO BEGIN
IF ASSIGNED(Sections[I].Base) THEN BEGIN // VirtualFree(Sections[I].Base,0,MEM_RELEASE); END; END;
Delphi-Quellcode:
PS: Das löst leider nicht das Speicherleck!
FOR I:=0 TO LENGTH(Sections)-1 DO BEGIN
IF ASSIGNED(Sections[I].Base) THEN BEGIN VirtualFree(Sections[I].Base,0,MEM_RELEASE); END; END; Danke Thorsten |
Re: MP3 in Cache "zwischenspeichern"
So ich hab mir jetzt den Code einmal angesehen, und muss sagen dass dieser so umfangreich ist, dass ich eine kleine 'Starthilfe' benötige:
Kannst du vielleicht nochmal nur den Code posten (in der minimalsten Form) den ich jetzt brauche um: [X] den Player zu initialisieren [X] einen Channel anzulegen [X] diesen Channel abspielen der Rest sollte mir dann von selbst klar werden |
Re: MP3 in Cache "zwischenspeichern"
Gerne...
Komponente initialisieren: BassdllPlayerEx:=TBassdllPlayerEx.Create(Self); Kanel hinzufügen (Volume = 100): BassdllPlayerEx.addChannel(100); 1. Kanal mit Datei laden: BassdllPlayerEx.Channel[0].LoadFromFile(...); 1. Kanal abspielen: BassdllPlayerEx.Channel[0].Play; Komponente freigeben: BassdllPlayerEx.free; MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
Super danke
//edit: Fehlt jetzt die EQ Funktion? (soweit ich es finde, gibts es nur mehr UpdateEQ und RemoveEQ) |
Re: MP3 in Cache "zwischenspeichern"
Ja, sorry.
Verschiebe einfach in der BassChannelEx-Unit die Zeile:
Delphi-Quellcode:
vom Private-Teil in den Public-Teil, dann kannst du auch wieder auf InitEQ zugreifen
procedure InitEQ;
MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
geht schon, danke
|
Re: MP3 in Cache "zwischenspeichern"
Liste der Anhänge anzeigen (Anzahl: 1)
So,
habe jetzt noch für jeden Kanal einen eigenen Equiliser eingebaut. Jeder Equiliser kann wiederrum unendlich viele Bänder haben. Viel Spass... MfG Thorsten |
Re: MP3 in Cache "zwischenspeichern"
... :thumb:
|
Re: MP3 in Cache "zwischenspeichern"
Nochmal eine Frage zum Euqalizer:
Wie muss ich diesen jetzt deklarieren/initialisieren? bis jetzt habe ich:
Delphi-Quellcode:
Wenn ich jetzt jedoch wie in der Demo die verschiedenen Bänder zbsp mit:
var Equalizor:TBassEquiliserClass;
.. Equalizor:=Player.Channel[0].Equiliser.create; Equalizor.Start
Delphi-Quellcode:
setzen will, bekomme ich einen Fehler
Equalizor.SetIndexGain(0,3);
|
Re: MP3 in Cache "zwischenspeichern"
Moin,
der Equiliser wird automatisch initialisiert. Also mal wieder ein minimal Beispiel... initialisieren: BassdllPlayerEx:=TBassdllPlayerEx.Create(Self); Kanal hinzufügen: BassChannel:=BassdllPlayerEx.addChannel(100); Band hinzufügen: BassChannel.Equiliser.addBand(1000, 18, 0); => Frequenz: 1KHz, Bandbreite: 18Hz, Gain: 0db Equiliser starten: BassChannel.Equiliser.Start; Equiliser stoppen: BassChannel.Equiliser.Stop; Gain einer Bandfrequenz auf 1 ändern: BassChannel.Equiliser.SetFrequenzGain(1000, 1); Gain über den Bandindex auf 1 ändern: BassChannel.Equiliser.SetIndexGain(0, 1); freigeben: BassdllPlayerEx.free; Viel Spass Thorsten |
Re: MP3 in Cache "zwischenspeichern"
k danke.
Ich hab in deiner Demo keine Zeile gefunden, wo die verschiedenen Bänder angelegt werden, deswegen hab ich geglaubt diese werden automatisch gemacht. Jetzt funktionier aber alles bestens |
Re: MP3 in Cache "zwischenspeichern"
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
die Zeilen findest du in FrameSoundkarteU. So, ich habe mal wieder eine überarbeitete Fassung. Es gibt jetzt auch Ereignisse. Zwei Stück. Ein Zeit-Ereignis und ein Paint-Ereignis. Beide werden über jeweils einen eigenen Timer ausgelöst. Das Interval ist einstellbar, wird aber eigentlich auch schon richtig initalisiert. Die Hauptkomponente (BassdllPlayerEx), die eine Soundkarte anspricht enthält die beiden Timer. Also hat man nun zwei Timer pro Soundkarte (vorher waren es zwei pro Kanal!). Die Ereignisse der BassdllPlayerEx-Komponente werden als erstes ausgelöst. Jeder Kanal hat wiederrum seine eigenen Ereignisse, die nach den Hauptereignissen aufgerufen werden. Dieses Aufrufen kann man in den Hauptereignissen auch deaktivieren (über ChannelEvent). Zusätzlich habe ich noch die Zeitangaben überarbeitet. Über SongTimeInfo[] kann man nun die Länge, die Spielzeit und die verbleibende Zeit in Sekunden oder als String auslesen. Von turboPascal habe ich eine erweiterte Unit erhalten, die die BitmapBlur.pas ersetzt. Dadurch sind jetzt auch schönere Levelanzeigen möglich. Eventuell sollte dass auch nochmal eine Klasse werden, damit man das Aussehen manipulieren kann. Naja, mal sehen... Viel Spass... Thorsten |
Re: MP3 in Cache "zwischenspeichern"
@omata:
Ich hätte wiedermal einen Verbesserungsvorschlag: Wäre es irgendwie möglich, dass die Position genauer ausgelesen, und gesetzt werden kann? (nicht nur auf Sekunden-Genauigkeit sondern vielleich auf die Millisekunde genau) Das würde neue Funktionen möglich machen mfg. kurtm1 |
Re: MP3 in Cache "zwischenspeichern"
|
Re: MP3 in Cache "zwischenspeichern"
Super danke!!!
|
Re: MP3 in Cache "zwischenspeichern"
So ich habe jetzt schon mal viel gecodet, und bin dabei auf folgendes Problem gestoßen:
Angenommen ich habe 2 Kanäle (A/B), und möchte diese "synchronisieren", ich würde dies so ausführen: B.MilliSecPosition:=A.MilliSecPosition; B.Play Wenn ich dies jedoch so code, dann wird die Position vom Kanal 2 anscheinend nicht gesetzt, Kanal B beginnt immer ganz von vorne zu spielen. Lösungen? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz