adrg / libvlc-go

Handcrafted Go bindings for libVLC and high-level media player interface
https://pkg.go.dev/github.com/adrg/libvlc-go/v3
MIT License
437 stars 50 forks source link

Embed VLC rather than floating window? #34

Closed erikherz closed 4 years ago

erikherz commented 4 years ago

This project launches a new window for VLC. Can we embed the VLC player inside another GUI toolkit, like GTK rather than spawning a new window?

adrg commented 4 years ago

Hi @erikherz. Thank you for your interest in the library. It should work if you're on Linux. I have to add another binding for setting the window for the player on Windows.

Here's a quick test I made using https://github.com/mattn/go-gtk:

package main

import (
    "log"

    vlc "github.com/adrg/libvlc-go/v3"
    "github.com/mattn/go-gtk/glib"
    "github.com/mattn/go-gtk/gtk"
)

func main() {
    // Initialize libVLC module.
    if err := vlc.Init("--quiet"); err != nil {
        log.Fatal(err)
    }
    defer vlc.Release()

    // Create GTK window.
    gtk.Init(nil)
    window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
    window.SetPosition(gtk.WIN_POS_CENTER)
    window.SetTitle("libVLC embed test")
    window.Connect("destroy", func(ctx *glib.CallbackContext) {
        gtk.MainQuit()
    }, "test")

    window.SetSizeRequest(600, 600)
    window.ShowAll()

    // Create a new player.
    player, err := vlc.NewPlayer()
    if err != nil {
        log.Fatal(err)
    }
    defer func() {
        player.Stop()
        player.Release()
    }()

    media, err := player.LoadMediaFromPath("test.mp4")
    if err != nil {
        log.Fatal(err)
    }
    defer media.Release()

    // Set window for the player.
    player.SetXWindow(uint32(window.GetWindow().GetNativeWindowID()))
    if err = player.Play(); err != nil {
        log.Fatal(err)
    }

    gtk.Main()
}
erikherz commented 4 years ago

Thank you. How can I attach the player object to a GTK widget? Ideally like so: grid.Attach(player, 1, 1, 3, 1) Can I map it to the GtkImage widget or GtkGLArea?

adrg commented 4 years ago

@erikherz Yes, the player can be attached to a GTK widget. I added a sample GTK player example which hopefully addresses your issue. In this case, I attached the player to a gtk.DrawingArea.

Let me know if the example helps: https://github.com/adrg/libvlc-go/blob/master/v3/examples/gtk_player.go

EDIT: You can also render to a gtk.Image.

playerWidget := gtk.NewImage()
// instead of:
// playerWidget := gtk.NewDrawingArea()
adrg commented 4 years ago

@erikherz I added bindings to set the player window for Windows and macOS. Also updated the GTK player example. Can this issue be closed?

erikherz commented 4 years ago

Thank you, Adrian-George. I am still having trouble getting VLC to compile against this on Windows.

I installed VLC on Windows as per your suggestion: https://github.com/adrg/libvlc-go/wiki/Install-on-Windows

I did pull the VLC code from Git and then was able to set these variables:

$ export CGO_CFLAGS="-IC:\libvlc\include"
$ export CGO_LDFLAGS="-LC:\libvlc"

C:\GIT\libvlc-go\v3>set CGO_LDFLAGS=-LC:\libvlc

C:\GIT\libvlc-go\v3>set CGO_CFLAGS=-IC:\libvlc\include

C:\GIT\libvlc-go\v3>go build
# runtime/cgo
gcc_libinit_windows.c: In function 'x_cgo_sys_thread_create':
gcc_libinit_windows.c:57:12: error: implicit declaration of function '_beginthread' [-Werror=implicit-function-declaration]
   57 |  thandle = _beginthread(func, 0, arg);
      |            ^~~~~~~~~~~~
cc1: all warnings being treated as errors
go: failed to remove work dir: GetFileInformationByHandle C:\Users\vivoh\AppData\Local\Temp\2\go-build851553638\NUL: Incorrect function.

C:\GIT\libvlc-go\v3>

C:\GIT\libvlc-go\v3>which go
/cygdrive/c/Go/bin/go

C:\GIT\libvlc-go\v3>go version
go version go1.14 windows/amd64

C:\GIT\libvlc-go\v3>
Screen Shot 2020-03-12 at 11 17 27 AM
adrg commented 4 years ago

@erikherz This does not seem related to libvlc. How did you install go? Did you build it from source? This seems like a problem with the C compiler. Can you do which gcc and gcc --version? Also, it seems you are using cygwin, which might have installed an old version of gcc. The screenshots I took were made in the regular Windows cmd. Did you try building in that? You could also try installing https://jmeubank.github.io/tdm-gcc.

erikherz commented 4 years ago

Will do.

vivoh@windows-gtk-1 /GIT/libvlc-go/v3 $ which gcc /usr/bin/gcc

vivoh@windows-gtk-1 /GIT/libvlc-go/v3 $ gcc --version gcc (GCC) 9.2.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

adrg commented 4 years ago

That's a pretty new version gcc. You could also try ignoring those warnings and see if that works, because they are treated as errors by default it seems.

set CGO_CFLAGS=-IC:\libvlc\include -D LIBSOLV_INTERNAL -Wno-error
set CGO_LDFLAGS=-LC:\libvlc
go build

Or to ignore all warnings:

set CGO_CFLAGS=-IC:\libvlc\include -D LIBSOLV_INTERNAL -w
set CGO_LDFLAGS=-LC:\libvlc
go build
erikherz commented 4 years ago

Looks like I need to set up pkg-config?

C:\GIT\libvlc-go\v3\examples>set CGO_CFLAGS=-IC:\libvlc\include -D LIBSOLV_INTERNAL -Wno-error

