MacOS and VLC - The main library loads, but after that.... help please! lazarus / 33-macOS - Mac OS X ---------------------------------------------------------------------- Manlio · 2022-02-11 16:06 I am trying to run a very basic VLC demo app on MacOS, using PasLibVlc from https://prog.olsztyn.pl/paslibvlc/ and I am stuck Short version of my question: if you have a basic demo app for MacOS that loads VLC and plays a video file, can you kindly share it, so that I can learn from it and move forward? This is what happens when I try to do it, using the first and simplest demo app included in the PasLibVlc package: The two main libraries libvlc.dylib and libvlccode.dylib are loaded successfully, using either libvlc_dynamic_dll_init() or libvlc_dynamic_dll_init_with_path(path). I can see that the two library handles are created, and all the procedure addresses are filled in correctly with calls to libvlc_dll_get_proc_addr(...) The next step, however, calling libvlc_new() always returns NIL. I tried with and without arguments:  libvlc_new(ArgC, ArgS), libvlc_new(0,nil) When trying with arguments, I tried countless combinations of arguments. (The documentation recommends to call it with (0,nil) by the way) I read every page and forum post on the subject that I could find, and most people say that the most likely cause of failure is that the plugins folder is not found. The documentation mentions that as a common reason for the call to libvcl_new() to fail and return nil. In my case however the plugins are in the standard folder. I even tried to: - Put a copy of the plugins folder next to the executable - Put a copy of all the dylib files next to the executable - Put a copy of both the main lib (vlc and vlccode) and plugin dylibs in the same folder as the executable. In every case, I was able to load the main libraries (vlc and vlccode) but libvlc_new() always returned nil. Now, in older versions there was a --plugin-path argument that allowed a different path to be specified, but if I used that I got a warning that the argument is not used anymore. Instead, a few places mention that a VLC_PLUGIN_PATH environment variable may be used to indicate a non-standard location of the plugins folder. I would like to try that, but I don't know how to set such an environment variable in MacOS. I tried fpsystem('export VLC_PLUGIN_PATH=mypath...') but I see that it doesn't get picked up when I enumerate with GetEnvironmentString. In fact, some sources say that it is not possible on MacOS to add environment strings once a process is running. VLC, on the other hand, states that if a non- standard location for the plugin is used, the VLC_PLUGIN_PATH should be set before the call to libvlc_new(). Now, can you help me to figure this out? How do I set this environment variable to the path where the plugins are located? Or is there something else that I am missing? After all, the plugins are in the standard location, and they should be found automatically. By the way, I did similar tests on Windows, and things worked fine right away. I'm only facing this problem on MacOS. I'm using PasLibVlc 3.0.11, VLC 3.0.17, Lazarus 2.0.10 and FPC 3.2.0 for MacOS. One last thing I noticed is that PasVlcLib looks like it was tested on Delphi for both Windows and MacOS, but on Lazarus only for Windows, and not for MacOS. I had to tweak a few things (like typecast THandle into pointer) to make it even compile on the MacOS version of FCP instead of the Windows one. Perhaps something is missing there, causing this problem? I am way out of my depth here, and any help will be extremely appreciated. And again, the best form of help would be a trivial demo app that compiles and runs on MacOS. In that case, please also include your version of the PasVlcLib files that should go with it. One again thanks... This is the code I'm currently using for testing: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TMainForm.PlayerInit();var i: integer; cmd: ansistring; res: cint;begin  cmd := 'export VLC_PLUGIN_PATH=' + PluginPath;  res := unix.fpSystem(cmd);  Log(cmd + ' RESULT=' + IntToStr(res));  Log('Use path: ' + vlc_path);  libvlc_dynamic_dll_init_with_path(vlc_path);  if libvlc_installed() then    Log('VLC installed in ' + libvlc_dynamic_dll_path)  else    Log('VLC NOT installed!!!');  if (libvlc_dynamic_dll_error <> '') then  begin    Log('Error: ' + libvlc_dynamic_dll_error);    MessageDlg(libvlc_dynamic_dll_error, mtError, [mbOK], 0);    Application.Terminate();    exit;  end;   for i := 0 to GetEnvironmentVariableCount-1 do    Log('EV#'+IntToStr(i+1)+'='+GetEnvironmentString(i));   sleep(20);   with TArgcArgs.Create([    WideString(libvlc_dynamic_dll_path),//    ' --verbose',    '--no-video-on-top'  ]) do  begin    p_li := libvlc_new(ARGC, ARGS);    if p_li=nil then      Log('FAILED, p_li NIL')    else      Log('SUCCESS');    Free;  end;   if (p_li <> NIL) then  begin    p_mi := libvlc_media_player_new(p_li);    if p_mi=nil then      Log('p_mi NIL FAILED')    else      Log('p_mi SUCCESS');  end;end; ---------------------------------------------------------------------- trev · 2022-02-12 03:03 I have written a demo macOS video player using the Mac's native API. See my Wiki article macOS Video Player if you're interested. Quote from: Manlio on February 11, 2022, 05:06:33 pmThe two main libraries libvlc.dylib and libvlccode.dylib are loaded successfully, using either libvlc_dynamic_dll_init() or libvlc_dynamic_dll_init_with_path(path). I can see that the two library handles are created, and all the procedure addresses are filled in correctly with calls to libvlc_dll_get_proc_addr(...) The next step, however, calling libvlc_new() always returns NIL. I tried with and without arguments:  libvlc_new(ArgC, ArgS), libvlc_new(0,nil) When trying with arguments, I tried countless combinations of arguments. (The documentation recommends to call it with (0,nil) by the way) I read every page and forum post on the subject that I could find, and most people say that the most likely cause of failure is that the plugins folder is not found. The documentation mentions that as a common reason for the call to libvcl_new() to fail and return nil. I have no experience with VLC libraries, but you may find my Wiki articles on creating and using macOS libraries helpful, especially in elation to debugging them. See in this order: * Libraries. * macoOS Frameworks. * macOS Dynamic Libraries. ---------------------------------------------------------------------- Manlio · 2022-02-12 21:18 Quote from: trev on February 12, 2022, 04:03:35 amI have written a demo macOS video player using the Mac's native API. See my Wiki article macOS Video Player if you're interested. That's excellent, thank you! I am going to study that code religiously now... Also many thanks for the links to the articles on static and dynamic linking to libraries. After reading those parts, I'd like to refine my original VLC-related question in this way: 1. In the case of VLC, there are two main dylib files (vlc and vlccore) and hundreds of "plugins", i.e. other dylib files that are called up as needed by vlc or vlccode. 2. The two main dylib are in one folder, and the plugins in another folder. 3. The main program only interacts with vlc/vlccore, and at design time it is not known which plugin may or may not be present. Plugins/dylib files are opened and closed by vlc/vlccore, without the main program knowing anything about it. 4. In my program, I load the main dylib files (vlc/vlccore) dynamically by providing the full path. But because the plugins are not opened explicitly by the main program, but rather they are opened by another dylib, and they (the plugins) are located in another folder -- I don't know how to let the system know at runtime where those plugins can be found. Previously, the call to libvlc_new() allowed an argument --plugin-path to specify that, but now it has been removed, and I don't know how to do things in the new way -- so once again, if anyone has a working demo of VLC for MacOS, it will be extremely appreciated! ---------------------------------------------------------------------- trev · 2022-02-12 23:40 Seems to be a VLC bug from July 2020: https://code.videolan.org/videolan/LibVLCSharp/-/issues/365 One solution is this (I've not tested myself): https://forum.videolan.org/viewtopic.php?t=76727 ---------------------------------------------------------------------- Manlio · 2022-02-13 03:24 Quote from: trev on February 13, 2022, 12:40:10 amSeems to be a VLC bug from July 2020: https://code.videolan.org/videolan/LibVLCSharp/-/issues/365 Somewhere in the bug description it says: "Even when using the non standard @rpath/libvlc dlopen argument and setting the correct VLC_PLUGIN_PATH, libvlc_new returns null." Now, in my case, I haven't gone that far -- I haven't been able to set the VLC_PLUGIN_PATH at all. Perhaps if I can set that environment variable (VLC_PLUGIN_PATH) to the plugins folder before calling libvlc_new() then it will work. I tried setting it with fpsystem('export VLC_PLUGIN_PATH=...') but apparently that's not the way... I will now create a new post to ask this specific question, how to create environmental variables in MacOS. Thanks! ---------------------------------------------------------------------- trev · 2022-02-13 05:09 It seems from the VLC source that setting the VLCParams property in the application's Info.plist file is supposed to work - but it may not if you read the solution someone came up with in the VLC forum topic which I posted above. It would certainly be the conventional macOS way. ---------------------------------------------------------------------- Manlio · 2022-02-13 09:46 Quote from: trev on February 13, 2022, 06:09:11 amIt seems from the VLC source that setting the VLCParams property in the application's Info.plist file is supposed to work - but it may not if you read the solution someone came up with in the VLC forum topic which I posted above. It would certainly be the conventional macOS way. I also wondered whether Info.plist was the way to go, and so I went to see the Info.plist file of the officially distributed VLC.app. I went through it line by line and there is no trace of any reference to any plugin folder anywhere. I am attaching VLC's own Info.plist file to this message if anyone is curious. I guess that one way to figure this out would be to download VLC's source code for macOS (it's open soure after all) and figure out how they do it, but I don't think I have the skills for that. Hopefully there should be at least one person who has played a file with VLC on the Mac with Lazarus at some point or another, and they can tell us how they did it...