[#389] Fix for "Too many open files" media issue. #390
|
@ -31,7 +31,6 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
:param poll_interval: How often the plugin should poll for new/removed
|
||||
Chromecast devices (default: 30 seconds).
|
||||
"""
|
||||
|
||||
super().__init__(poll_interval=poll_interval, **kwargs)
|
||||
|
||||
self._is_local = False
|
||||
|
@ -42,11 +41,18 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
|
||||
def _get_chromecasts(self, *args, **kwargs):
|
||||
with self._refresh_lock:
|
||||
chromecasts = pychromecast.get_chromecasts(*args, **kwargs)
|
||||
ret = pychromecast.get_chromecasts(*args, **kwargs)
|
||||
|
||||
if isinstance(chromecasts, tuple):
|
||||
return chromecasts[0]
|
||||
return chromecasts
|
||||
if isinstance(ret, tuple):
|
||||
chromecasts, browser = ret
|
||||
if browser:
|
||||
browser.stop_discovery()
|
||||
if browser.zc:
|
||||
browser.zc.close()
|
||||
|
||||
return chromecasts
|
||||
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def _get_device_property(cc, prop: str):
|
||||
|
@ -58,14 +64,25 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
"""
|
||||
Convert a Chromecast object and its status to a dictionary.
|
||||
"""
|
||||
if hasattr(cc, 'cast_info'): # Newer PyChromecast API
|
||||
host = cc.cast_info.host
|
||||
port = cc.cast_info.port
|
||||
elif hasattr(cc, 'host'):
|
||||
host = getattr(cc, 'host', None)
|
||||
port = getattr(cc, 'port', None)
|
||||
elif hasattr(cc, 'uri'):
|
||||
host, port = cc.uri.split(':')
|
||||
else:
|
||||
raise RuntimeError('Invalid Chromecast object')
|
||||
|
||||
return {
|
||||
'type': cc.cast_type,
|
||||
'name': cc.name,
|
||||
'manufacturer': self._get_device_property(cc, 'manufacturer'),
|
||||
'model_name': cc.model_name,
|
||||
'uuid': str(cc.uuid),
|
||||
'address': cc.host if hasattr(cc, 'host') else cc.uri.split(':')[0],
|
||||
'port': cc.port if hasattr(cc, 'port') else int(cc.uri.split(':')[1]),
|
||||
'address': host,
|
||||
'port': port,
|
||||
'status': (
|
||||
{
|
||||
'app': {
|
||||
|
@ -284,24 +301,23 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
chromecast = chromecast or self.chromecast
|
||||
cast = self.get_chromecast(chromecast)
|
||||
|
||||
if cast.media_controller.is_paused:
|
||||
if cast.media_controller.status.player_is_paused:
|
||||
cast.media_controller.play()
|
||||
elif cast.media_controller.is_playing:
|
||||
elif cast.media_controller.status.player_is_playing:
|
||||
cast.media_controller.pause()
|
||||
|
||||
cast.wait()
|
||||
return self.status(chromecast=chromecast)
|
||||
|
||||
@action
|
||||
def stop(self, *_, chromecast: Optional[str] = None, **__):
|
||||
def stop(self, *_, chromecast: Optional[str] = None, **__): # type: ignore
|
||||
chromecast = chromecast or self.chromecast
|
||||
if not chromecast:
|
||||
return
|
||||
return None
|
||||
|
||||
cast = self.get_chromecast(chromecast)
|
||||
cast.media_controller.stop()
|
||||
cast.wait()
|
||||
|
||||
return self.status(chromecast=chromecast)
|
||||
|
||||
@action
|
||||
|
@ -347,51 +363,51 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
def is_playing(self, chromecast: Optional[str] = None, **_):
|
||||
return self.get_chromecast(
|
||||
chromecast or self.chromecast
|
||||
).media_controller.is_playing
|
||||
).media_controller.status.player_is_playing
|
||||
|
||||
@action
|
||||
def is_paused(self, chromecast: Optional[str] = None, **_):
|
||||
return self.get_chromecast(
|
||||
chromecast or self.chromecast
|
||||
).media_controller.is_paused
|
||||
).media_controller.status.player_is_paused
|
||||
|
||||
@action
|
||||
def is_idle(self, chromecast: Optional[str] = None):
|
||||
return self.get_chromecast(
|
||||
chromecast or self.chromecast
|
||||
).media_controller.is_idle
|
||||
).media_controller.status.player_is_idle
|
||||
|
||||
@action
|
||||
def list_subtitles(self, chromecast: Optional[str] = None):
|
||||
return self.get_chromecast(
|
||||
chromecast or self.chromecast
|
||||
).media_controller.subtitle_tracks
|
||||
).media_controller.status.subtitle_tracks
|
||||
|
||||
@action
|
||||
def enable_subtitles(
|
||||
self, chromecast: Optional[str] = None, track_id: Optional[str] = None, **_
|
||||
self, chromecast: Optional[str] = None, track_id: Optional[int] = None, **_
|
||||
):
|
||||
mc = self.get_chromecast(chromecast or self.chromecast).media_controller
|
||||
if track_id is not None:
|
||||
return mc.enable_subtitle(track_id)
|
||||
if mc.subtitle_tracks:
|
||||
return mc.enable_subtitle(mc.subtitle_tracks[0].get('trackId'))
|
||||
if mc.status.subtitle_tracks:
|
||||
return mc.enable_subtitle(mc.status.subtitle_tracks[0].get('trackId'))
|
||||
|
||||
@action
|
||||
def disable_subtitles(
|
||||
self, chromecast: Optional[str] = None, track_id: Optional[str] = None, **_
|
||||
self, chromecast: Optional[str] = None, track_id: Optional[int] = None, **_
|
||||
):
|
||||
mc = self.get_chromecast(chromecast or self.chromecast).media_controller
|
||||
if track_id:
|
||||
return mc.disable_subtitle(track_id)
|
||||
if mc.current_subtitle_tracks:
|
||||
return mc.disable_subtitle(mc.current_subtitle_tracks[0])
|
||||
if mc.status.current_subtitle_tracks:
|
||||
return mc.disable_subtitle(mc.status.current_subtitle_tracks[0])
|
||||
|
||||
@action
|
||||
def toggle_subtitles(self, chromecast: Optional[str] = None, **_):
|
||||
mc = self.get_chromecast(chromecast or self.chromecast).media_controller
|
||||
all_subs = mc.status.subtitle_tracks
|
||||
cur_subs = mc.status.status.current_subtitle_tracks
|
||||
cur_subs = mc.status.current_subtitle_tracks
|
||||
|
||||
if cur_subs:
|
||||
return self.disable_subtitles(chromecast, cur_subs[0])
|
||||
|
@ -511,7 +527,6 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
self,
|
||||
chromecast: Optional[str] = None,
|
||||
timeout: Optional[float] = None,
|
||||
blocking: bool = True,
|
||||
):
|
||||
"""
|
||||
Disconnect a Chromecast and wait for it to terminate
|
||||
|
@ -520,11 +535,9 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
the default configured Chromecast will be used.
|
||||
:param timeout: Number of seconds to wait for disconnection (default:
|
||||
None: block until termination).
|
||||
:param blocking: If set (default), then the code will wait until
|
||||
disconnection, otherwise it will return immediately.
|
||||
"""
|
||||
cast = self.get_chromecast(chromecast)
|
||||
cast.disconnect(timeout=timeout, blocking=blocking)
|
||||
cast.disconnect(timeout=timeout)
|
||||
|
||||
@action
|
||||
def join(self, chromecast: Optional[str] = None, timeout: Optional[float] = None):
|
||||
|
@ -550,17 +563,6 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
cast = self.get_chromecast(chromecast)
|
||||
cast.quit_app()
|
||||
|
||||
@action
|
||||
def reboot(self, chromecast: Optional[str] = None):
|
||||
"""
|
||||
Reboots the Chromecast
|
||||
|
||||
:param chromecast: Chromecast to cast to. If none is specified, then
|
||||
the default configured Chromecast will be used.
|
||||
"""
|
||||
cast = self.get_chromecast(chromecast)
|
||||
cast.reboot()
|
||||
|
||||
@action
|
||||
def set_volume(self, volume: float, chromecast: Optional[str] = None):
|
||||
"""
|
||||
|
@ -621,7 +623,7 @@ class MediaChromecastPlugin(MediaPlugin, RunnablePlugin):
|
|||
"""
|
||||
chromecast = chromecast or self.chromecast
|
||||
cast = self.get_chromecast(chromecast)
|
||||
cast.set_volume_muted(not cast.status.volume_muted)
|
||||
cast.set_volume_muted(not cast.media_controller.status.volume_muted)
|
||||
cast.wait()
|
||||
return self.status(chromecast=chromecast)
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# pylint: disable=too-few-public-methods
|
||||
class SubtitlesAsyncHandler:
|
||||
import logging
|
||||
|
||||
from pychromecast.controllers.media import MediaStatusListener
|
||||
|
||||
|
||||
class SubtitlesAsyncHandler(MediaStatusListener):
|
||||
"""
|
||||
This class is used to enable subtitles when the media is loaded.
|
||||
"""
|
||||
|
@ -8,9 +12,17 @@ class SubtitlesAsyncHandler:
|
|||
self.mc = mc
|
||||
self.subtitle_id = subtitle_id
|
||||
self.initialized = False
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def new_media_status(self, *_):
|
||||
if self.subtitle_id and not self.initialized:
|
||||
self.mc.update_status()
|
||||
self.mc.enable_subtitle(self.subtitle_id)
|
||||
self.initialized = True
|
||||
|
||||
def load_media_failed(self, queue_item_id: int, error_code: int) -> None:
|
||||
self.logger.warning(
|
||||
"Failed to load media with queue_item_id %d, error code: %d",
|
||||
queue_item_id,
|
||||
error_code,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue