shoes / shoes3

a tiny graphical app kit for ruby
http://walkabout.mvmanila.com
Other
181 stars 19 forks source link

vlc video audio #133

Closed passenger94 closed 8 years ago

passenger94 commented 9 years ago

made a "video" branch on my repository

working for me using system libvlc 2.2.0 should work on Windows too according to vlc doc with a method change from libvlc_media_player_set_xwindow to libvlc_media_player_set_hwnd, there's also a cocoa method : libvlc_media_player_set_nsobject ...

tested with simple-video.rb with a remote and a local file

ccoupe commented 8 years ago

Nice find for a a cocoa use of VLC. Very helpful. The online documentation appears to be wrong or incomplete. Who could have thought of that? :-)

Looks like I have to learn enough fiddle to build an char*[](aka argv) from Ruby [str, str,..]

ccoupe commented 8 years ago

cmd line args to libvlc_new() do print on the OSX launch terminal so that's nice. Still returns null from libvlc_new(). I suspect It's related to DYLD_LIBRARY_PATH and friends - see: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dyld.1.html

I suspect that libvlc.dylib tries to load libvlccore.dyblib using @loader_path and Shoes and fiddle are expecting @executable_path linkage. The causal OSX audience may not have the otool and libtool commands to rewrite, nor should that be done on a users system. Assuming I'm correct, this going to be big problem and and at the moment I don't know how to test it other than copying the two vlc dylibs into Shoes.

passenger94 commented 8 years ago

on linux this works : libvlc_new(1, ["--no-xlib"].pack('p')) for 1 command line argument libvlc_new(2, ["--no-xlib", "--no-video-title-show"].pack('p2')) for 2 command line arguments etc...

btw, vlc docs tells to stay away from command line args (in libvlc_new), mainly for portability reasons, if i understand correctly, but as long as we need to check for platform anyway ...

also an issue with plugin path on macos comes often, see https://www.bountysource.com/issues/2851867-lib-vlc-does-not-correctly-detect-the-plugin-path-correctly-if-loaded-in-a-thirdparty-app we can set it in command line arg : "--plugin-path=path_ to _plugins" sorry for DYLD_LIBRARY_PATH and friends, that's total cryptic for me ...

ccoupe commented 8 years ago

Pack? Of course. I knew there had to be a better way. Once the the args were passed in, vlc found and populated the plugins.dat file - another 50+ dylibs. First, I need to verify that DYLD_LIBRARY_PATH is the problem (or solution)

ccoupe commented 8 years ago

Fortunately for all, it just takes setting the ENV['VLC_PLUGIN_PATH'] osx-vid Now I can undo all the ugly I added.

IanTrudel commented 8 years ago

Awesome screenshot.

ccoupe commented 8 years ago

Awesome is the work of @passenger94 !!!

I do have a question for the international folks. We have hard coded paths to /Applications/VLC.app on OSX, for example. Is that a good path for internationalized OSX? . We check for "c:\Program Files (x86). Is that name used in all Windows? I have no idea.

Betas for OSX and Windows at the usual place http://walkabout.mvmanila.com/public/shoes Tight Linux builds have some issues which I know will be solvable. Documenting this ability for Shoes will be something of a challenge that I look forward too. I can hardly wait to tell everyone!

It's hard to describe how pleased I am.

IanTrudel commented 8 years ago

We have hard coded paths to /Applications/VLC.app on OSX, for example. Is that a good path for internationalized OSX?

My understanding is that translation is provided on UI level rather than filesystem level. The filesystem is all on the same on any localized version of MacOS X. Can anyone confirm this?

We check for "c:\Program Files (x86). Is that name used in all Windows?

Actually, we are supposed to use %ProgramFiles% and %ProgramFiles(X86)%. Never hard coded path! Please, take note that translation is provided at UI level. Filesystem is in plain English.

References https://technet.microsoft.com/en-us/library/cc749104(v=ws.10).aspx

ccoupe commented 8 years ago

Thanks @BackOrder , It appears that we have ENV['ProgramFiles(x86)'] already available (use samples/simple-info.rb) so that should be used . Here's screen shot after that change win7-video

IanTrudel commented 8 years ago

Take note that ENV['ProgramFiles(x86)'] is only available on 64 bit systems. 32 bit systems and older systems such as Windows XP use ENV['ProgramFiles'].

passenger94 commented 8 years ago

YES ! cool, nice news !! :+1:

ccoupe commented 8 years ago

There are confounding issues with the case of not having vlc installed in Linux - it doesn't always trigger an exception from dlload(). That one I think I can fix (have fixed for Linux?)

There is a more difficult problem if the vlc version is too old. Then videoffi.rb dies trying to extern something not in the older libvlc. VLC 2.0 vs 2.1 and 2.2. ? You'd want to raise an exception that says "Your version of VLC is too old" I'm unclear where to do that. The @version string isn't available until import symbols is called. @passenger94 - Advice, please

