Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playing form an url using an API is not working #104

Open
SamuelMR98 opened this issue May 9, 2023 · 2 comments
Open

Playing form an url using an API is not working #104

SamuelMR98 opened this issue May 9, 2023 · 2 comments

Comments

@SamuelMR98
Copy link

SamuelMR98 commented May 9, 2023

So I'm implementing an API that receives an URL in JSON format from an HTTP request, and plays the video using VLC. However, the player never starts, when I use the -vvv flag VLC seems to be alive but not reproducing anything. FYI, I'm currently running this on Manjaro, but plan to implement it on a Rasp Berry Pi running on Raspbian. Thanks in advance.

Here's what I have so far:

my handler:

func (v *VlcManager) playStream(c *gin.Context) {
	v.Log.Debug("playing stream")

	Player = nil

	// Get the infor from streamURL json
	var streamURL StreamURL
	err := c.BindJSON(&streamURL)
	if err != nil {
		v.Log.Warn("failed to bind json", zap.Error(err))
		c.JSON(http.StatusInternalServerError, err)
		return
	}
	url := string(streamURL.URL)
	fmt.Println("url: ", url)

	if v.ConfigService != nil {
		stream, err := v.ConfigService.GetStreamConfig(c.Request.Context(), url)
		if err == nil && stream.Secret != "" {
			// the token is everything after the base URL
			token, err := v.generateToken(stream)
			if err != nil {
				v.Log.Error("error generating secure token: %s", zap.Error(err))
				c.JSON(http.StatusInternalServerError, err)
				return
			}
			v.Log.Info("generated secure token", zap.String("token", token))
			url += token
		}

	}
	Player, err = helpers.SwitchStream(Player, url)
	if err != nil {
		v.Log.Warn("failed to switch stream", zap.Error(err))
		c.JSON(http.StatusInternalServerError, err)
		return
	}
	c.JSON(http.StatusOK, "stream playing")
}

the actual command:

func SwitchStream(player *vlc.Player, stream string) (*vlc.Player, error) {

	// Initialize libVLC. Additional command line arguments can be passed in
	// to the libVLC by specifying them in the Init function.
	if err := vlc.Init("-vvv"); err != nil {
		log.Fatal(err)
		return nil, err
	}
	defer vlc.Release()

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

	media, err := player.LoadMediaFromURL(stream)
	if err != nil {
		log.Fatal(err)
		log.Printf("error loading media: %s", err)
		return nil, err
	}
	defer media.Release()

	manager, err := player.EventManager()
	if err != nil {
		log.Fatal(err)
	}

	quit := make(chan struct{})
	eventCallback := func(event vlc.Event, userData interface{}) {
		close(quit)
	}

	eventID, err := manager.Attach(vlc.MediaPlayerEndReached, eventCallback, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer manager.Detach(eventID)

	if err != nil {
		log.Fatal(err)
	}
	defer manager.Detach(eventID)

	//Start playing the media.
	if err = player.Play(); err != nil {
		log.Fatal(err)
		log.Printf("error playing media: %s", err)
		return nil, err
	}

	<-quit

	return player, nil
}
@adrg
Copy link
Owner

adrg commented May 11, 2023

Hi @SamuelMR98,

At a first glance, one thing you can try is to initialize libVLC just once, preferably on the main thread (somewhere at the beginning of your main function perhaps) instead of doing so per request.

Can you please provide a minimal sample which I can run and test the issue?

@SamuelMR98
Copy link
Author

Thanks for your Reply!
Here's the link to the repo where the project lives:
https://github.com/byuoitav/vlcplayer-microservice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants