In TTMSFNCWXAudioPlayer, the IsPlaying property does not reflect the actual playback state — it only updates through OnPlay/OnPause, and doesn’t handle manual stops or interruptions.
This issue is clearly visible even in the official demo you provide.
If there's a quick workaround, I’d appreciate receiving it without waiting for the next update.
While the property is indeed set before calling OnPlay and OnPause, these events are tied to the underlying HTML <audio> element's play and pause events. We don't see any issues happening with the demo, if the play button is clicked in the control itself, the TButton equivalent also updates accordingly and vice versa. Is that not what you are seeing? Can you please clarify what goes wrong in your case?
Thank you for your reply.
As a matter of fact, my issue arises when I trigger the Play procedure of TTMSFNCWXAudioPlayer programmatically.
I noticed that the IsPlaying property is not updated immediately afterward.
This is problematic for me because I would like to implement my own logic to allow the component to play until it resumes (in an asynchronous way).
Moreover, I sometimes need to read the value of IsPlaying right after calling TMSFNCWXAudioPlayer.Play.
Indeed, the demo works well.
I would be delighted to receive assistance in resolving this issue.
I also appreciate highly the immense effort Fnc team is doing for delphi developers!!
Here my code. It seems that AudioPlayer2.IsPlaying is not reflecting the good value
if WaitUntilDone then
begin
i := 0;
while AudioPlayer2.IsPlaying and (i < 120000) do
begin
Sleep(100);
Application.ProcessMessages;
Inc(i, 100);
end;
end;
Yes. I realy appreciate your immediate response.
The demo works very fine. But in my case I wanted to let the component play the media via code I modified a little the code in the demo to fit my need:
procedure TForm2.playBtnClick(Sender: TObject);
var st:String;
begin
TMSFNCWXAudioPlayer1.Play;
if TMSFNCWXAudioPlayer1.IsPlaying then
Self.Caption:='IsPlaying'
else
Self.Caption:='Is not Playing';
end;
It seems that as long as iam still inside the body of the event, i got caption= 'Is not Playing';
Although the audio is launched!!!
It seems I should do something after the execution of the line TMSFNCWXAudioPlayer1,
to let the Isplaying property have true value...
Any idea?
As the onplay and onpause events are asynchronous, the IsPlaying property won't be updated immediately after calling Play.
There is no straightforward solution here unfortunately:
Hardcoding the IsPlaying property would report an incorrect value if something goes wrong with playing the audio
It also seems the onplay is triggered before the onerror, meaning you can't really use a thread to wait for a response from the audio player first, because the initial response reports it is playing.
This is something we'll need to give more thought first.
Can you explain this more in detail to see if there's a way around this instead of waiting for the IsPlaying to update immediately?
Let me put it very simply.
I noticed that the TFncWxAudioPlayer.Play procedure plays audio asynchronously—it does not block the execution of the next lines in my code.
But what if I want it to run in blocking mode (i.e., start playing, then pause the code execution until the playback finishes)?
I was a bit frustrated to find that such a feature is not supported by the component—something we used to have with the old MediaPlayer in Delphi or even with the PlaySound function provided by the system.
I tried to implement this behavior myself, but without success, because the IsPlaying property is not updated immediately after calling TFncWxAudioPlayer.Play.
Here is the code I attempted:
pascal
CopyEdit
procedure TMyAudioPlayer.PlayAudio(AUrl: String; WaitUntilDone: Boolean);
var
i: Integer;
begin
AudioPlayer2.URL := AUrl;
AudioPlayer2.Play;
if WaitUntilDone then
begin
i := 0;
while AudioPlayer2.IsPlaying and (i < 120000) do
begin
Sleep(100);
Application.ProcessMessages;
Inc(i, 100);
end;
end;
end;
Again, we are surfacing what the web APIs offer. The web API is asynchronous, there is in web API not a blocking mode to play audio. You could treat the audio as playing before you call the Play method and you could use the ended event that signals when the audio is finished to determine if the audio is playing.
As Bruno said, you'll have to rely on the OnEnded and OnError events one way or another. If using them as-is is not what you are looking for, the only other option you have is to utilize a thread that can be blocked until the OnEnded/OnError is triggered.
procedure TForm1.Button1Click(Sender: TObject);
begin
TTask.Run(procedure
begin
FEvent.ResetEvent;
TThread.Synchronize(nil, procedure
begin
TMSFNCWXAudioPlayer1.URL := 'https://download.samplelib.com/mp3/sample-3s.mp3';
TMSFNCWXAudioPlayer1.Play;
end);
if FEvent.WaitFor = wrSignaled then
Label1.Text := 'finished';
end);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FEvent := TEvent.Create;
end;
procedure TForm1.TMSFNCWXAudioPlayer1Ended(Sender: TObject);
begin
FEvent.SetEvent;
end;
procedure TForm1.TMSFNCWXAudioPlayer1Error(Sender: TObject;
Error: TTMSFNCWXMediaPlayerMediaError);
begin
FEvent.SetEvent;
end;