Refactor to always have the playbin
This commit is contained in:
parent
18c1e6c4a7
commit
ed71a3a05c
1 changed files with 20 additions and 39 deletions
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, TypeVar, cast, overload
|
from typing import Any, cast, overload
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
|
@ -15,8 +15,6 @@ gi.require_version("Gst", "1.0")
|
||||||
gi.require_version("Pango", "1.0")
|
gi.require_version("Pango", "1.0")
|
||||||
from gi.repository import Gdk, Gio, Gst, Gtk, Pango # NOQA: E402
|
from gi.repository import Gdk, Gio, Gst, Gtk, Pango # NOQA: E402
|
||||||
|
|
||||||
_T = TypeVar("_T")
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(Gtk.ApplicationWindow):
|
class MainWindow(Gtk.ApplicationWindow):
|
||||||
file_info_label: Gtk.Label
|
file_info_label: Gtk.Label
|
||||||
|
@ -26,6 +24,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
selection_model: Gtk.SingleSelection
|
selection_model: Gtk.SingleSelection
|
||||||
video_widget: Gtk.Picture
|
video_widget: Gtk.Picture
|
||||||
pipeline: Gst.Pipeline
|
pipeline: Gst.Pipeline
|
||||||
|
playbin: Gst.Element
|
||||||
overlay_tick_callback_id: int
|
overlay_tick_callback_id: int
|
||||||
overlay_label: Gtk.Label
|
overlay_label: Gtk.Label
|
||||||
overlay_hide_time: float
|
overlay_hide_time: float
|
||||||
|
@ -94,12 +93,14 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
if not playbin:
|
if not playbin:
|
||||||
raise RuntimeError("Failed to create playbin element")
|
raise RuntimeError("Failed to create playbin element")
|
||||||
|
|
||||||
|
self.playbin = playbin
|
||||||
|
|
||||||
video_sink = Gst.ElementFactory.make("gtk4paintablesink", "gtk4paintablesink")
|
video_sink = Gst.ElementFactory.make("gtk4paintablesink", "gtk4paintablesink")
|
||||||
if not video_sink:
|
if not video_sink:
|
||||||
raise RuntimeError("Failed to create gtk4paintablesink element")
|
raise RuntimeError("Failed to create gtk4paintablesink element")
|
||||||
|
|
||||||
playbin.set_property("video-sink", video_sink)
|
self.playbin.set_property("video-sink", video_sink)
|
||||||
self.pipeline.add(playbin)
|
self.pipeline.add(self.playbin)
|
||||||
|
|
||||||
# Link video widget to sink
|
# Link video widget to sink
|
||||||
paintable = video_sink.get_property("paintable")
|
paintable = video_sink.get_property("paintable")
|
||||||
|
@ -154,24 +155,20 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
position = self._load_attribute("position", 0)
|
position = self._load_attribute("position", 0)
|
||||||
|
|
||||||
# Start playing the video
|
# Start playing the video
|
||||||
playbin = self.pipeline.get_by_name("playbin")
|
|
||||||
if not playbin:
|
|
||||||
return
|
|
||||||
|
|
||||||
full_path = os.path.abspath(file_item.full_path)
|
full_path = os.path.abspath(file_item.full_path)
|
||||||
playbin.set_property("uri", f"file://{full_path}")
|
self.playbin.set_property("uri", f"file://{full_path}")
|
||||||
|
|
||||||
track = self._load_attribute("subtitle_track", -2)
|
track = self._load_attribute("subtitle_track", -2)
|
||||||
|
|
||||||
if track >= 0:
|
if track >= 0:
|
||||||
flags = playbin.get_property("flags")
|
flags = self.playbin.get_property("flags")
|
||||||
flags |= 0x00000004 # TEXT flag
|
flags |= 0x00000004 # TEXT flag
|
||||||
playbin.set_property("flags", flags)
|
self.playbin.set_property("flags", flags)
|
||||||
playbin.set_property("current-text", track)
|
self.playbin.set_property("current-text", track)
|
||||||
elif track == -1:
|
elif track == -1:
|
||||||
flags = playbin.get_property("flags")
|
flags = self.playbin.get_property("flags")
|
||||||
flags &= ~0x00000004 # TEXT flag
|
flags &= ~0x00000004 # TEXT flag
|
||||||
playbin.set_property("flags", flags)
|
self.playbin.set_property("flags", flags)
|
||||||
|
|
||||||
if position:
|
if position:
|
||||||
# Pause and wait for it to complete.
|
# Pause and wait for it to complete.
|
||||||
|
@ -326,10 +323,6 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
def _seek_relative(self, offset: int) -> None:
|
def _seek_relative(self, offset: int) -> None:
|
||||||
"""Seek relative to current position by offset seconds"""
|
"""Seek relative to current position by offset seconds"""
|
||||||
|
|
||||||
playbin = self.pipeline.get_by_name("playbin")
|
|
||||||
if not playbin:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Query current position
|
# Query current position
|
||||||
success, current = self.pipeline.query_position(Gst.Format.TIME)
|
success, current = self.pipeline.query_position(Gst.Format.TIME)
|
||||||
if not success:
|
if not success:
|
||||||
|
@ -350,12 +343,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
def _get_subtitle_info(self, track_index: int) -> str:
|
def _get_subtitle_info(self, track_index: int) -> str:
|
||||||
"""Get subtitle track info including language if available"""
|
"""Get subtitle track info including language if available"""
|
||||||
|
|
||||||
playbin = self.pipeline.get_by_name("playbin")
|
|
||||||
if not playbin:
|
|
||||||
return str(track_index)
|
|
||||||
|
|
||||||
# Query the subtitle track's tags
|
# Query the subtitle track's tags
|
||||||
caps: Gst.TagList | None = playbin.emit("get-text-tags", track_index)
|
caps: Gst.TagList | None = self.playbin.emit("get-text-tags", track_index)
|
||||||
if not caps:
|
if not caps:
|
||||||
return str(track_index)
|
return str(track_index)
|
||||||
|
|
||||||
|
@ -365,10 +354,6 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
def _save_position(self) -> None:
|
def _save_position(self) -> None:
|
||||||
"""Save current playback position as xattr"""
|
"""Save current playback position as xattr"""
|
||||||
|
|
||||||
playbin = self.pipeline.get_by_name("playbin")
|
|
||||||
if not playbin:
|
|
||||||
return
|
|
||||||
|
|
||||||
success, position = self.pipeline.query_position(Gst.Format.TIME)
|
success, position = self.pipeline.query_position(Gst.Format.TIME)
|
||||||
success2, duration = self.pipeline.query_duration(Gst.Format.TIME)
|
success2, duration = self.pipeline.query_duration(Gst.Format.TIME)
|
||||||
|
|
||||||
|
@ -412,14 +397,10 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
def _cycle_subtitles(self) -> None:
|
def _cycle_subtitles(self) -> None:
|
||||||
"""Cycle through available subtitle tracks, including off state"""
|
"""Cycle through available subtitle tracks, including off state"""
|
||||||
|
|
||||||
playbin = self.pipeline.get_by_name("playbin")
|
|
||||||
if not playbin:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Get current flags and subtitle track
|
# Get current flags and subtitle track
|
||||||
flags = playbin.get_property("flags")
|
flags = self.playbin.get_property("flags")
|
||||||
current = playbin.get_property("current-text")
|
current = self.playbin.get_property("current-text")
|
||||||
n_text = playbin.get_property("n-text")
|
n_text = self.playbin.get_property("n-text")
|
||||||
|
|
||||||
if n_text == 0:
|
if n_text == 0:
|
||||||
self.show_overlay_text("No subtitles available")
|
self.show_overlay_text("No subtitles available")
|
||||||
|
@ -428,8 +409,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
# If subtitles are disabled, enable them and set to first track
|
# If subtitles are disabled, enable them and set to first track
|
||||||
if not (flags & 0x00000004): # TEXT flag
|
if not (flags & 0x00000004): # TEXT flag
|
||||||
flags |= 0x00000004
|
flags |= 0x00000004
|
||||||
playbin.set_property("flags", flags)
|
self.playbin.set_property("flags", flags)
|
||||||
playbin.set_property("current-text", 0)
|
self.playbin.set_property("current-text", 0)
|
||||||
track_info = self._get_subtitle_info(0)
|
track_info = self._get_subtitle_info(0)
|
||||||
self.show_overlay_text(f"Subtitle track: {track_info}")
|
self.show_overlay_text(f"Subtitle track: {track_info}")
|
||||||
self._save_attribute("subtitle_track", 0)
|
self._save_attribute("subtitle_track", 0)
|
||||||
|
@ -438,14 +419,14 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||||
# If we're on the last track, disable subtitles
|
# If we're on the last track, disable subtitles
|
||||||
if current >= n_text - 1:
|
if current >= n_text - 1:
|
||||||
flags &= ~0x00000004 # TEXT flag
|
flags &= ~0x00000004 # TEXT flag
|
||||||
playbin.set_property("flags", flags)
|
self.playbin.set_property("flags", flags)
|
||||||
self.show_overlay_text("Subtitles: Off")
|
self.show_overlay_text("Subtitles: Off")
|
||||||
self._save_attribute("subtitle_track", -1)
|
self._save_attribute("subtitle_track", -1)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Otherwise cycle to next track
|
# Otherwise cycle to next track
|
||||||
next_track = current + 1
|
next_track = current + 1
|
||||||
playbin.set_property("current-text", next_track)
|
self.playbin.set_property("current-text", next_track)
|
||||||
track_info = self._get_subtitle_info(next_track)
|
track_info = self._get_subtitle_info(next_track)
|
||||||
self.show_overlay_text(f"Subtitle track: {track_info}")
|
self.show_overlay_text(f"Subtitle track: {track_info}")
|
||||||
self._save_attribute("subtitle_track", next_track)
|
self._save_attribute("subtitle_track", next_track)
|
||||||
|
|
Loading…
Reference in a new issue