Lazarus

Programming => Widgetset => Carbon => Topic started by: Hansaplast on July 14, 2012, 06:51:24 am

Title: VideoLAN (VLC) use in MacOS Apps?
Post 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):
Code: [Select]
/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)

Code: [Select]
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?
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 14, 2012, 09:16:24 am
And your code using the unit (i.e. a test program)?

Quote
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.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 14, 2012, 05:00:05 pm
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.



Code: [Select]
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.

Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 14, 2012, 05:18:38 pm
In libvlc_dynamic_dll_init_with_path:
Code: [Select]
{$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:
Code: [Select]
IncludeTrailingPathDelimiter(libvlc_dynamic_dll_path)or
Code: [Select]
AppendPathDelim(libvlc_dynamic_dll_path)The 2nd one requires FileUtil to be present in the uses clause.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 16, 2012, 06:13:38 pm
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.  :)
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 16, 2012, 11:47:33 pm
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?
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 16, 2012, 11:57:11 pm
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?
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 17, 2012, 01:52:51 am
Functions like GetVideoHeight, GetVideowidth, GetVideoLenStr all return correct values ...
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: mdalacu on July 17, 2012, 09:02:07 am
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.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: BigChimp on July 17, 2012, 10:01:52 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.
...
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 ;)
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 17, 2012, 11:00:17 am
Quote
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?
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 17, 2012, 11:02:15 am
Quote
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.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 19, 2012, 07:08:16 am
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:
Code: [Select]
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:
Code: [Select]
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 :(
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 19, 2012, 09:11:18 am
Quote
FParentWindow := Windows.GetParent(SELF.Handle);
Shouldn't it be replaceable with:
Code: [Select]
FParentWindow := Self.Parent.Handle;?
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 19, 2012, 05:46:58 pm
Quote
FParentWindow := Windows.GetParent(SELF.Handle);
Shouldn't it be replaceable with:
Code: [Select]
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:

Code: [Select]
FParentWindow := SELF.ParentWindow;
No dice ... :(
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 20, 2012, 06:23:28 am
Maybe more progress:

For Windows VLClib uses:

Code: [Select]
libvlc_media_player_set_hwnd
For Linux:

Code: [Select]
libvlc_media_player_set_xwindow
And ... there is a function which I believe might be for MacOS use:

Code: [Select]
libvlc_media_player_set_nsobject
Which appears defined in PasLibVlc as:

Code: [Select]
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):

Quote
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:

Code: [Select]
(**
 * 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.  :)
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 25, 2012, 04:19:15 am
Nobody familier with this?  :o
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: mdalacu on July 25, 2012, 06:59:49 am
Does it work for you on Linux or Windows? I only get AV. If yes can you provide an working example. Thank you.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 25, 2012, 01:11:12 pm
Quote
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).
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 25, 2012, 03:58:39 pm
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.
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 25, 2012, 04:00:01 pm
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 ... :(
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Leledumbo on July 25, 2012, 04:58:34 pm
Quote
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
Title: Re: VideoLAN (VLC) use in MacOS Apps?
Post by: Hansaplast on July 25, 2012, 08:05:08 pm
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 ;)