Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

1

17.07.2016, 20:51

Dauer einer Mp3 Datei ermitteln

Hallo,
ich bastel mir momentan ein Programm, mit dem man ein Mp3 Lied abspielen kann, damit es in Sprachchats übertragen wird, quasi wie ein Musikbot. Dieses Programm soll aber nur kleinere Ausgaben machen, die man per Hotkey auslöst. Damit sind also keine Lieder gemeint, sondern eher eine kleine Musik, die man anstoßen kann, wenn man z.B. beim zocken etwas erreicht hat. Das Ganze funktioniert über

C#-Quelltext

1
2
[DllImport("winmm.dll")]
private static extern long mciSendString(string strCommand, StringBuilder strReturn, int iReturnLength, IntPtr hwndCallback);


Nun möchte ich mir noch eine Progessbar hinsetzen, bin aber auf der Suche nach einer Möglichkeit, die Dauer des Liedes zu ermitteln. Im Internet gibt es viele Möglichkeiten, die meisten liefern aber nur die Größe und nicht die Dauer des Liedes, oder benutzen den Windows Media Player als Komponente.

Abgespielt wird die Datei einfach über diesen Aufruf,

C#-Quelltext

1
2
3
4
5
public void Play()
        {
            string command = "play MediaFile";
            mciSendString(command, null, 0, IntPtr.Zero);
        }


dort wird auch der Timer angestoßen. Festlegen möchte ich die Tickintervalle dann einfach über die Dauer des Liedes / 100.

Weiß jemand, ob man mit dieser DLL die Dauer des Liedes herausbekommen kann?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

17.07.2016, 20:59

Hier findest du C++-Code, den du nach C# portieren können solltest. Mir ist keine direkte Möglichkeit bekannt, die ohne externe Bibliotheken auskommt.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

3

17.07.2016, 21:07

Nachtrag:
Vielleicht geht es doch mit MCI. Schau dir mal den status-Befehl an, dort gibt es eine length-Option: https://msdn.microsoft.com/de-de/library…p/dd798683.aspx. Du musst dann den zweiten Parameter von mciSendString benutzen, dort schreibt die Funktion ihr Ergebnis rein (in deinem Fall hoffentlich die Länge des geladenen Sounds).

Zitat

length: Returns the total length of the media, in the current time format. For PPQN files, the length is returned in song pointer units. For SMPTE files, it is returned as hh:mm:ss:ff, where hh is hours, mm is minutes, ss is seconds, and ff is frames. For VCR devices, the length is 2 hours (unless the length has been explicitly changed using the set command).

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

4

17.07.2016, 21:50

Erstmal vielen Dank für die Links,

mit dem Aufruf

C#-Quelltext

1
2
3
4
5
6
7
8
9
 public int Duration
        {
            get
            {
                StringBuilder builder = new StringBuilder(128);
                mciSendString("status mediafile length", builder, 128, IntPtr.Zero);
                return Convert.ToInt32(builder.ToString());
            }
        }


komme ich gut an die Dateilänge ran. Leider kommt es natürlich zu Rundungsfehlern beim Umwandeln. Ich könnte das Format auch auf Ulong lassen, kann dann aber bei

C#-Quelltext

1
ticker.Interval = datei.Duration / 100;


logischerweise nicht mehr durch 100 teilen. Hast du dafür noch eine tolle Idee? :P

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

17.07.2016, 22:26

Du solltest mit set mediafile timeformat milliseconds das Zeitformat auf Millisekunden setzen. Den Rest solltest du allein hinkriegen. ;)

PS: All diese Infos habe ich mit Google gefunden. Ich habe überhaupt keine Ahnung von MCI. *Wink mit dem Zaunpfahl*

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

6

17.07.2016, 22:44

Zu meiner Verteidigung muss ich aber sagen, dass ich mit meinem wenigen Wissen auch die Suchbegriffe allgemein gehalten habe, wie zB "C# get mp3 duration" :p

Aber ja du hast Recht, hätte ich wohl finden müssen/können ..

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

18.07.2016, 08:59

Die moderne Lösung wäre wohl MMF.

Hier findest du ein vollständiges Tutorial zum Einlesen von Audiodaten über die Microsoft Media Foundation. Insbesondere folgender Teil dürfte interessieren: https://msdn.microsoft.com/en-us/library…g_file_duration

Garzec

Alter Hase

  • »Garzec« ist der Autor dieses Themas

Beiträge: 693

Wohnort: Gießen

  • Private Nachricht senden

8

18.07.2016, 09:32

Ich weiß ja nicht wie "veraltet" die Nutzung von der winmm.dll ist, aber es funktioniert noch einwandfrei, mein einziges Problem ist halt die Zeitberechnung ;D Mithilfe von Davids Links bin ich zumindest so weit:

C#-Quelltext

1
2
3
4
5
6
7
8
public long Duration
        {
            get
            {
                long dauer = mciSendString("set MediaFile time format milliseconds", null, 0, IntPtr.Zero);
                return dauer;
            }
        }


Ich habe einen Testsound von 12 Sekunden. Zurückgeliefert wird die Zahl 1125981511221248. Ich kann mir nicht vorstellen, dass dies die richtige Zeit in Millisekunden ist :crazy:




Kleiner Nachtrag: Mit

C#-Quelltext

1
2
3
4
5
6
7
8
9
public ulong Duration
        {
            get
            {
                StringBuilder builder = new StringBuilder(128);
                mciSendString("status mediafile length", builder, 128, IntPtr.Zero);
                return Convert.ToUInt64(builder.ToString()) / 1000;
            }
        }


wird die richtige Zeit zurückgeliefert.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Garzec« (18.07.2016, 09:42)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

18.07.2016, 10:34

Mit set time format setzt du ja auch nur das Zeitformat. Da kriegst du nix zurück. Das wirkt sich darauf aus, in welchem Format du später mit status length die Länge zurückkriegst. Du musst also beides machen.

Werbeanzeige