Only resolve youtubelinks when playing

This makes everything ALOT faster
main
Micke Nordin 2 years ago
parent 094b25f8cb
commit cf54794220
Signed by: micke
GPG Key ID: 0DA0A7A5708FE257

@ -22,7 +22,6 @@ libgstreamer-plugins-bad1.0-0:amd64
libgstreamer-plugins-base1.0-0:amd64 libgstreamer-plugins-base1.0-0:amd64
libgstreamer-plugins-good1.0-0:amd64 libgstreamer-plugins-good1.0-0:amd64
libgstreamer1.0-0:amd64 libgstreamer1.0-0:amd64
libmpv1
python3-wxgtk-media4.0 python3-wxgtk-media4.0
python3-wxgtk4.0 python3-wxgtk4.0
python3-feedparser python3-feedparser

@ -1,2 +1,2 @@
pychromecast pychromecast
python-mpv youtube-search-python

@ -1,14 +1,11 @@
import threading
import feedparser import feedparser
import wx import wx
import time
import youtube_dl
from Channel import Channel from Channel import Channel
from Items import Item from Items import Item
from Utils import (add_video, get_default_logo, get_latest_video_timestamp, hash_string, from Utils import (add_video, get_default_logo, get_latest_video_timestamp, hash_string,
make_bitmap_from_url, video_exists) make_bitmap_from_url, video_exists)
#from youtubesearchpython.search import VideosSearch
class YouTube(Channel): class YouTube(Channel):
@ -22,11 +19,6 @@ class YouTube(Channel):
def parse_feed(self) -> None: def parse_feed(self) -> None:
feed = feedparser.parse(self.get_feed()) feed = feedparser.parse(self.get_feed())
ydl_opts = {
'format':
'worstvideo[ext=mp4]+worstaudio[ext=m4a]/worstvideo+worstaudio',
'container': 'webm_dash',
}
entries = feed['entries'] entries = feed['entries']
for entry in entries: for entry in entries:
@ -36,22 +28,11 @@ class YouTube(Channel):
title = str(entry['title']) title = str(entry['title'])
thumbnail_link = str(entry['media_thumbnail'][0]['url']) thumbnail_link = str(entry['media_thumbnail'][0]['url'])
description = str(entry['description']) description = str(entry['description'])
link = '' #video_search = VideosSearch(entry['id'], limit = 1).result()['result'][0]
with youtube_dl.YoutubeDL(ydl_opts) as ydl: resolved_link = entry['link']
try: print(resolved_link)
video = ydl.extract_info(entry['link'], download=False)
for form in video['formats']: # type: ignore
if form['height']:
if form['height'] < 480 and form[
'acodec'] != 'none':
link = form['url']
except youtube_dl.utils.ExtractorError and youtube_dl.utils.DownloadError:
pass
resolved_link = link
published_parsed = entry['published_parsed'] published_parsed = entry['published_parsed']
if not resolved_link: if not resolved_link:
continue continue

@ -11,9 +11,12 @@ from urllib.parse import urlparse
import requests import requests
import wx import wx
import youtube_dl
from Items import Item from Items import Item
HEIGHT = int(1440 / 2)
BTN_HEIGHT = 40
SIZE = wx.Size(100, 68) SIZE = wx.Size(100, 68)
MYPATH = path.dirname(path.abspath(__file__)) MYPATH = path.dirname(path.abspath(__file__))
SCREEN_WIDTH = int(720 / 2) SCREEN_WIDTH = int(720 / 2)
@ -129,9 +132,10 @@ def get_latest(provider_id: str,
pass pass
return videos return videos
def get_latest_video_timestamp(channel_id: str, def get_latest_video_timestamp(channel_id: str,
basepath: str = BASEPATH, basepath: str = BASEPATH,
filename: str = DB_FILE_NAME) -> datetime: filename: str = DB_FILE_NAME) -> datetime:
fullpath = path.join(basepath, filename) fullpath = path.join(basepath, filename)
try: try:
con = sqlite3.connect(fullpath) con = sqlite3.connect(fullpath)
@ -145,6 +149,7 @@ def get_latest_video_timestamp(channel_id: str,
pass pass
return datetime.fromtimestamp(timestamp) return datetime.fromtimestamp(timestamp)
def get_subscriptions(basepath: str = BASEPATH, def get_subscriptions(basepath: str = BASEPATH,
filename: str = DB_FILE_NAME) -> list[tuple[str, str]]: filename: str = DB_FILE_NAME) -> list[tuple[str, str]]:
subscriptions = list() subscriptions = list()
@ -223,17 +228,20 @@ def make_sized_button(parent_pnl: wx.Panel, bitmap_or_str: Union[wx.Bitmap,
else: else:
bitmap = bitmap_or_str bitmap = bitmap_or_str
btn_style = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT btn_style = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT
btn_logo = wx.BitmapButton(parent_pnl, wx.ID_ANY, bitmap, style=btn_style) btn_logo = wx.BitmapButton(parent_pnl,
btn_logo.SetMinSize(SIZE) wx.ID_ANY,
bitmap,
style=btn_style,
size=bitmap.GetSize())
btn_logo.SetToolTip(text) btn_logo.SetToolTip(text)
btn_sizer.Add(btn_logo, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 1) btn_sizer.Add(btn_logo, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP, 1)
btn_text = wx.Button(parent_pnl, btn_text = wx.Button(parent_pnl,
wx.ID_ANY, wx.ID_ANY,
text, text,
style=wx.BORDER_NONE | wx.BU_AUTODRAW) style=wx.BORDER_NONE | wx.BU_AUTODRAW,
btn_text.SetMinSize( size=wx.Size(SCREEN_WIDTH - SIZE.GetWidth(),
wx.Size(SCREEN_WIDTH - SIZE.GetWidth(), SIZE.GetHeight())) SIZE.GetHeight()))
btn_text.SetToolTip(text) btn_text.SetToolTip(text)
btn_sizer.Add(btn_text, 0, wx.BOTTOM | wx.RIGHT | wx.TOP | wx.EXPAND, 1) btn_sizer.Add(btn_text, 0, wx.BOTTOM | wx.RIGHT | wx.TOP | wx.EXPAND, 1)
parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_logo) parent_pnl.Bind(wx.EVT_BUTTON, callback, btn_logo)
@ -307,6 +315,27 @@ def resolve_svt_channel(svt_id: str) -> dict:
return channels[svt_id] return channels[svt_id]
def resolve_youtube_link(link):
ydl_opts = {
'format':
'worstvideo[ext=mp4]+worstaudio[ext=m4a]/worstvideo+worstaudio',
'container': 'webm dash'
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
try:
video = ydl.extract_info(link, download=False)
for form in video['formats']: # type: ignore
if form['height']:
if form['height'] < 480 and form['acodec'] != 'none':
link = form['url']
except youtube_dl.utils.ExtractorError and youtube_dl.utils.DownloadError:
pass
return link
def video_exists(video_id: str, def video_exists(video_id: str,
channel_id: str, channel_id: str,
basepath: str = BASEPATH, basepath: str = BASEPATH,

@ -1,20 +1,19 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import mpv
import json
import os import os
import threading import threading
import time import time
from typing import Callable from typing import Callable
from urllib.parse import urlparse
import pychromecast import pychromecast
import wx import wx
import wx.lib.scrolledpanel as scrolled import wx.lib.scrolledpanel as scrolled
import wx.media import wx.media
from youtubesearchpython import ChannelsSearch
from Channel import SVT, YouTube from Channel import SVT, YouTube
from ChannelProvider import ChannelProvider from ChannelProvider import ChannelProvider
from Utils import get_subscriptions, import_from_newpipe, make_sized_button from Utils import (get_subscriptions, import_from_newpipe, make_sized_button,
resolve_youtube_link)
WIDTH = int(720 / 2) WIDTH = int(720 / 2)
HEIGHT = int(1440 / 2) HEIGHT = int(1440 / 2)
@ -25,6 +24,9 @@ SCROLL_RATE = 5
BM_BTN_STYLE = wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP BM_BTN_STYLE = wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.TOP
BTN_STYLE = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT BTN_STYLE = wx.BORDER_NONE | wx.BU_AUTODRAW | wx.BU_EXACTFIT | wx.BU_NOTEXT
FLAGS = wx.SizerFlags()
FLAGS.Center()
class Cast(wx.Frame): class Cast(wx.Frame):
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
@ -35,6 +37,7 @@ class Cast(wx.Frame):
super().__init__(*args, **kw) super().__init__(*args, **kw)
self.m_selected_chromecast = None self.m_selected_chromecast = None
self.SetSizeHints(WIDTH, HEIGHT, maxW=WIDTH) self.SetSizeHints(WIDTH, HEIGHT, maxW=WIDTH)
self.m_style = self.GetWindowStyle()
self.m_chromecast_thr = threading.Thread(target=self.get_chromecasts, self.m_chromecast_thr = threading.Thread(target=self.get_chromecasts,
args=(), args=(),
kwargs={}) kwargs={})
@ -46,8 +49,6 @@ class Cast(wx.Frame):
self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True) self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True)
self.m_panel.SetSizer(self.m_sizer) self.m_panel.SetSizer(self.m_sizer)
self.m_providers: list[ChannelProvider] = self.get_providers() self.m_providers: list[ChannelProvider] = self.get_providers()
# self.m_selected_channel = None
# self.m_selected_provider_index = None
self.show_provider_list(None) self.show_provider_list(None)
def add_back_button(self, callback: Callable) -> None: def add_back_button(self, callback: Callable) -> None:
@ -58,6 +59,31 @@ class Cast(wx.Frame):
backbtn.Bind(wx.EVT_BUTTON, callback) backbtn.Bind(wx.EVT_BUTTON, callback)
self.m_sizer.Add(backbtn) self.m_sizer.Add(backbtn)
def add_youtube_buttons(self) -> None:
def search_callback(event, text: wx.TextCtrl) -> None:
reply = text.GetLineText(0)
text.Clear()
channels_search = ChannelsSearch(reply,
limit=1).result()['result'][0]
print(channels_search)
text: wx.TextCtrl = wx.TextCtrl(self.m_panel, size=(WIDTH, BTN_HEIGHT))
self.m_sizer.Add(text)
searchbtn = wx.Button(self.m_panel,
-1,
label="Search",
size=(WIDTH, BTN_HEIGHT))
self.m_sizer.Add(searchbtn)
searchbtn.Bind(
wx.EVT_BUTTON,
lambda event, textctl=text: search_callback(event, textctl))
importbtn = wx.Button(self.m_panel,
-1,
label="Import from NewPipe",
size=(WIDTH, BTN_HEIGHT))
importbtn.Bind(wx.EVT_BUTTON, lambda event: self.show_importer(event))
self.m_sizer.Add(importbtn)
def get_chromecasts(self) -> None: def get_chromecasts(self) -> None:
""" """
[TODO:description] [TODO:description]
@ -66,6 +92,71 @@ class Cast(wx.Frame):
""" """
self.m_chromecasts, self.m_browser = pychromecast.get_chromecasts() self.m_chromecasts, self.m_browser = pychromecast.get_chromecasts()
def get_player_controls(self, channel_index: int, uri: str) -> wx.BoxSizer:
inner_sizer = wx.BoxSizer(wx.HORIZONTAL)
play_button = wx.Button(self.m_panel,
-1,
"Play",
size=(WIDTH / 4, BTN_HEIGHT))
pause_button = wx.Button(self.m_panel,
-1,
"Pause",
size=(WIDTH / 4, BTN_HEIGHT))
back_button = wx.Button(self.m_panel,
-1,
"Back",
size=(WIDTH / 4, BTN_HEIGHT))
back_button.Bind(
wx.EVT_BUTTON,
lambda event, cindex=channel_index: self.show_video_list(
event, cindex),
)
inner_sizer.Add(play_button, FLAGS)
inner_sizer.Add(pause_button, FLAGS)
inner_sizer.Add(back_button, FLAGS)
if not self.m_chromecast_thr.is_alive(
) and not self.m_selected_chromecast:
chromecast_button = wx.Button(self.m_panel,
-1,
"Cast",
size=(WIDTH / 4, BTN_HEIGHT))
chromecast_button.Bind(
wx.EVT_BUTTON,
lambda event, muri=uri, cindex=channel_index: self.
select_chromecast(event, muri, cindex),
)
inner_sizer.Add(chromecast_button, FLAGS)
elif self.m_selected_chromecast:
chromecast_button = wx.Button(self.m_panel,
-1,
"Stop Cast",
size=(WIDTH / 4, BTN_HEIGHT))
chromecast_button.Bind(
wx.EVT_BUTTON,
lambda event, muri=uri, cindex=channel_index: self.stop_callback(event, muri, cindex),
)
inner_sizer.Add(chromecast_button, FLAGS)
if self.m_selected_chromecast:
self.cast(wx.media.EVT_MEDIA_LOADED, uri),
play_button.Bind(wx.EVT_BUTTON, self.play_cast)
pause_button.Bind(wx.EVT_BUTTON, self.pause_cast)
else:
self.Bind(wx.media.EVT_MEDIA_LOADED,
lambda event: wx.Frame.SetFocus(self))
play_button.Bind(wx.EVT_BUTTON, self.play)
pause_button.Bind(wx.EVT_BUTTON, self.pause)
inner_sizer.Fit(self)
inner_sizer.Layout()
return inner_sizer
def get_providers(self) -> list[ChannelProvider]: def get_providers(self) -> list[ChannelProvider]:
providers = list() providers = list()
@ -88,8 +179,9 @@ class Cast(wx.Frame):
for channel in subscriptions: for channel in subscriptions:
channels.append(YouTube.YouTube(channel[0], channel[1])) channels.append(YouTube.YouTube(channel[0], channel[1]))
else: else:
channels.append(YouTube.YouTube("UCs6A_0Jm21SIvpdKyg9Gmxw", "Pine 64")) channels.append(
YouTube.YouTube("UCs6A_0Jm21SIvpdKyg9Gmxw", "Pine 64"))
youtube = ChannelProvider("YouTube", channels=channels) youtube = ChannelProvider("YouTube", channels=channels)
providers.append(youtube) providers.append(youtube)
@ -97,11 +189,14 @@ class Cast(wx.Frame):
def show_importer(self, _) -> None: def show_importer(self, _) -> None:
with wx.FileDialog(self, "Open Newpipe json file", wildcard="Json files (*.json)|*.json", with wx.FileDialog(self,
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as file_dialog: "Open Newpipe json file",
wildcard="Json files (*.json)|*.json",
style=wx.FD_OPEN
| wx.FD_FILE_MUST_EXIST) as file_dialog:
if file_dialog.ShowModal() == wx.ID_CANCEL: if file_dialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind return # the user changed their mind
# Proceed loading the file chosen by the user # Proceed loading the file chosen by the user
subfile = file_dialog.GetPath() subfile = file_dialog.GetPath()
@ -113,14 +208,14 @@ class Cast(wx.Frame):
yt_chan = YouTube.YouTube(channel[0], channel[1]) yt_chan = YouTube.YouTube(channel[0], channel[1])
yt_chan.refresh() yt_chan.refresh()
channels.append(yt_chan) channels.append(yt_chan)
# Index 1 is YouTube
self.m_providers[1].set_channels(channels) self.m_providers[1].set_channels(channels)
self.m_providers[1].make_latest() self.m_providers[1].make_latest()
self.show_channel_list(None,self.m_selected_provider_index) self.show_channel_list(None, self.m_selected_provider_index)
def show_provider_list(self, _) -> None: def show_provider_list(self, _) -> None:
self.m_sizer.Clear(delete_windows=True) self.m_sizer.Clear(delete_windows=True)
self.m_sizer = wx.BoxSizer(wx.VERTICAL) self.m_sizer = wx.BoxSizer(wx.VERTICAL)
# self.m_sizer.AddSpacer(SPACER_HEIGHT * 4)
closebtn = wx.Button(self.m_panel, closebtn = wx.Button(self.m_panel,
-1, -1,
label="Close", label="Close",
@ -154,9 +249,7 @@ class Cast(wx.Frame):
self.add_back_button(bck_callback) self.add_back_button(bck_callback)
if self.m_selected_provider.get_name() == "YouTube": if self.m_selected_provider.get_name() == "YouTube":
importbtn = wx.Button(self.m_panel, -1, label="Import from NewPipe",size=(WIDTH, BTN_HEIGHT)) self.add_youtube_buttons()
importbtn.Bind(wx.EVT_BUTTON, lambda event: self.show_importer(event))
self.m_sizer.Add(importbtn)
channel_index = 0 channel_index = 0
@ -175,37 +268,42 @@ class Cast(wx.Frame):
self.m_sizer.Fit(self) self.m_sizer.Fit(self)
self.m_sizer.Layout() self.m_sizer.Layout()
def show_video_list(self, _,channel_index) -> None: def show_video_list(self, _, channel_index) -> None:
self.Show() self.SetWindowStyle(self.m_style)
self.m_selected_channel = self.m_selected_provider.get_channel_by_index(channel_index) self.m_selected_channel = self.m_selected_provider.get_channel_by_index(
channel_index)
self.m_sizer.Clear(delete_windows=True) self.m_sizer.Clear(delete_windows=True)
self.m_sizer = wx.BoxSizer(wx.VERTICAL) self.m_sizer = wx.BoxSizer(wx.VERTICAL)
# self.m_sizer.AddSpacer(SPACER_HEIGHT * 4)
back_callback = lambda event: self.show_channel_list( back_callback = lambda event: self.show_channel_list(
event, self.m_selected_provider_index) event, self.m_selected_provider_index)
self.add_back_button(back_callback) self.add_back_button(back_callback)
if self.m_selected_provider.get_name() == 'YouTube' or (self.m_selected_provider.get_name() == 'SVT' and self.m_selected_channel.get_id() == 'feed'): if self.m_selected_provider.get_name() == 'YouTube' or (
self.m_selected_provider.get_name() == 'SVT'
and self.m_selected_channel.get_id() == 'feed'):
def refresh_callback(event): def refresh_callback(event):
if self.m_selected_provider.get_name() == 'YouTube' and channel_index == 0: if self.m_selected_provider.get_name(
) == 'YouTube' and channel_index == 0:
with wx.BusyInfo("Please wait, working..."): with wx.BusyInfo("Please wait, working..."):
for chan in self.m_selected_provider.get_channels(): for chan in self.m_selected_provider.get_channels():
chan.refresh() chan.refresh()
wait = 1 wait = 1
while wait > 0: while wait > 0:
wait = 0 wait = 0
for chan in self.m_selected_provider.get_channels(): for chan in self.m_selected_provider.get_channels(
):
if chan.wait(): if chan.wait():
wait += 1 wait += 1
time.sleep(1) time.sleep(1)
wx.GetApp().Yield() wx.GetApp().Yield()
else: else:
self.m_selected_channel.refresh() self.m_selected_channel.refresh()
self.show_video_list(event,channel_index) self.show_video_list(event, channel_index)
refreshbtn = wx.Button(self.m_panel, refreshbtn = wx.Button(self.m_panel,
-1, -1,
label="Refresh", label="Refresh",
size=(WIDTH, BTN_HEIGHT)) size=(WIDTH, BTN_HEIGHT))
refreshbtn.Bind(wx.EVT_BUTTON, refresh_callback) refreshbtn.Bind(wx.EVT_BUTTON, refresh_callback)
self.m_sizer.Add(refreshbtn) self.m_sizer.Add(refreshbtn)
@ -215,7 +313,6 @@ class Cast(wx.Frame):
time.sleep(1) time.sleep(1)
wx.GetApp().Yield() wx.GetApp().Yield()
btnindex = 0 btnindex = 0
for item in self.m_selected_channel.get_items(): # type: ignore for item in self.m_selected_channel.get_items(): # type: ignore
inner_sizer = wx.BoxSizer(wx.VERTICAL) inner_sizer = wx.BoxSizer(wx.VERTICAL)
@ -228,7 +325,8 @@ class Cast(wx.Frame):
btn = wx.BitmapButton(self.m_panel, btn = wx.BitmapButton(self.m_panel,
id=btnindex, id=btnindex,
bitmap=bitmap, bitmap=bitmap,
style=BM_BTN_STYLE) style=BM_BTN_STYLE,
size=bitmap.GetSize())
btn.Bind( btn.Bind(
wx.EVT_BUTTON, wx.EVT_BUTTON,
lambda event, link=item["link"], cindex=channel_index: self. lambda event, link=item["link"], cindex=channel_index: self.
@ -236,7 +334,10 @@ class Cast(wx.Frame):
) )
inner_sizer.Add(title) inner_sizer.Add(title)
inner_sizer.Add(btn) inner_sizer.Add(btn)
collapsable_pane = wx.CollapsiblePane(self.m_panel, wx.ID_ANY, "Details:") collapsable_pane = wx.CollapsiblePane(self.m_panel,
wx.ID_ANY,
"Details:",
size=(WIDTH, 20))
inner_sizer.Add(collapsable_pane, 0, wx.GROW | wx.ALL, 5) inner_sizer.Add(collapsable_pane, 0, wx.GROW | wx.ALL, 5)
pane_win = collapsable_pane.GetPane() pane_win = collapsable_pane.GetPane()
description = wx.StaticText(pane_win, -1, item["description"]) description = wx.StaticText(pane_win, -1, item["description"])
@ -245,6 +346,7 @@ class Cast(wx.Frame):
pane_sizer.Add(description, wx.GROW | wx.ALL, 2) pane_sizer.Add(description, wx.GROW | wx.ALL, 2)
pane_win.SetSizer(pane_sizer) pane_win.SetSizer(pane_sizer)
pane_sizer.SetSizeHints(pane_win) pane_sizer.SetSizeHints(pane_win)
def fit_and_layout(_): def fit_and_layout(_):
pane_sizer.Layout() pane_sizer.Layout()
pane_sizer.Fit(pane_win) pane_sizer.Fit(pane_win)
@ -253,7 +355,8 @@ class Cast(wx.Frame):
self.m_sizer.Fit(self) self.m_sizer.Fit(self)
self.m_sizer.Layout() self.m_sizer.Layout()
collapsable_pane.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, lambda event: fit_and_layout(event) ) collapsable_pane.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED,
lambda event: fit_and_layout(event))
#inner_sizer.Add(description) #inner_sizer.Add(description)
self.m_sizer.Add(inner_sizer) self.m_sizer.Add(inner_sizer)
self.m_sizer.AddSpacer(SPACER_HEIGHT) self.m_sizer.AddSpacer(SPACER_HEIGHT)
@ -263,84 +366,48 @@ class Cast(wx.Frame):
self.m_sizer.Fit(self) self.m_sizer.Fit(self)
self.m_sizer.Layout() self.m_sizer.Layout()
def show_player(self, _, uri, channel_index: int): def show_player(self, _, uri: str, channel_index: int):
""" """
Show the video player Show the video player
:param _ event: unused :param _ event: unused
:param uri str: the link to the video stream :param uri str: the link to the video stream
""" """
if 'youtube' in uri:
uri = resolve_youtube_link(uri)
self.m_sizer.Clear(delete_windows=True) self.m_sizer.Clear(delete_windows=True)
self.m_sizer = wx.BoxSizer(wx.VERTICAL) self.m_sizer = wx.BoxSizer(wx.VERTICAL)
inner_sizer = wx.BoxSizer(wx.HORIZONTAL) if not self.m_selected_chromecast:
self.m_control = wx.media.MediaCtrl( self.m_control = wx.media.MediaCtrl(
self.m_panel, self.m_panel,
size=(0,0), szBackend=wx.media.MEDIABACKEND_GSTREAMER,
szBackend=wx.media.MEDIABACKEND_GSTREAMER,
)
play_button = wx.Button(self.m_panel, -1, "Play")
pause_button = wx.Button(self.m_panel, -1, "Pause")
back_button = wx.Button(self.m_panel, -1, "Back")
back_button.Bind(
wx.EVT_BUTTON,
lambda event, cindex=channel_index: self.show_video_list(event, cindex),
)
self.m_control.Show()
self.m_sizer.Add(self.m_control)
inner_sizer.Add(play_button)
inner_sizer.Add(pause_button)
inner_sizer.Add(back_button)
if not self.m_chromecast_thr.is_alive(
) and not self.m_selected_chromecast:
chromecast_button = wx.Button(self.m_panel, -1, "Cast")
chromecast_button.Bind(
wx.EVT_BUTTON,
lambda event, muri=uri, cindex=channel_index: self.select_chromecast(event, muri, cindex),
) )
inner_sizer.Add(chromecast_button) self.m_sizer.Add(self.m_control, FLAGS)
self.m_sizer.Add(inner_sizer) self.Bind(wx.media.EVT_MEDIA_FINISHED,
lambda event: self.show_video_list(event, 0))
if self.m_selected_chromecast: self.Bind(wx.EVT_POWER_SUSPENDING,
self.Bind( lambda event: wx.EVT_POWER_SUSPENDING.Veto(event))
wx.media.EVT_MEDIA_LOADED, self.load_uri(uri)
lambda event, muri=uri: self.cast(event, muri), self.m_sizer.Add(self.get_player_controls(channel_index, uri), FLAGS)
) self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True)
play_button.Bind(wx.EVT_BUTTON, self.play_cast)
pause_button.Bind(wx.EVT_BUTTON, self.pause_cast)
else:
self.Bind(wx.media.EVT_MEDIA_LOADED, self.play)
play_button.Bind(wx.EVT_BUTTON, self.play)
pause_button.Bind(wx.EVT_BUTTON, self.pause)
self.Bind(wx.media.EVT_MEDIA_FINISHED, lambda event: self.show_video_list(event,0))
self.Bind(wx.EVT_POWER_SUSPENDING, lambda event: wx.EVT_POWER_SUSPENDING.Veto(event))
self.SetSizeHints(minW=WIDTH, minH=-1, maxH=HEIGHT)
self.load_uri(uri)
self.m_panel.SetSizer(self.m_sizer) self.m_panel.SetSizer(self.m_sizer)
self.m_sizer.Fit(self) self.m_sizer.Fit(self)
self.m_sizer.Layout() self.m_sizer.Layout()
self.Hide()
def select_chromecast(self, _, uri, channel_index): def select_chromecast(self, _, uri, channel_index):
self.m_sizer.Clear(delete_windows=True) self.m_sizer.Clear(delete_windows=True)
self.m_sizer = wx.BoxSizer(wx.VERTICAL) self.m_sizer = wx.BoxSizer(wx.VERTICAL)
# self.m_sizer.AddSpacer(SPACER_HEIGHT * 4)
cancel_btn = wx.Button(self.m_panel, cancel_btn = wx.Button(self.m_panel,
-1, -1,
"Cancel", "Cancel",
size=(WIDTH, BTN_HEIGHT), size=(WIDTH, BTN_HEIGHT))
style=wx.BU_EXACTFIT)
cancel_btn.Bind( cancel_btn.Bind(
wx.EVT_BUTTON, wx.EVT_BUTTON,
lambda event, cindex=channel_index: self.show_video_list( lambda event, cindex=channel_index: self.show_video_list(
event, cindex), event, cindex),
) )
self.m_sizer.Add(cancel_btn) #, wx.ALIGN_CENTER_VERTICAL) self.m_sizer.Add(cancel_btn)
for cast in self.m_chromecasts: for cast in self.m_chromecasts:
friendly_name = cast.cast_info.friendly_name friendly_name = cast.cast_info.friendly_name
@ -353,7 +420,7 @@ class Cast(wx.Frame):
lambda event, chromecast=cast, muri=uri, cindex=channel_index: lambda event, chromecast=cast, muri=uri, cindex=channel_index:
self.set_chromecast(event, chromecast, muri, cindex), self.set_chromecast(event, chromecast, muri, cindex),
) )
self.m_sizer.Add(btn) #, wx.ALIGN_CENTER_VERTICAL) self.m_sizer.Add(btn)
self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True) self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True)
self.m_panel.SetSizer(self.m_sizer) self.m_panel.SetSizer(self.m_sizer)
self.m_sizer.Fit(self) self.m_sizer.Fit(self)
@ -375,7 +442,6 @@ class Cast(wx.Frame):
while True: while True:
if player_state != cast.media_controller.status.player_state: if player_state != cast.media_controller.status.player_state:
player_state = cast.media_controller.status.player_state player_state = cast.media_controller.status.player_state
# print("Player state:", player_state)
if player_state == "PLAYING": if player_state == "PLAYING":
has_played = True has_played = True
@ -392,12 +458,32 @@ class Cast(wx.Frame):
def pause_cast(self, event): def pause_cast(self, event):
cast = self.m_selected_chromecast cast = self.m_selected_chromecast
cast.wait()
cast.media_controller.pause() cast.media_controller.pause()
def play_cast(self, event): def play_cast(self, event):
cast = self.m_selected_chromecast cast = self.m_selected_chromecast
cast.wait()
cast.media_controller.play() cast.media_controller.play()
def stop_cast(self, event):
cast = self.m_selected_chromecast
cast.wait()
cast.media_controller.pause()
time.sleep(2)
cast.media_controller.stop()
self.m_selected_chromecast = None
def stop_callback(self, event, uri: str, channel_index: int):
self.stop_cast(event)
self.m_sizer.Clear(delete_windows=True)
self.m_sizer = wx.BoxSizer(wx.VERTICAL)
self.m_sizer.Add(self.get_player_controls(channel_index, uri))
self.m_panel.SetupScrolling(rate_y=SCROLL_RATE, scrollToTop=True)
self.m_panel.SetSizer(self.m_sizer)
self.m_sizer.Fit(self)
self.m_sizer.Layout()
def load_uri(self, uri): def load_uri(self, uri):
self.m_control.LoadURI(uri) self.m_control.LoadURI(uri)

Loading…
Cancel
Save