Hello,
I have to make an MP3 player that can work on 3 different ways.
- You click, it plays, you click again, it pauses
- You hold down the mouse, it plays, you release the mouse, it pauses
- A timer, you can set up a timer to pause it up to 60 seconds, with a scrollbar or something appearing to select a amount of seconds to play until it pauses.
I figured I can do the playing options in a groupbox but I have no idea how to do any of this.
Also, I'm not supposed to use a button to play and pause, I have to do this all by clicking the form itself. But I have no idea how to do all of this.
Also, when the form starts it has to open a map in which you can select MP3's, but I can't get this to work either. If someone can help me, you have my eternal gratitude.

Edited 1 Year Ago by Michaël: Forgot something

Take a look in the Object Inspector at the events for the form. It has OnClick, OnMouseDown, OnMouseUp events that you can use to start/pause/stop the play. The Shift parameter to the OnMouseDown and OnMouseUp event handlers tells you which mouse button was pressed so you could use the left button to start, the right button to pause or whatever.

Thanks for the help, but there is one thing left that won't work

procedure TForm1.cmbAfspeelManierenChange(Sender: TObject);
begin
if cmbAfspeelManieren.text = 'Klikken en spelen' Then
begin
Form1.Click := MP1.Play;
PB1.Min := 0;
PB1.Max := MP1.Length;
Timer1.Enabled := true;
Form1.Click := MP1.Pause;
end;
end;

Can anyone tell me what's wrong with this? Also, do I have to put the pause somewhere else?

I see you have made some progress. Good.

The line Form1.Click := MP1.Play; has 2 errors:

a) It should be Form1.onClick because you want to specify the event handler, not actually click the form.

b) Form1.onClick is a TNotify event which is defined as:

    procedure(Sender: TObject) of object;

A procedure that matches this definition would look like:

    procedure TSomeObject.SomeMethod(Sender : TObject);

MP1.Play is defined as:
   `procedure TMediaPlayer.Play;`
As you can see it has no Sender parameter so doesn't
match the required definition.

What you need to do is define your own method which
does match the definition and call MP1.Play from there.
Something like:

In the form definition:


      TForm1 = class(TForm)
      private
        procedure StartPlay(Sender : TObject);


Then in the implementation section implement this as:


        procedure TForm1.StartPlay(Sender: TObject);
        begin
          MP1.Play;
        end;

You then assign your StartPlay method as the event handler for the form's onClick event, like this: `Form1.onClick := StartPlay`

The line Form2.Click := MP1.Pause; has the same errors.
You can resolve them in a similar way.

Ok so, it keeps giving the same error at the procedure TMediaPlayer.Play;
"Expected '=' but ';' found." same with .Pause, any idea how to fix this?

type
  TForm1 = class(TForm)
    Image1: TImage;
    MP1: TMediaPlayer;
    XPManifest1: TXPManifest;
    OD1: TOpenDialog;
    Timer1: TTimer;
    Image2: TImage;
    PB1: TProgressBar;
    procedure FormCreate(Sender: TObject);
    procedure Image1Click(Sender: TObject);
    procedure Image2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormClick(Sender: TObject);
    procedure TMediaPlayer.Play;
    procedure TMediaPlayer.Pause;


  private
    procedure StartPlay(Sender : TObject);
    procedure PausePlay(Sender : TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.StartPlay(Sender: TObject);
begin
MP1.Play;
end;

procedure TForm1.PausePlay(Sender: TObject);
begin
MP1.Pause;
end;


procedure TForm1.FormClick(Sender: TObject);
begin
Form1.OnClick := StartPlay;
PB1.Min := 0;
PB1.Max := MP1.Length;
Timer1.Enabled := true;
if StartPlay = true then
Form1.OnClick := PausePlay;
PB1.Min := 0;
PB1.Max := MP1.Length;
Timer1.Enabled := false;

Also, is the playing and pausing with same form.Onclick done correctly?

can do a boolean for play and stop maybe alot more useful and hander for later on detection if you want to see if the player is playing.

private
   IsPlaying: Boolean;

procedure TMPForm.FormCreate(Sender: TObject);
begin
  IsPlaying := False;
end;

procedure TMPForm.FormClick(Sender: TObject);
begin
  if IsPlaying then StopMedia else PlayMedia;
end;

procedure TMPForm.PlayMedia;
begin
  MP1.Play;
  IsPlaying := True;
end;

procedure TMPForm.StopMedia;
begin
  MP1.Stop;
  IsPlaying := False;
end;

Simon, that is a nice and simple approach, better in many ways than changing the event handler. I should have seen that but I focused too much on Michaël's syntax errors rather than his logic. Good catch anyway.

One trivial issue with this code is that the TMediaPlayer already keeps track of what it is doing so you could check MP1.Mode and eliminate the isPlaying variable.

The next tricky issue is the requirement to hold down the mouse to play and release it to pause. The problem here is how to distinguish between a press/hold/release sequence and a click. Taking the view that "holding down" implies some time period longer than a click, I would add a timer and set its interval to, say, 500 and its enabled property false. Add an onMouseDown event handler to enable the timer and in the timer event start the play. In the PlayMedia method disable the timer. The code would be simple:

// New method
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  if not isPlaying then
    HoldDownTimer.Enabled := TRUE;
end;

// New method
procedure TForm1.HoldDownTimerTimer(Sender: TObject);
begin
  PlayMedia;
end;

procedure TForm1.PlayMedia;
begin
  HoldDownTimer.Enabled := FALSE;    <<<=== New line
  MP1.Play;
  IsPlaying := True;
end;

Michaël, if you use this approach to the hold/release requirement, make sure you understand why this code handles mouse down events to start the play but doesn't need to handle mouse up events to pause.

This article has been dead for over six months. Start a new discussion instead.