C:\GIT\libvlc-go\v3\examples>set CGO_LDFLAGS=-LC:\libvlc

C:\GIT\libvlc-go\v3\examples>go build
# pkg-config --cflags  -- pango
pkg-config: exec: "pkg-config": executable file not found in %PATH%
# pkg-config --cflags  -- glib-2.0 gobject-2.0
pkg-config: exec: "pkg-config": executable file not found in %PATH%
# github.com/adrg/libvlc-go/v3
In file included from _cgo_export.c:4:
event_manager.go: In function 'eventAttach':
event_manager.go:11:55: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
event_manager.go: In function 'eventDetach':
event_manager.go:14:48: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
# github.com/adrg/libvlc-go/v3
..\event_manager.go: In function 'eventAttach':
..\event_manager.go:11:55: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   11 |     return libvlc_event_attach(em, et, eventDispatch, (void*)userData);
      |                                                       ^
..\event_manager.go: In function 'eventDetach':
..\event_manager.go:14:48: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   14 |     libvlc_event_detach(em, et, eventDispatch, (void*)userData);
      |                                                ^
# github.com/adrg/libvlc-go/v3
cgo-gcc-prolog: In function '_cgo_a07b0869c079_Cfunc_libvlc_media_is_parsed':
cgo-gcc-prolog:173:2: warning: 'libvlc_media_is_parsed' is deprecated [-Wdeprecated-declarations]
In file included from C:\libvlc\include/vlc/vlc.h:51,
                 from ..\media.go:4:
C:\libvlc\include/vlc/deprecated.h:249:4: note: declared here
  249 |    libvlc_media_is_parsed( libvlc_media_t *p_md );
      |    ^~~~~~~~~~~~~~~~~~~~~~
cgo-gcc-prolog: In function '_cgo_a07b0869c079_Cfunc_libvlc_media_parse':
cgo-gcc-prolog:226:2: warning: 'libvlc_media_parse' is deprecated [-Wdeprecated-declarations]
In file included from C:\libvlc\include/vlc/vlc.h:51,
                 from ..\media.go:4:
C:\libvlc\include/vlc/deprecated.h:209:1: note: declared here
  209 | libvlc_media_parse( libvlc_media_t *p_md );
      | ^~~~~~~~~~~~~~~~~~
cgo-gcc-prolog: In function '_cgo_a07b0869c079_Cfunc_libvlc_media_parse_async':
cgo-gcc-prolog:238:2: warning: 'libvlc_media_parse_async' is deprecated [-Wdeprecated-declarations]
In file included from C:\libvlc\include/vlc/vlc.h:51,
                 from ..\media.go:4:
C:\libvlc\include/vlc/deprecated.h:233:1: note: declared here
  233 | libvlc_media_parse_async( libvlc_media_t *p_md );
      | ^~~~~~~~~~~~~~~~~~~~~~~~

C:\GIT\libvlc-go\v3\examples>
adrg commented 4 years ago

Yes. It seems that's needed for GTK. See the Windows installation instructions on the go-gtk repository. But from the output you attached that seems like a warning. Did it build the executable?

erikherz commented 4 years ago

I don't see a binary. To be clear, I should now follow these here: https://github.com/gotk3/gotk3/wiki/Installing-on-Windows

adrg commented 4 years ago

Yes, you most certainly need to install GTK. Try following the installation instructions on the link you mentioned. I'll try running the example on Windows as well.

erikherz commented 4 years ago

I got an error in MSYS running the required pacman commands:

vivoh@windows-gtk-1 MSYS ~
$ pacman --noconfirm -Su
      1 [main] bash 491 child_copy: data read copy failed, 0x1004C4000..0x1004CCD40, done 24576, windows pid 1484, Win32 error 299
Segmentation fault
erikherz commented 4 years ago

I reinstalled Go after setting the environment variable and now the pacman scripts are running ... I am optimistic. More soon ...

adrg commented 4 years ago

Installing GTK turns out to be a very tedious task. In any case, my advice is to try to get one of the examples mentioned in https://github.com/gotk3/gotk3/wiki/Installing-on-Windows running on Windows first.

The examples in my repository are using go-gtk (which uses GTK2). However, if you get an example from the gotk3 repository up and running, integrating libVLC should be pretty easy.

EDIT: I'll probably also update the examples to use GTK3 sometime this week or at the beginning of the next one.

erikherz commented 4 years ago

No luck

C:\GIT\gotk3>cd gtk

C:\GIT\gotk3\gtk>go build
# github.com/gotk3/gotk3/glib
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in

C:\GIT\gotk3\gtk>

and

C:\GIT\libvlc-go\v3\examples>go get github.com/gotk3/gotk3/gtk
go: downloading github.com/gotk3/gotk3 v0.4.0
go: found github.com/gotk3/gotk3/gtk in github.com/gotk3/gotk3 v0.4.0
# github.com/gotk3/gotk3/glib
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
adrg commented 4 years ago

I'll update the examples to GTK3 and try and get them running on Windows and let you know. Cross-compiling from Linux is also an alternative: https://github.com/gotk3/gotk3/wiki/Cross-Compiling.

adrg commented 4 years ago

Hi @erikherz. I adapted the player example to GTK 3. You can find the example here: https://github.com/adrg/libvlc-go/tree/master/v3/examples/gtk3_player I also tested it on Windows and created a wiki page on how to build the GTK 3 examples: https://github.com/adrg/libvlc-go/wiki/Build-GTK-3-examples

EDIT: I also updated the GTK 2 player example: https://github.com/adrg/libvlc-go/tree/master/v3/examples/gtk2_player You can find instructions for building GTK 2 examples on Windows here: https://github.com/adrg/libvlc-go/wiki/Build-GTK-2-examples

erikherz commented 4 years ago

Thank you!