There's another error that may be related to my old linux chroot for x86 and i386 when run outside the chroot - They fail in ffi.so trying to load fiddle.so from Ruby which seems backwards to me. That could be that ruby wasn't compiled with ffi or fiddle or ... Doesn't happen on the pi2 build which uses a more recent debian that the chroots.

Lastly, there is @BackOrder mention of XP and 32 bit Windows. I have no way of testing on XP or interest in XP and you'll probably run afoul of the older VLC version problem noted above. It's only a few lines of Ruby to add to your XP Shoes. If systems are too old to run the new video code (and I have two linux chroots that won't) then it's time to update or do without video.

Failing gracefully is what I'm working on now.

passenger94 commented 8 years ago

for the libvlc version, we can

sorry i didn't paid much attention to that, just thrown (threw ?) a minimal check also the Object monkey patching is temporary, and maybe some structure declaration not needed for the moment : i'm still struggling with Fiddle to be able to check for width and height of a possible Video track, if someone have some advice ... ... i have different "working" (computer gods accepts the offering) routines but i get absurd numbers, and still unclear how to manage a union inside a structure in Fiddle context, which i need to access video, audio or subtitle track after calling libvlc_media_tracks_get https://github.com/Shoes3/shoes3/blob/b667c0b21574cbce8502a786256b36ac453e8922/lib/shoes/videoffi.rb#L333

ccoupe commented 8 years ago

That's much like I was going to do for version checks but I thought I should ask you since you know more than I about fiddle and vlc. I'll constrain my changes to that part of videoffi.rb FWIW, one can get VLC 2.1.5 on old debians (7.2 timeframe) via the backport repo. Removing it is not so obvious. Shoes 3.3.1 works with that one on i686 and fails properly if there is no vlc installed.

passenger94 commented 8 years ago

so it's under control now ? failing gracefully everywhere if problems ?

i managed, finally !, to get the width and height of the video track through libvlc_media_tracks_getusing a void pointer in place of the union in the Media_track structure

ccoupe commented 8 years ago

Now it doing the right thing for Linux, OSX & Windows when VLC is not installed or the version is too old. Also added a check for @BackOrder 32 bit XP "Program Files" but I can't test that.

I'm going to work on the manual for this feature. @passenger94 , if you get bored coding, you could always update the Wiki articles for installing Shoes on Windows or tell me what instructions were wrong or outdated.

passenger94 commented 8 years ago

Some food to think about the better protocol to call libvlc

i managed to compile latest git vlc (linux, 3.0.0 Vetinari) and our fiddling works ! I didn't installed it, so i gave the (not standard) path to libvlc to Vlc.load_lib AND i had to point the ENV['VLC_PLUGIN_PATH'] to the modules subdir ! (obviously becomes the plugins dir if installed)

So, at the moment, user have 2 different places to change in order to work with a random vlc lib, not good (and one is in shoes libs) ... also ENV['VLC_PLUGIN_PATH'] might be something to check on all platform (not standard installation is a frequent enough dandyism, i myself ....) Thoughts ?

passenger94 commented 8 years ago

i propose giving an optional "plugin_path" argument, set to a default nil, for Vlc.load_lib function and inside that function after importing symbols setting the ENV['VLC_PLUGIN_PATH'] with the value if given. I mean using named arguments, so we can deal with all combination of "path" and "plugin_path", being nil or not (assuming ruby 2.0+)

for example for me, in Shoes script, it is : Vlc.load_lib path: '~/NBWorkspace/vlc/lib/.libs/libvlc.so.5.5.0', plugin_path: "~/NBWorkspace/vlc/modules"

ccoupe commented 8 years ago

I do think it's a good idea to allow for non standard locations (plural) but rather than code that location into the users script, why not another cobbler screen. Very similarly to how we can change the location of the packaging downloads. Screen would allow user to enter the locations and create a small file in ~/.shoes/walkabout (and set two ENV['vars'] ). At Shoes startup, (lib/shoes/cache.rb) we can test for that file and if found, load the ENV['vars'] Should be pretty simple.

we could also move/duplicate some of the code in vlc.load_lib to run at Shoes startup to populate the ENV[vars] if the file doesn't exist but the defaults paths do.

passenger94 commented 8 years ago

oh yes, let's go to the cobbler, sounds good to me ! Beware, that guy is slowly but surely growing up ... ! ;-D

Speaking of back shop, i finally put the libvlc_media_tracks_get under control, after like decades of fiddle and C pointers bloody skirmish, (that was something !)

cleaning, synch and PR

Edit: another advantage of non standard locations is that you can zip/pack libvlc with your script as an option and set paths accordingly (will be platform dependant, but it'll be a user choice only)

is it good to synch now ? or better wait a bit ?

As for the build on Windows Wiki page, i'll look closely, but the general explanation is accurate (with the precious help of your prepared files ...)

ccoupe commented 8 years ago

I'll volunteer to update the cobbler, cache and and that part of videoffi.rb if you like. I'm familiar with it. Unless you want to do it.

passenger94 commented 8 years ago

please do so, i'm not familiar with the cobbler, i should though !! :-D

ccoupe commented 8 years ago

I think I'm done with my mods. Works well enough for me. I'd be happy for a PR from @passenger94 and we can merge this branch into master and release 3.3.1. After documenting and testing again, of course.

ccoupe commented 8 years ago

Edit: another advantage of non standard locations is that you can zip/pack libvlc with your script as an option and set paths accordingly (will be platform dependant, but it'll be a user choice only)

Anybody that does that successfully cross platform Will be named "King Of Shoes." All hail their suffering.

passenger94 commented 8 years ago

haha ! i sure got that ! I mean : if one wants to give a shoes script using video facility to someone else not having vlc or not wanting to install vlc, she/he could do it provided both being on same platform ! just send the (usual packed) script along with a copy of libvlc and plugins dir then set path accordingly, conceivable ? just tested ok with both libvlc and plugin dir in some random dir (250Mo+ though ...) Your setup seems to work nice !!! Thanks !!!!! Doing a PR with synched repo and further fixes, enhancements (regression?)

do we need this ? : https://github.com/Shoes3/shoes3/blob/video_vlc/samples/expert-video-player.rb#L113 This should be taken care of in Vlc.load_lib (it is, i think) just require 'shoes/videoffi'; Vlc.load_lib; and be done ? isn't it the whole purpose of the cobbler ?

ccoupe commented 8 years ago

I've merged everything into master at github so that's were we should finish up any more changes to video. I'm very pleased about this. Thank you for your hard work.

do we need this ? : https://github.com/Shoes3/shoes3/blob/video_vlc/samples/expert-video-player.rb#L113

I just felt it was a better example of how to determine that you have video capabilities and respond in a GUI friendly manner (the alert) rather than a blank screen with an error message in the hidden console and also moved the required and load into the Shoes.app {} block. Or demonstrating how to catch an expectation.

just send the (usual packed) script along with a copy of libvlc and plugins dir then set path accordingly, conceivable ? As long as you don't attempt to copy into directories you don't have permissions. Clever people could create a gem with the tar balls inside and an extract script that runs when the gem is required and you could package that HUGE gem with your script. Even bigger GEM if it has all 5 architectures inside !

2nd thought. One could have yet another cobble button to load those tar balls into some new place into the Shoes/Ruby tree (we can write into the gem areas) - very non standard from a Ruby perspective. I don't want to host those files though but someone else could.

passenger94 commented 8 years ago

something is missing here ? https://github.com/Shoes3/shoes3/blob/master/shoes/video/video.c#L156

As we know that we are going to raise an exception if something is wrong with libvlc path, we just need to Shoes.show_log prior to raise, seems to work from my tests ? that way, if working, we can keep require and load_lib clean

for the libvlc, plugins dir sharing, the idea was to give the entire responsibility of this, to the user, just letting know it's possible, if on same platform of course ! (plugins dir is like 16 Mo in fact - i was sharing the entire modules dir from a compile setup, with all intermediate files and sources -)

i have no way to test this, going from https://github.com/Shoes3/shoes3/blob/master/lib/shoes/videoffi.rb#L263 to

    if RUBY_PLATFORM =~ /darwin/ && ENV['VLC_PLUGIN_PATH'].nil?
         ENV['VLC_PLUGIN_PATH']="/Applications/VLC.app/Contents/MacOS/plugins"
    end
    # if you need to pass command line args in, then create them like this:
    # libvlc_new(2, ["--no-xlib", "--no-video-title-show"].pack('p2'))
    @vlci = libvlc_new(0, nil)
    @version = libvlc_get_version
    raise "vlc version #{@version} #{@vlci.inspect}" if @vlci.null?
ccoupe commented 8 years ago

something is missing here ? https://github.com/Shoes3/shoes3/blob/master/shoes/video/video.c#L156

In this case, OSX is easier. Shoes_Control_Ref is * NSView which what vlc wants to draw in. No special casting is needed.

i have no way to test this, going from https://github.com/Shoes3/shoes3/blob/master/lib/shoes/videoffi.rb#L263

In this case OSX is harder. VLC can only be installed in /Applications and can't be moved from /Applications easily and if you do, it's not an OSX App that you can browse in to find the libvlc.dylib and plugins. So, OSX can't have two VLC's, unless one of them is built from source but not installed. Linux is actually similar. Windows does allow VLC to be installed in different places so except for your situation (two vlc's, one not installed) only Windows really could use this feature, for regular folks. I should remove that darwin condition however since it's not needed and interferes with the unlikely case that Shoes user actually has build from source vlc and a the normal VLC

ccoupe commented 8 years ago

Confirmed that on OSX, the Shoes ask_open dialogs will not go inside an App bundle. That's a good thing if you want to pick an App. Not so good to pick something inside an app.bundle. Current behavior is highly likely continue which means on OSX, VLC needs to be in /Applications.

passenger94 commented 8 years ago

Ok ! noted :-)

ccoupe commented 8 years ago

I'm willing to close this issue and release 3.3.1 - Note, closing an issue doesn't mean it's 100% just that its good enough for people to use.