playbin3 in python3 Gtk with Gst.ElementFactory
The audio stream with audio description is always automatically selected.
Is there a flag to prevent that?
I am currently using the flag 0x13 so that no subtitles are displayed.
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import Gst, GObject, Gtk, Gdk
from gi.repository import GstVideo
import warnings
warnings.simplefilter("ignore")
channel_url = "https://mdrtvthhls.akamaized.net/hls/live/2016880/mdrtvth/master.m3u8"
class MainWin(object):
def __init__(self):
self.is_playing = False
self.tv_icon = "video-display"
self.window = Gtk.Window()
self.window.set_icon_name("video-display")
self.window.set_keep_above(True)
self.window.set_title("TV-Player")
self.window.resize(427, 240)
screen = Gdk.Screen.get_default()
monitor = Gdk.Screen.get_primary_monitor(screen)
monitor_n_geo = screen.get_monitor_geometry(monitor)
print(f"Monitor Resolution: {monitor_n_geo.width}x{monitor_n_geo.height}")
self.window.move(monitor_n_geo.width - 427, monitor_n_geo.height - 240)
self.window.connect("destroy", Gtk.main_quit, "WM destroy")
vbox = Gtk.VBox()
self.window.add(vbox)
self.movie_window = Gtk.DrawingArea()
vbox.add(self.movie_window)
self.window.show_all()
self.player = Gst.ElementFactory.make("playbin3", "player")
self.player.set_property("flags", 0x13) # to prevent subtitle
self.player.set_property("volume", 1.0)
bus = self.player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
bus.connect("message", self.on_message)
bus.connect("sync-message::element", self.on_sync_message)
self.window.connect('delete-event', self.on_close)
self.window.connect("key-press-event",self.on_key_press_event)
self.window.connect("window-state-event", self.on_window_state_event)
self.player.set_state(Gst.State.NULL)
self.player.set_property("uri", channel_url)
self.player.set_state(Gst.State.PLAYING)
self.window.set_title("MDR")
self.is_playing = True
def fullscreen_mode(self):
if self.__is_fullscreen:
self.window.unfullscreen()
else:
self.window.fullscreen()
def on_key_press_event(self, widget, event):
key = Gdk.keyval_name(event.keyval)
if key == "q":
self.player.set_state(Gst.State.NULL)
print("player stopped")
self.window.destroy()
if key == "f":
self.fullscreen_mode()
if key == "1":
self.playTV(None, 0)
if key == "space":
self.pauseTV()
if key == "m":
if self.player.get_property("mute") == False:
self.player.set_property("mute", True)
print("audio muted")
else:
self.player.set_property("mute", False)
print("audio unmuted")
if key == "Down":
v = self.player.get_property("volume")
self.player.set_property("volume", v - 0.1)
print(f"Volume: {v:.2f}")
if key == "Up":
v = self.player.get_property("volume")
self.player.set_property("volume", v + 0.1)
print(f"Volume: {v:.2f}")
def pauseTV(self, *args):
if self.is_playing:
self.player.set_state(Gst.State.PAUSED)
self.is_playing = False
else:
self.player.set_state(Gst.State.PLAYING)
self.is_playing = True
def on_close(self, event, *args):
self.player.set_state(Gst.State.NULL)
print("player stopped")
self.window.destroy()
def on_message(self, bus, message):
t = message.type
if t == Gst.MessageType.EOS:
self.player.set_state(Gst.State.NULL)
elif t == Gst.MessageType.ERROR:
self.player.set_state(Gst.State.NULL)
err, debug = message.parse_error()
print ("Error: %s" % err, debug)
def on_sync_message(self, bus, message):
if message.get_structure().get_name() == 'prepare-window-handle':
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True)
imagesink.set_window_handle(self.movie_window.get_property('window').get_xid())
def on_window_state_event(self, widget, ev):
self.__is_fullscreen = bool(ev.new_window_state & Gdk.WindowState.FULLSCREEN)
Gdk.threads_init()
GObject.threads_init()
Gst.init(None)
MainWin()
Gtk.main()
The content of the m3u8
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=1672000,AVERAGE-BANDWIDTH=1460800,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=50.000,AUDIO="program_audio",SUBTITLES="subs"
master_640x360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=6520800,AVERAGE-BANDWIDTH=5640800,CODECS="avc1.64002a,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=50.000,AUDIO="program_audio",SUBTITLES="subs"
master_1920x1080.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4224000,AVERAGE-BANDWIDTH=3660800,CODECS="avc1.640020,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=50.000,AUDIO="program_audio",SUBTITLES="subs"
master_1280x720.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2182400,AVERAGE-BANDWIDTH=1900800,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=960x540,FRAME-RATE=50.000,AUDIO="program_audio",SUBTITLES="subs"
master_960x540.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1034000,AVERAGE-BANDWIDTH=910800,CODECS="avc1.4d401e,mp4a.40.2",RESOLUTION=480x270,FRAME-RATE=50.000,AUDIO="program_audio",SUBTITLES="subs"
master_480x270.m3u8
#EXT-X-MEDIA:TYPE=SUBTITLES,NAME="Untertitel",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="de",GROUP-ID="subs",URI="master_cc.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,LANGUAGE="de",NAME="Deutsch",AUTOSELECT=YES,DEFAULT=YES,GROUP-ID="program_audio",URI="master_audio1.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,LANGUAGE="de",NAME="klare Sprache",AUTOSELECT=YES,DEFAULT=NO,GROUP-ID="program_audio",URI="master_audio2.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,LANGUAGE="de",NAME="Audiodescription",AUTOSELECT=YES,DEFAULT=NO,GROUP-ID="program_audio",URI="master_audio3.m3u8"