2017-10-09 4 views
1

J'ai besoin d'intégrer un lecteur MP3 trivial dans une application Delphi7. Je vais simplement scanner un répertoire et lire tous les fichiers dans un ordre aléatoire.La notification Delphi MediaPlayer sur la chanson s'est arrêtée

J'ai trouvé deux solutions possibles: l'une utilisant Delphi MediaPlayer et l'autre utilisant l'API PlaySound Windows.

Aucun ne fonctionne.

Le problème semble être dans la notification "stop" manquante. En utilisant PlaySound comme ceci:

playsound(pchar(mp3[r].name), 0, SND_ASYNC or SND_FILENAME); 

Je ne pouvais pas trouver un moyen de (poliment) demander à Windows pour me dire quand une chanson a cessé de jouer.

Utilisation du Delphi MediaPlayer, Internet est plein de suggestions copier/coller l'un de l'autre, comme ici:

http://www.swissdelphicenter.ch/en/showcode.php?id=689

http://delphi.cjcsoft.net/viewthread.php?tid=44448

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    MediaPlayer1.Notify := True; 
    MediaPlayer1.OnNotify := NotifyProc; 
end; 

procedure TForm1.NotifyProc(Sender: TObject); 
begin 
    with Sender as TMediaPlayer do 
    begin 
    case Mode of 
     mpStopped: {do something here}; 
    end; 
    //must set to true to enable next-time notification 
    Notify := True; 
    end; 
end; 
{ 
    NOTE that the Notify property resets back to False when a 
    notify event is triggered, so inorder for you to recieve 
    further notify events, you have to set it back to True as in the code. 
    for the MODES available, see the helpfile for MediaPlayer.Mode; 
} 

Mon problème est que je reçois un NotifyValue == nvSuccessfull quand une chanson est terminée mais aussi quand je commence une chanson, donc je ne peux pas compter dessus. En outre, je ne reçois jamais, jamais un changement d'état de la propriété "mode", qui devrait devenir mpStopped en fonction de tous les exemples que j'ai trouvés.

Il y a une question similaire ici

How can I repeat a song?

mais cela ne fonctionne pas parce que, comme dit, je reçois le nvSuccessfull deux fois, sans un moyen de distinguer entre le début et l'arrêt.

Last but not least, cette application devrait fonctionner de XP à Win10, c'est pourquoi je développe avec Delphi7 sur WinXP.

Merci et désolé pour la longueur de ce post, mais j'ai vraiment essayé de nombreuses solutions avant de demander de l'aide.

+0

Le plus simple pourrait être 'mciSendString'. Vous créez une fenêtre invisible (par AllocateHWnd) et _listen_ pour le message MM_MCINOTIFY. – Victoria

+0

Merci. En général, programmer directement avec Windows API n'est pas mon truc "pain et beurre", mais en lisant le MM_MCINOTIFY sur MSDN, on dirait que c'est ce que Delphi mappe sur la propriété "NotifyValue", donc j'aurais besoin de plus d'aide pour distinguer entre les deux :) – ZioBit

+0

@Victoria - semble une solution intéressante - mais si vous n'utilisez que l'API et ne vous fiez pas à la VCL, ne pourriez-vous pas simplement utiliser un thread? J'ai eu le même problème (application différente mais même problème). Les versions originales des fenêtres (et je parle ici d'XP) étaient solides en mode notification. Les derniers ne l'étaient pas. Donc, je suis curieux de connaître une bonne solution aussi. – Dsm

Répondre

2

Pour détecter le moment de charger un nouveau fichier pour la lecture, vous pouvez utiliser l'événement OnNotify et les EndPos et Position propriétés du TMediaPlayer (ci-après MP)

de configuration d'abord le MP et sélectionnez un TimeFormat, par exemple

MediaPlayer1.Wait := False; 
MediaPlayer1.Notify := True; 
MediaPlayer1.TimeFormat := tfFrames; 
MediaPlayer1.OnNotify := NotifyProc; 

Lorsque vous chargez un fichier pour la lecture, définissez la propriété EndPos

MediaPlayer1.FileName := OpenDialog1.Files[NextMedia]; 
MediaPlayer1.Open; 
MediaPlayer1.EndPos := MediaPlayer1.Length; 
MediaPlayer1.Play; 

Et la procédure OnNotify()

procedure TForm1.NotifyProc(Sender: TObject); 
var 
    mp: TMediaPlayer; 
begin 
    mp:= Sender as TMediaPlayer; 

    if not (mp.NotifyValue = TMPNotifyValues.nvSuccessful) then Exit; 

    if mp.Position >= mp.EndPos then 
    begin 
    // Select next file to play 
    NextMedia := (NextMedia + 1) mod OpenDialog1.Files.Count; 
    mp.FileName := OpenDialog1.Files[NextMedia]; 
    mp.Open; 
    mp.EndPos := mp.Length; 
    mp.Position := 0; 
    mp.Play; 
    // Set Notify, important 
    mp.Notify := True; 
    end; 
end; 

Enfin un commentaire à votre tentative d'utiliser le mode MP.Mode = mpStopped pour changer une nouvelle chanson. Le mode est modifié lorsque les touches sont utilisées, par exemple mpStopped lorsque l'utilisateur appuie sur le bouton Stop.Changer la chanson et commencer à la jouer ne serait probablement pas ce que l'utilisateur attendait.

+0

Merci pour la solution (que j'essaierai comme dans 24h) et l'explication du comportement de mpStopped, je n'étais pas au courant de cela. En fait, je n'utilise pas l'interface utilisateur, je garde le contrôle caché, c'était juste un moyen simple de lire des fichiers mp3. – ZioBit

+0

Ça marche, merci! – ZioBit