Closed matejbizjak closed 4 years ago
Hi @matejbizjak. Is this a public stream you are trying to play? Can you share the link so I can test?
The audio stream in the README usage section can also be played over https
. I tested with that one and it works fine for me.
Have you tried playing the stream using the vlc
application? Does it work with the application?
@adrg, yes, it is a public stream. I tried to play Vimeo and Youtube videos (example1, example2). They all work in the vlc application, I only have problems in the code with the library. However, I checked with some other https streams now and it works fine.
On Vimeo streams I got this errors:
[0000000028997960] main tls client error: connection error: Interrupted function call
That might be a specific problem only for Youtube and Vimeo as I'm reading here. However, it works in the vlc
application.
Yes, there are some Lua
plugins used for Vimeo
and Youtube
as the real video URL is embedded somewhere in the page (for Youtube, I think the plugin actually runs some Javascript
in order to obtain the video URL). In any case, there are no issues with the Lua
plugins as far as I can tell.
It seems like the media item retrieved from these sources has some subitems. I think I need to implement the libvlc_media_subitems binding for this. Then, you would call this new method for the obtained media and play the first subitem. This is the case if you want to play the media using the regular player.
However, I found that I am able to play the Vimeo
media using the list player, as the list player can play media with subitems.
package main
import (
"log"
vlc "github.com/adrg/libvlc-go/v3"
)
func main() {
if err := vlc.Init(); err != nil {
log.Fatal(err)
}
defer vlc.Release()
// Create a new list player.
player, err := vlc.NewListPlayer()
if err != nil {
log.Fatal(err)
}
defer func() {
player.Stop()
player.Release()
}()
// Create a new media list.
list, err := vlc.NewMediaList()
if err != nil {
log.Fatal(err)
}
defer list.Release()
err = list.AddMediaFromURL("https://vimeo.com/259411563")
if err != nil {
log.Fatal(err)
}
// Set player media list.
if err = player.SetMediaList(list); err != nil {
log.Fatal(err)
}
// Start playing the media list.
if err = player.Play(); err != nil {
log.Fatal(err)
}
// Retrieve player event manager.
manager, err := player.EventManager()
if err != nil {
log.Fatal(err)
}
// Register the media end reached event with the event manager.
quit := make(chan struct{})
eventCallback := func(event vlc.Event, userData interface{}) {
close(quit)
}
eventID, err := manager.Attach(vlc.MediaListPlayerPlayed, eventCallback, nil)
if err != nil {
log.Fatal(err)
}
defer manager.Detach(eventID)
<-quit
}
EDIT: I think the vlc
application actually uses a list player by default as well.
I implemented the binding for retrieving media sub-items. However, the process for playing Youtube
and Vimeo
media using the regular player
is kind of tedious.
Here are the steps:
vlc.MediaSubItemTreeAdded
event with the media event manager.vlc.MediaSubItemTreeAdded
event is fired, retrieve the sub-item list and play the first one.NOTE: for Vimeo
, it's actually even worse as the first sub-item needs to be parsed as well, and its first sub-item is the actual video that can be played.
So my recommendation is using a list player
when playing media from these two sources, as it is a lot easier.
package main
import (
"log"
vlc "github.com/adrg/libvlc-go/v3"
)
func main() {
// Initialize libVLC.
if err := vlc.Init(); err != nil {
log.Fatal(err)
}
defer vlc.Release()
// Create a new player.
player, err := vlc.NewPlayer()
if err != nil {
log.Fatal(err)
}
defer func() {
player.Stop()
player.Release()
}()
// Create media instance.
media, err := vlc.NewMediaFromURL("https://youtube.com/watch?v=or1dAmUO8k0")
if err != nil {
log.Fatal(err)
}
defer media.Release()
// Listen for sub-item change events for the media instace.
mManager, err := media.EventManager()
if err != nil {
log.Fatal(err)
}
mEventCB := func(event vlc.Event, userData interface{}) {
switch event {
case vlc.MediaSubItemTreeAdded:
subItems, err := media.SubItems()
if err != nil {
log.Fatal(err)
}
defer subItems.Release()
m, err := subItems.MediaAtIndex(0)
if err != nil {
log.Fatal(err)
}
if err := player.SetMedia(m); err != nil {
log.Fatal(err)
}
if err := player.Play(); err != nil {
log.Fatal(err)
}
}
}
mEventID, err := mManager.Attach(vlc.MediaSubItemTreeAdded, mEventCB, nil)
if err != nil {
log.Fatal(err)
}
defer mManager.Detach(mEventID)
// Parse media.
err = media.ParseWithOptions(0, vlc.MediaParseNetwork)
if err != nil {
log.Fatal(err)
}
// Retrieve player event manager.
manager, err := player.EventManager()
if err != nil {
log.Fatal(err)
}
// Register the media end reached event with the event manager.
quit := make(chan struct{})
eventCB := func(event vlc.Event, userData interface{}) {
close(quit)
}
eventID, err := manager.Attach(vlc.MediaPlayerEndReached, eventCB, nil)
if err != nil {
log.Fatal(err)
}
defer manager.Detach(eventID)
<-quit
}
Also, make sure you have the latest versions of vimeo.lua
and youtube.lua
. You can find them on the vlc
repository at https://github.com/videolan/vlc/tree/master/share/lua/playlist. Just copy the files in the Lua playlist
plugin directory of your vlc
installation.
@adrg Thanks, it works great now!
Player works fine with http streams, but it will not play streams over SSL.
I have the same problem with Python library... Is there a solution for playing over https?