Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2023-11

LclVLC usage questions for switching from PasLibVLC

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I created a video editing tool back in 2018 or so in order to help pinpointing cut points for editing mp4 videos.

At the time I did not find anything useful other than PasLibVLC, which I have been using since then on Windows. It works OK for what I need but I have to install the custom package into the IDE every time I make a new Lazarus installation. Until now I have only been on Windows with this application.

A few days ago I wanted to build the application on a Linux system, but even though it compiled after I removed some Windows-only experimental functions it did not actually display the video, nothing at all shows up....

So I have been looking around for a solution and yesterday I found what is right under my nose:

Lazarus contains LibVLC as a standard package available to be installed in the GUI using Package/Install-remove packages! No download needed from external sources!

Really very neat and simple to get going and to rely upon going forward!

Anyway, I have been experimenting with the example inside the package code and also read Michael's document "Displaying video files using Free Pascal and Lazarus".

I think I can switch out PasLibVLC and replace it with the LclVLC player instead but I need some help in implementation.

There are some functions I would like to get hints on how to implement:

1) Progressbar update
---------------------
It is decribed how to make a progressbar show the current position of the video playback. That is event driven AFAICT. And it is shown in the doc...

However, I don't understand what is going on in the pdf doc regarding getting the actual position shown by the position of the progressbar.

I have tried to get the info from the player like this, but it won't work at all, it looks like the DoPositionChanged() event code does not get called.. This is what I have done:

procedure TfrmMainVlc.FormCreate(Sender: TObject);
begin
  FPlayer:=TLCLVLCPlayer.Create(Self);
  FPlayer.ParentWindow:=PVideo;
  ; //Set event handler
  FVideoFile := ReadIniString('Files', 'LastVideo', ''); //Get last video name
  FEVideo.FileName := FVideoFile;
  tbVolume.Position := ReadIniInt('Settings', 'Volume', 10); //Get last volume
end;
procedure TfrmMainVlc.DoPositionChanged(Sender: TObject; const APos: Double);
var
  nCurrPos: int64;
begin
  //Just print the position to screen as first test
  nCurrPos := Round(APos); //Position in ms
  stxPos.Caption := IntToStr(nCurrPos); //Show position in StaticText box
end;

Nothing at all happens when I play the video, the event function is not called.

2) Reposition video via progressbar
-----------------------------------
I also need the reverse, i.e. when I click the progressbar I want the video to be repositioned to the place I clicked.
And this I have solved using this piece of code (note: I have set the progressbar max value to 1000 to get better resolution:

//Mouse up on progressbar should reposition the video to the clicked pos
procedure TfrmMainVlc.pgbVideoposMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  VidPos,
  Duration: int64;
begin
  Duration := FPlayer.VideoLength div 1000;
  VidPos := Round(X / pgbVideopos.Width * pgbVideopos.Max * Duration / 1000);
  FPlayer.VideoPosition := Round(VidPos * 1000);
end;

3) Increase/decrease playback speed?
------------------------------------
Is it possible to adjust the playback speed (I can do this with PasLibVLC)? Then how can it be done, say to enter a percentage between 50 and 200 in a box and then tell the player to use that setting.

4) Lipsync adjust
-----------------
Is it possible to shift the audio forward/backward relative to the image in order to adjust lip sync? I can do this with PasLibVLC, but how can it be done here?

Grateful for any suggestions on how to get this to work!

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 9 lines
procedure TfrmMainVlc.FormCreate(Sender: TObject); begin FPlayer:=TLCLVLCPlayer.Create(Self); FPlayer.ParentWindow:=PVideo; ; //Set event handler FVideoFile := ReadIniString('Files', 'LastVideo', ''); //Get last video name FEVideo.FileName := FVideoFile; tbVolume.Position := ReadIniInt('Settings', 'Volume', 10); //Get last volume end;

Sorry, in actual fact I have this in the FormCreate:

procedure TfrmMainVlc.FormCreate(Sender: TObject);
begin
  FPlayer:=TLCLVLCPlayer.Create(Self);
  FPlayer.ParentWindow:=PVideo;
  ;
  FVideoFile := ReadIniString('Files', 'LastVideo', '');
  FEVideo.FileName := FVideoFile;
  tbVolume.Position := ReadIniInt('Settings', 'Volume', 10);
  FPlayer.UseEvents:=True; // Enable events
end;

The last line was added *after* I copied the function to the list message....

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund: I created a video editing tool back in 2018 or so in order to help pinpointing cut points…
Bo Berglund wrote 15 lines
Lazarus contains LibVLC as a standard package available to be installed in the GUI using Package/Install-remove packages! No download needed from external sources! Anyway, I have been experimenting with the example inside the package code and also read Michael's document "Displaying video files using Free Pascal and Lazarus". I think I can switch out PasLibVLC and replace it with the LclVLC player instead but I need some help in implementation. There are some functions I would like to get hints on how to implement: 1) Progressbar update ---------------------

THIS IS NOW SOLVED!
--------------------
I added a TThread.Create... statement as I found in the document, without really understanding how it can help. Seems to me like creating a thread that immediately exits. What can that do?
And I also added an FPlayer.UseEvents statement.
This is how it now looks and it does allow the events to fire...

procedure TfrmMainVlc.FormCreate(Sender: TObject);
begin
  With TThread.Create(False) do Terminate; //Initialize the treading system??
  FPlayer:=TLCLVLCPlayer.Create(Self);
  FPlayer.ParentWindow:=PVideo;
  ;
  FVideoFile := ReadIniString('Files', 'LastVideo', '');
  FEVideo.FileName := FVideoFile;
  FEVideo.InitialDir := ExtractFileDir(FVideoFile);
  tbVolume.Position := ReadIniInt('Settings', 'Volume', 10);
  FPlayer.UseEvents:=True;
end;

The next item is the handling of the progress bar: It now looks like this and works:

procedure TfrmMainVlc.DoPositionChanged(Sender: TObject; const APos: Double);
var
  VPos: integer;
begin
  VPos := Round(APos * pgbVideopos.Max);
  pgbVideopos.Position := VPos;
end;
2) Reposition video via progressbar -----------------------------------

This is also now working as follows:

//Mouse up on progressbar should reposition the video to the clicked pos
procedure TfrmMainVlc.pgbVideoposMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  VidPos: int64;
  Duration: int64;
begin
  Duration := FPlayer.VideoLength div 1000;
  VidPos := Round(X / pgbVideopos.Width * pgbVideopos.Max * Duration);
  FPlayer.VideoPosition := VidPos;
end;

However the progressbar does not immediately reposition to the clicked position, instead it takes a second or so while it moves stepwise across.

How can I make that instantaneous?

Show quoted text 6 lines
3) Increase/decrease playback speed? ------------------------------------ Is it possible to adjust the playback speed (I can do this with PasLibVLC)? Then how can it be done, say to enter a percentage between 50 and 200 in a box and then tell the player to use that setting.

In the original code using PasLibVLC it is done like this:

procedure TfrmMain.btnFFClick(Sender: TObject);
begin
  vlcPlayer.SetPlayRate(speSpeed.Value);
end;
And here the progressbar position is immediately changed to the target position
below the mous pointer.
Show quoted text 5 lines
4) Lipsync adjust ----------------- Is it possible to shift the audio forward/backward relative to the image in order to adjust lip sync? I can do this with PasLibVLC, but how can it be done here?

In the original code again it works and is done like shown below where the spinedit speAudio contains a value in milliseconds but the command expects microseconds, hence the multiplication by 1000:

//For testing purposes, delay audio by the value from speAudio
procedure TfrmMain.btnShiftAudioClick(Sender: TObject);
var
  SyncCmd: string;
begin
  vlcPlayer.SetAudioDelay(speAudio.Value *1000); //Convert to us
  SyncCmd := FormatAudioSyncCmd(-1 * speAudio.Value, FVideoFile);
  Clipboard.AsText := SyncCmd; //Ffmpeg command to modify file if needed
end;

Here I put the SyncCmd on the clipboard so it can be pasted into an SSH command window for ffmpeg to modify the video file itself if needed. This file modification is done after checking the effect inside the video player first, in the player whatever shift is applied is immediately there to check...

Items 3 & 4 are still unsolved, how can it be done?

Still hoping for suggestions on how to get this to work!

Bo Berglund Developer in Sweden

Reply by email

Sven Barth
to Bo Berglund

Bo Berglund via lazarus schrieb am Mo., 20.
Nov. 2023, 15:09:

Show quoted text 29 lines
On Sun, 19 Nov 2023 14:50:34 +0100, Bo Berglund via lazarus wrote: >Lazarus contains LibVLC as a standard package available to be installed in the >GUI using Package/Install-remove packages! No download needed from external >sources! >Anyway, I have been experimenting with the example inside the package code and >also read Michael's document "Displaying video files using Free Pascal and >Lazarus". > >I think I can switch out PasLibVLC and replace it with the LclVLC player instead >but I need some help in implementation. > >There are some functions I would like to get hints on how to implement: > >1) Progressbar update >--------------------- THIS IS NOW SOLVED! -------------------- I added a TThread.Create... statement as I found in the document, without really understanding how it can help. Seems to me like creating a thread that immediately exits. What can that do?

It ensures that the RTL is multi threading aware, cause as long as no Pascal thread is started (which is the case for many programs) some shortcuts are taken by not using locks and such. However if you use an external library that starts non-Pascal threads that then call into the Pascal code things might go wrong due to this. Thus creating an empty thread will ensure that all locks are properly in place.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20231120/6d27807b/attachment.htm>

Reply by email