Lazarus
Programming => Widgetset => Carbon => Topic started by: Hansaplast on July 14, 2012, 06:51:24 am
-
I have developed a small app that utilize the libvlc.dll for Windows in Delphi, now that I've been playing with MacOS more and more, I would love to recompile my apps for the MacOS platform.
If I see things correctly, this should be possible since libvlc is available under MacOS as wel, but I'm completely unclear about the use of dylib files.
The lib can be found here on a Mac that has VLC installed (second one is linked to the first one):
/Applications/VLC.app/Contents/MacOS/lib/libvlc.5.dylib
/Applications/VLC.app/Contents/MacOS/lib/libvlc.dylib
I looked at paslibvlc (http://sourceforge.net/projects/paslibvlc/), which I used under Delphi.
They did add support for Linux, but nothing yet for MacOS.
I did some dabbling myself in the paslibvlc code but keep getting "Access Violation" (not running the IDE) or "EXC_BAD_ACCESS" (running IDE) suggesting that accessing the library is not working.
My modifications:
Line 4067 (latest version - file attached with this post)
uses
{$IFDEF UNIX}
Unix, dynlibs,
{$ENDIF}
{$IFDEF MSWINDOWS}
Windows, Registry,
{$ENDIF}
SysUtils, Classes;
const
{$IFDEF WIN32}
libvlc_name = 'libvlc.dll';
{$ELSE}
{$IFDEF DARWIN}
libvlc_name = 'libvlc.5.dylib';
{$ELSE}
libvlc_name = 'libvlc.so';
{$ENDIF}
{$ENDIF}
var
libvlc_handle : THandle;
function libvlc_get_install_path() : string;
{$IFDEF WIN32}
var
r : TRegistry;
begin
Result := '';
r := TRegistry.Create(KEY_READ);
try
r.RootKey := HKEY_LOCAL_MACHINE;
if r.OpenKey('Software\VideoLAN\VLC', FALSE) then
begin
if r.ValueExists('InstallDir') then
Result := r.ReadString('InstallDir');
end;
finally
r.Free;
end;
end;
{$ELSE}
{$IFDEF DARWIN}
begin
// Assumes VLC to be installed in the standard location
Result := '/Applications/VLC.app/Contents/MacOS/lib';
end;
{$ELSE}
begin
// Linux searches a library in the paths of the environment variable
// LD_LIBRARY_PATH, then in /lib, then /usr/lib and finally the paths of
// /etc/ld.so.conf.
Result := '';
end;
{$ENDIF}
{$ENDIF}
Any help would be greatly appreciated.
p.s. wouldn't VLC be an ideal candidate for a "universal" mediaplayer component for Lazarus?
-
And your code using the unit (i.e. a test program)?
p.s. wouldn't VLC be an ideal candidate for a "universal" mediaplayer component for Lazarus?
Perhaps, the license AFAIK has changed to LGPL which is good for most people.
-
I create (based on the demo app) a very straight forward test program; standard program, add button, drop PasLibVLCPlayer on it, on button click call "PasLibVlcPlayer1.Play('/Volumes/2ndSSD/Lazarus/VLCtest/WoodChucks.mp4');" (the video file exists)
Note; I used the lpk from the Lazarus component they offered.
The pas file linking to the library is the file in my previous post, since there was no linking to the dylib on the Mac.
After failing, I also (as this appears a common trick under Windows) copied the files from "/Applications/VLC.app/Contents/MacOS/" into my application/code directory, but that didn't make a difference.
When dropping PasLibVLCPlayer on my form it does "create" an area prepared for video playback.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, PasLibVlcPlayerUnit;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
PasLibVlcPlayer1: TPasLibVlcPlayer;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
PasLibVlcPlayer1.Play('/Volumes/2ndSSD/Lazarus/VLCtest/WoodChucks.mp4');
end;
{$R *.lfm}
end.
-
In libvlc_dynamic_dll_init_with_path:
{$IFDEF SUPPORTS_UNICODE}
libvlc_handle := LoadLibrary(PWideChar(libvlc_dynamic_dll_path + '\' + libvlc_name));
{$ELSE}
libvlc_handle := LoadLibrary(PAnsiChar(libvlc_dynamic_dll_path + '\' + libvlc_name));
{$ENDIF}
Try replacing libvlc_dynamic_dll_path + '\' with:
IncludeTrailingPathDelimiter(libvlc_dynamic_dll_path)
or
AppendPathDelim(libvlc_dynamic_dll_path)
The 2nd one requires FileUtil to be present in the uses clause.
-
Thank you Leledumbo for the quick response - I'm not home right now, but I'll give it a try when I get home later this week. :)
-
Thanks for the tips Leldumbo; I didn't know about the IncludeTrailingPathDelimiter() function :)
Your suggestions did improve the code, but I'm still getting the "Project project1.app raised exception class 'EXC_BAD_CCESS'" though. Building the file path works, the function "FileExists()" confirms this when debugging.
The function "LoadLibrary" keeps returning a 0 handle :(
For some reason the Library does not load ... (I'm using "/Applications/VLC.app/Contents/MacOS/lib/libvlc.5.dylib")
I fails loading the library as well when I use a local copy (in my project directory - including all plugins etc).
My knowledge about dylib libraries is close to zero, I have worked with DLL's before under Windows.
Does 32 bit vs 64 bit make a difference?
-
OK, it's a 32- vs 64-bit issue.
I downloaded VLC 32 bit, copied into my project directory and pointed to the proper dylib, and .... sounds works ... no video though :(
So I guess I'm looking at some 32/64 bit issues here (running MacOS X 10.7.4).
The 32 bit VLC client [running as a standalone app - the VLC app you'd download from VideoLan.org] appears to work just fine in a 64 bit environment ...
Anyone having insight in this?
-
Functions like GetVideoHeight, GetVideowidth, GetVideoLenStr all return correct values ...
-
How can i get this to work on Windows x64, i get only AV, even with the supplied exe from demo folder. I am using VLC 2.0.2.
Please provide an working example or rewuired version of dlls.
Thank you.
-
I have developed a small app that utilize the libvlc.dll for Windows in Delphi, now that I've been playing with MacOS more and more, I would love to recompile my apps for the MacOS platform.
...
p.s. wouldn't VLC be an ideal candidate for a "universal" mediaplayer component for Lazarus?
If you guys get a working cross-platform example, it would make sense to add that as an example to the Lazarus source directory itself or perhaps to Lazarus CCR..
Edit: had a look at the license for the pasvlc unit: it's GPL. Seeing as Lazarus is LGPL (with GPL for the IDE), I'd think this isn't a good fit for inclusion in Lazarus itself, but it could be added to Lazarus CCR, documented on the wiki etc.
Also, perhaps I'm wrong and perhaps there are GPL licensed examples in the Lazarus dir.
In any case, looking at the change history for the units on sourceforge, it seems like the developer is quite receptive to modifications, so when the OSX adaptations mentioned in this thread work, I'd strongly suggest submitting them to the author so he can update the original version... which will make it easier and less confusing for users to find it.
Sorry I haven't added anything to the topic of improving the code, and sorry if you already are aware of the above, but I added it in case you weren't... better safe than sorry ;)
-
Edit: had a look at the license for the pasvlc unit: it's GPL.
Oh, my... I didn't notice that :o
I only looked at libvlc license itself, which is LGPL and I think the Pascal wrapper would be the same, which is unfortunately not. Perhaps somebody wants to contact the author to allow LGPL?
-
OK, it's a 32- vs 64-bit issue.
I downloaded VLC 32 bit, copied into my project directory and pointed to the proper dylib, and .... sounds works ... no video though
So I guess I'm looking at some 32/64 bit issues here (running MacOS X 10.7.4).
The 32 bit VLC client [running as a standalone app - the VLC app you'd download from VideoLan.org] appears to work just fine in a 64 bit environment ...
Anyone having insight in this?
Both your application and dll must agree regarding this. If your app is 64-bit, the dll must be 64-bit. If your app is 32-bit, the dll must be 32-bit.
-
If I can get it to work, I'll gladly notify the author of PasLibvlc so he can add it to his distribution (thanks for all the legal info on this topic! I wasn't even aware.) - currently PasLibVLC supports Delphi and Lazarus (only Windows and Linux).
I would love to get it to work on MacOS X (Intel).
Referring to the 64 bit windows question earlier;
I assume that the 32 bit app vs 32 bit library applies to other platforms as well.
If your compiler builds 32 bit then you should probably use the 32 bit version of VLC as well, even under Windows?
Anyhow; I'm currently focussing on MacOS X.
Having the 32 bit version of VLC and a 32 bit app, I still only get sound, no video, no error messages though.
Most functions of the library seem to work just fine - getting video width, height, etc return the correct info.
I tried using GfxCardStatus (http://codykrieger.com/gfxCardStatus) (I'm working on a MacBook Pro that dynamically switches graphics "chips"), but switching between discreet graphics (nVidia) and integrated graphics (Intel) (http://tweaking4all.com/applications/mac-tools/macbook-pro-choose-what-video-chip-to-use) didn't make a difference. I switched before starting the app and while running the app, even forcing the video mode - none of it made a difference.
I played with the properties "AutoSize", "UseOverlay" and "VideoOnTop" (all booleans), but no results with those either.
But ... still no video :(
I have no idea how to debug this.
I'm having to guess right now, since I'm not seeing video, that I need to poke around with the following in PasLibVlcPlayerUnit;
Doh! %)
I just realized that I forgot that I commented out the following line - definitely a reason why there is no video:
FParentWindow := Windows.GetParent(SELF.Handle);
The compiler would throw an error there because (I'm guessing here) there is no "Windows" or "Unix" unit providing the "Windows" object?
I tried including "LCLIntf" instead, but that didn't work either.
Current uses clause:
unit PasLibVlcPlayerUnit;
interface
uses
{$IFDEF UNIX}
Unix,
{$ENDIF}
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
Classes, SysUtils, Controls, ExtCtrls, Graphics,
{$IFDEF FPC}
LCLType, LazarusPackageIntf, LResources, Forms, Dialogs,
{$ELSE}
Messages,
{$ENDIF}
PasLibVlcUnit,
PasLibVlcClassUnit;
Any suggestions what unit I should add to the uses clause to replace either the "unix" or "windows" unit?
Like I said; I'm really not sure where to look :(
-
FParentWindow := Windows.GetParent(SELF.Handle);
Shouldn't it be replaceable with:
FParentWindow := Self.Parent.Handle;
?
-
FParentWindow := Windows.GetParent(SELF.Handle);
Shouldn't it be replaceable with:
FParentWindow := Self.Parent.Handle;
?
I did try that as well, that was my first "work around" (or: correction).
That didn't work though (didn't crash either, but still no video).
I also tried:
FParentWindow := SELF.ParentWindow;
No dice ... :(
-
Maybe more progress:
For Windows VLClib uses:
libvlc_media_player_set_hwnd
For Linux:
libvlc_media_player_set_xwindow
And ... there is a function which I believe might be for MacOS use:
libvlc_media_player_set_nsobject
Which appears defined in PasLibVlc as:
libvlc_media_player_set_nsobject_t = procedure(
p_mi: libvlc_media_player_t_ptr;
drawable: Pointer
); cdecl;
The first parameter appears "easy" as it's being used in the Windows and Linux approach as well.
The second parameter (the pointer) is a little bit more difficult. According to the VLC documentations (http://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media__player.html#ga46c26a395b496e48917101198acc31f6):
drawable: the drawable that is either an NSView or an object following the VLCOpenGLVideoViewEmbedding protocol.
NSView (I think) is Apple specific - I just don't know where to find it and/or how to use it.
I did find this sniplet in the PasLibVlc code:
(**
* Set the NSView handler where the media player should render its video output.
*
* Use the vout called "macosx".
*
* The drawable is an NSObject that follow the VLCOpenGLVideoViewEmbedding
* protocol:
*)
// \@protocol VLCOpenGLVideoViewEmbedding <NSObject>
// - (void)addVoutSubview:(NSView *)view;
// - (void)removeVoutSubview:(NSView *)view;
// \@end
(*
* Or it can be an NSView object.
*
* If you want to use it along with Qt4 see the QMacCocoaViewContainer. Then
* the following code should work:
* @begincode
* {
* NSView *video = [[NSView alloc] init];
* QMacCocoaViewContainer *container = new QMacCocoaViewContainer(video, parent);
* libvlc_media_player_set_nsobject(mp, video);
* [video release];
* }
* @endcode
*
* You can find a live example in VLCVideoView in VLCKit.framework.
*
* \param p_mi the Media Player
* \param drawable the drawable that is either an NSView or an object following
* the VLCOpenGLVideoViewEmbedding protocol.
*)
Any of the Mac experts know how to work with this? Help is very much appreciated. :)
-
Nobody familier with this? :o
-
Does it work for you on Linux or Windows? I only get AV. If yes can you provide an working example. Thank you.
-
NSView (I think) is Apple specific - I just don't know where to find it and/or how to use it.
Yes, it's part of Mac OS X's Objective-C framework. FPC support is documented here (http://wiki.freepascal.org/FPC_PasCocoa). Note that I'm not a Mac expert (I don't have it, it's way too expensive).
-
Does it work for you on Linux or Windows? I only get AV. If yes can you provide an working example. Thank you.
According to the PasLibVlc package, both Windows and Linux are support already through this open source package.
Download it here: http://sourceforge.net/projects/paslibvlc/ (http://sourceforge.net/projects/paslibvlc/)
Note:
I am assuming that if you're creating a 32bit app, that you should use the 32bit version of VLC as well.
-
Yes, it's part of Mac OS X's Objective-C framework. FPC support is documented here (http://wiki.freepascal.org/FPC_PasCocoa).
Thanks :)
I did try to read through that, but I'm still confused on how to use it ... :(
-
I did try to read through that, but I'm still confused on how to use it ...
If you buy me a Mac I might be able to help :P
-
If you buy me a Mac I might be able to help :P
Haha, yeah, if I win Powerball, I'll keep that in mind :P
p.s. plenty of hackintosh possibilities and virtual machines for vmware player out there ;)