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

Basic Video support #333

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

essboyer
Copy link
Contributor

@essboyer essboyer commented Dec 11, 2024

Basic Video Support

This PR provides a working POC (proof-of-concept) demonstrating native video playback capabilities inside Linux Show Player. In the final phase it will provide a basic implementation of video support which should be good enough for many shows (and which should ultimately address issue #3).

In the POC Phase (Phase I) LSP uses the WaylandSink for full-sized video playback on the main display. The video can be set to play in fullscreen. In Phase II a choice of video sinks may be presented to suit the environment.

Code changes are entirely within the gst_backend plugin.

This is my first contribution to the project (and my first time contributing to a python project) and I hope it will spark some interest in further development in LSP as a capable rival to the likes of QLab.

What's working

  • add a video cue (right-click context menu)
  • add a video cue (drag & drop)
  • video playback on main display only
  • fullscreen playback on main display
  • seek/pause/etc
  • audio playback
  • audio pipeline (db meters, etc)
  • video duration

TODO

  • video playback on external monitor/projector
  • more robust video sink selection
  • hide mouse during playback
  • fade video opacity
  • adjust other video parameters (brightness, contrast, etc)
  • image transform (keystone)
  • video playback in a window (audition)
  • video thumbnail

@essboyer essboyer marked this pull request as ready for review December 11, 2024 01:30
@FrancescoCeruti FrancescoCeruti added the GStreamer Related to the Gstreamer backend label Jan 2, 2025
@FrancescoCeruti FrancescoCeruti self-assigned this Jan 2, 2025
Copy link
Contributor

@s0600204 s0600204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, and welcome to the project from a (fairly) long-time contributor!

Fiirstly, thank you for looking into this. Speaking anecdotally: over the past couple of years I've been involved in shows that have wanted to use video projection, QLab has just not wanted to behave itself (stuttering and juddering, despite running on a computer that can play the files just fine via QuickTime), ShowCueSystems hasn't worked reliably either, and all I've been able to do is shrug as my weapon of choice (LiSP) doesn't support outputting video at all. (And it seems like I cannot get my head round GStreamer at all, which is why I never got anywhere with this myself.) So seeing some progress in this area is much appreciated.

So, I don't have Wayland setup on the computer I use day-to-day, so this immediately doesn't work for me (the cue is marked as "playing" in the UI but doesn't progress and no audio is heard). But that's a me problem, rather than a you problem (And something I probably should look into, if only to know how to get it working on my "show" computer). My point is, I'd be happy to see other sinks implemented, if you get the time.

Comment on lines +85 to +97
def loadSettings(self, settings):
device = settings.get(
"device",
GstBackend.Config.get("wayland_device", "wayland-0"),
)

self.deviceComboBox.setCurrentText(
self.devices.get(device, self.devices.get('wayland-0'))
)

self.fullScreen.setChecked(
GstBackend.Config.get("fullscreen", True)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GstBackend.Config contains the contents of the application-level GstBackend config, not the current settings of this element on a given cue - that's passed via the settings object.

Suggested change
def loadSettings(self, settings):
device = settings.get(
"device",
GstBackend.Config.get("wayland_device", "wayland-0"),
)
self.deviceComboBox.setCurrentText(
self.devices.get(device, self.devices.get('wayland-0'))
)
self.fullScreen.setChecked(
GstBackend.Config.get("fullscreen", True)
)
def loadSettings(self, settings):
self.deviceComboBox.setCurrentText(
self.devices.get(
settings.get("device", list(self.devices.keys())[0])
)
)
self.fullScreen.setChecked(settings.get("fullscreen", True))

Comment on lines +34 to +35
device = GstProperty("wayland_sink", "display", default="wayland-0")
fullscreen = GstProperty("wayland_sink", "fullscreen", default=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be class properties, not instance variables.



class WaylandSink(GstMediaElement):
ElementType = ElementType.Output
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. if a user opens a newly created Media (Video) Cue, then opens the "Edit Pipeline" dialog, it is possible to specify the "Wayland Video" element as the Output (instead of "System Out", "ALSA Out", ...), leading to (once the dialog closed) "Wayland Video" element appearing twice in the pipeline.

  2. if a user removes the "Wayland Video" element from the pipeline of a Media (Video) Cue, then closes the "Edit Pipeline" dialog, upon reopening it, it is no longer possible to add the "Wayland Video" element back.

Both can be resolved by setting this to ElementType.Plugin.

Admittedly this is perhaps conceptually wrong, but it works!

"_enabled_": true,
"audio-pipeline": ["Volume", "Equalizer10", "DbMeter", "AutoSink"],
"video-pipeline": ["Volume", "DbMeter", "Equalizer10", "WaylandSink", "AutoSink"],
"pipeline": ["Volume", "Equalizer10", "DbMeter", "AutoSink"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pipeline key is still read and written by the application preferences dialog ("File" > "Preferences" then "Plugins" > "GstBackend"), where it is intended to be used to allow users to specifiy what the default pipeline for new Media (Audio) Cues should be.

However, as this key is no longer used by the GstMediaCue class to build the initial pipeline, this no longer works as intended.

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

Successfully merging this pull request may close these issues.

3 participants