[media] Made the youtube-dl executable configurable.

`youtube-dl` is mostly dead and there are several forks available, thus
we need to give the user the ability to pick which `youtube-dl`
executable fork they want to use.

Among these, `yt-dlp` is probably the most maintained today and it's
also included in many default repos, so it's been added as an extra
requirement for all the media plugins.

Closes: #268
This commit is contained in:
Fabio Manganiello 2023-11-04 11:57:09 +01:00
parent 5478b90288
commit 44d4ae2a96
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
7 changed files with 50 additions and 41 deletions

View file

@ -14,6 +14,7 @@ import requests
from platypush.config import Config from platypush.config import Config
from platypush.context import get_plugin, get_backend from platypush.context import get_plugin, get_backend
from platypush.plugins import Plugin, action from platypush.plugins import Plugin, action
from platypush.utils import get_default_downloads_dir
class PlayerState(enum.Enum): class PlayerState(enum.Enum):
@ -147,7 +148,9 @@ class MediaPlugin(Plugin, ABC):
env: Optional[Dict[str, str]] = None, env: Optional[Dict[str, str]] = None,
volume: Optional[Union[float, int]] = None, volume: Optional[Union[float, int]] = None,
torrent_plugin: str = 'torrent', torrent_plugin: str = 'torrent',
youtube_format: str = 'best', # youtube_format: Optional[str] = 'bv*[height<=?1080][ext=mp4]+bestaudio/best',
youtube_format: Optional[str] = 'best[height<=?1080][ext=mp4]',
youtube_dl: str = 'yt-dlp',
**kwargs, **kwargs,
): ):
""" """
@ -169,10 +172,17 @@ class MediaPlugin(Plugin, ABC):
- ``webtorrent`` - torrent support over webtorrent (unstable) - ``webtorrent`` - torrent support over webtorrent (unstable)
:param youtube_format: Select the preferred video/audio format for :param youtube_format: Select the preferred video/audio format for
YouTube videos (default: ``best``). See the `youtube-dl YouTube videos. See the `youtube-dl documentation
documentation
<https://github.com/ytdl-org/youtube-dl#format-selection>`_ for more <https://github.com/ytdl-org/youtube-dl#format-selection>`_ for more
info on supported formats. info on supported formats. Default:
``bv*[height<=?1080][ext=mp4]+bestaudio/best`` - select the best
mp4 video with a resolution <= 1080p, and the best audio format.
:param youtube_dl: Path to the ``youtube-dl`` executable, used to
extract information from YouTube videos and other media platforms.
Default: ``yt-dlp``. The default has changed from ``youtube-dl`` to
the ``yt-dlp`` fork because the former is badly maintained and its
latest release was pushed in 2021.
""" """
super().__init__(**kwargs) super().__init__(**kwargs)
@ -216,16 +226,12 @@ class MediaPlugin(Plugin, ABC):
os.path.expanduser( os.path.expanduser(
download_dir download_dir
or player_config.get('download_dir') or player_config.get('download_dir')
or os.path.join( or get_default_downloads_dir()
(os.path.expanduser('~') or self._env.get('HOME') or '/'),
'Downloads',
)
) )
) )
if not os.path.isdir(self.download_dir):
os.makedirs(self.download_dir, exist_ok=True) os.makedirs(self.download_dir, exist_ok=True)
self._ytdl = youtube_dl
self.media_dirs.add(self.download_dir) self.media_dirs.add(self.download_dir)
self.volume = volume self.volume = volume
self._videos_queue = [] self._videos_queue = []
@ -468,7 +474,7 @@ class MediaPlugin(Plugin, ABC):
self.logger.exception(e) self.logger.exception(e)
results = [ results = [
{'type': media_type, **result} {**result, 'type': media_type}
for media_type in self._supported_media_types for media_type in self._supported_media_types
for result in results.get(media_type, []) for result in results.get(media_type, [])
if media_type in results if media_type in results
@ -580,17 +586,20 @@ class MediaPlugin(Plugin, ABC):
def get_youtube_video_url(self, url, youtube_format: Optional[str] = None): def get_youtube_video_url(self, url, youtube_format: Optional[str] = None):
ytdl_cmd = [ ytdl_cmd = [
'youtube-dl', self._ytdl,
'-f', *(
youtube_format or self.youtube_format, ['-f', youtube_format or self.youtube_format]
if youtube_format or self.youtube_format
else []
),
'-g', '-g',
url, url,
] ]
self.logger.info('Executing command %s', ' '.join(ytdl_cmd)) self.logger.info('Executing command %s', ' '.join(ytdl_cmd))
with subprocess.Popen(ytdl_cmd, stdout=subprocess.PIPE) as youtube_dl: with subprocess.Popen(ytdl_cmd, stdout=subprocess.PIPE) as ytdl:
url = youtube_dl.communicate()[0].decode().strip() url = ytdl.communicate()[0].decode().strip()
youtube_dl.wait() ytdl.wait()
return url return url
@ -628,9 +637,7 @@ class MediaPlugin(Plugin, ABC):
if m: if m:
url = f'https://www.youtube.com/watch?v={m.group(1)}' url = f'https://www.youtube.com/watch?v={m.group(1)}'
with subprocess.Popen( with subprocess.Popen([self._ytdl, '-j', url], stdout=subprocess.PIPE) as proc:
['youtube-dl', '-j', url], stdout=subprocess.PIPE
) as proc:
if proc.stdout is None: if proc.stdout is None:
return None return None

View file

@ -3,11 +3,15 @@ manifest:
install: install:
apk: apk:
- mplayer - mplayer
- yt-dlp
apt: apt:
- mplayer - mplayer
- yt-dlp
dnf: dnf:
- mplayer - mplayer
- yt-dlp
pacman: pacman:
- mplayer - mplayer
- yt-dlp
package: platypush.plugins.media.mplayer package: platypush.plugins.media.mplayer
type: plugin type: plugin

View file

@ -4,15 +4,20 @@ manifest:
apk: apk:
- mpv - mpv
- py3-mpv - py3-mpv
- yt-dlp
apt: apt:
- mpv - mpv
- python3-mpv - python3-mpv
- yt-dlp
dnf: dnf:
- mpv - mpv
- yt-dlp
pacman: pacman:
- mpv - mpv
- python-mpv - python-mpv
- yt-dlp
pip: pip:
- python-mpv - python-mpv
- yt-dlp
package: platypush.plugins.media.mpv package: platypush.plugins.media.mpv
type: plugin type: plugin

View file

@ -3,7 +3,9 @@ manifest:
install: install:
pip: pip:
- omxplayer-wrapper - omxplayer-wrapper
- yt-dlp
apt: apt:
- omxplayer - omxplayer
- yt-dlp
package: platypush.plugins.media.omxplayer package: platypush.plugins.media.omxplayer
type: plugin type: plugin

View file

@ -4,15 +4,20 @@ manifest:
apk: apk:
- vlc - vlc
- py3-vlc - py3-vlc
- yt-dlp
apt: apt:
- vlc - vlc
- python3-vlc - python3-vlc
- yt-dlp
dnf: dnf:
- vlc - vlc
- python3-vlc - python3-vlc
- yt-dlp
pacman: pacman:
- vlc - vlc
- yt-dlp
pip: pip:
- python-vlc - python-vlc
- yt-dlp
package: platypush.plugins.media.vlc package: platypush.plugins.media.vlc
type: plugin type: plugin

View file

@ -2,28 +2,14 @@ manifest:
events: {} events: {}
install: install:
apk: apk:
- py3-google-api-python-client - yt-dlp
- py3-google-auth
- py3-oauth2client
- py3-httplib2
apt: apt:
- python3-google-auth - yt-dlp
- python3-oauth2client
- python3-httplib2
dnf: dnf:
- python-google-api-client - yt-dlp
- python-google-auth
- python-oauth2client
- python-httplib2
pacman: pacman:
- python-google-api-python-client - yt-dlp
- python-google-auth
- python-oauth2client
- python-httplib2
pip: pip:
- google-api-python-client - yt-dlp
- google-auth
- oauth2client
- httplib2
package: platypush.plugins.youtube package: platypush.plugins.youtube
type: plugin type: plugin

View file

@ -118,7 +118,7 @@ setup(
# Support for OMXPlayer plugin # Support for OMXPlayer plugin
'omxplayer': ['omxplayer-wrapper'], 'omxplayer': ['omxplayer-wrapper'],
# Support for YouTube # Support for YouTube
'youtube': ['youtube-dl'], 'youtube': ['yt-dlp'],
# Support for torrents download # Support for torrents download
'torrent': ['python-libtorrent'], 'torrent': ['python-libtorrent'],
# Generic support for cameras # Generic support for cameras