Working in a buggy state... but more or less working
This commit is contained in:
parent
fc9b79172a
commit
15cc8f8147
4 changed files with 49 additions and 48 deletions
|
@ -37,6 +37,8 @@ import engineio
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from yaml import load, Loader
|
from yaml import load, Loader
|
||||||
|
|
||||||
|
from syng.player_libmpv import Player
|
||||||
|
|
||||||
from . import jsonencoder
|
from . import jsonencoder
|
||||||
from .entry import Entry
|
from .entry import Entry
|
||||||
from .sources import configure_sources, Source
|
from .sources import configure_sources, Source
|
||||||
|
@ -121,6 +123,7 @@ class Client:
|
||||||
self.sources = configure_sources(config["sources"])
|
self.sources = configure_sources(config["sources"])
|
||||||
self.state = State()
|
self.state = State()
|
||||||
self.currentLock = asyncio.Semaphore(0)
|
self.currentLock = asyncio.Semaphore(0)
|
||||||
|
self.player = Player()
|
||||||
self.register_handlers()
|
self.register_handlers()
|
||||||
|
|
||||||
def register_handlers(self) -> None:
|
def register_handlers(self) -> None:
|
||||||
|
@ -244,26 +247,7 @@ class Client:
|
||||||
:type entry: :py:class:`Entry`
|
:type entry: :py:class:`Entry`
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
background = Image.new("RGB", (1280, 720))
|
self.player.queue_next(entry)
|
||||||
subtitle: str = f"""1
|
|
||||||
00:00:00,00 --> 00:05:00,00
|
|
||||||
{entry.artist} - {entry.title}
|
|
||||||
{entry.performer}"""
|
|
||||||
with tempfile.NamedTemporaryFile() as tmpfile:
|
|
||||||
background.save(tmpfile, "png")
|
|
||||||
process = await asyncio.create_subprocess_exec(
|
|
||||||
"mpv",
|
|
||||||
tmpfile.name,
|
|
||||||
f"--image-display-duration={self.state.config['preview_duration']}",
|
|
||||||
"--sub-pos=50",
|
|
||||||
"--sub-file=-",
|
|
||||||
"--fullscreen",
|
|
||||||
self.state.config["mpv_options"],
|
|
||||||
stdin=asyncio.subprocess.PIPE,
|
|
||||||
stdout=asyncio.subprocess.PIPE,
|
|
||||||
stderr=asyncio.subprocess.PIPE,
|
|
||||||
)
|
|
||||||
await process.communicate(subtitle.encode())
|
|
||||||
|
|
||||||
async def handle_play(self, data: dict[str, Any]) -> None:
|
async def handle_play(self, data: dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -293,7 +277,9 @@ class Client:
|
||||||
self.state.current_source = self.sources[entry.source]
|
self.state.current_source = self.sources[entry.source]
|
||||||
if self.state.config["preview_duration"] > 0:
|
if self.state.config["preview_duration"] > 0:
|
||||||
await self.preview(entry)
|
await self.preview(entry)
|
||||||
await self.sources[entry.source].play(entry, self.state.config["mpv_options"])
|
await self.sources[entry.source].play(
|
||||||
|
entry, self.player, self.state.config["mpv_options"]
|
||||||
|
)
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
print_exc()
|
print_exc()
|
||||||
self.state.current_source = None
|
self.state.current_source = None
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from typing import Optional
|
from typing import Iterable, Optional
|
||||||
from qrcode.main import QRCode
|
from qrcode.main import QRCode
|
||||||
import mpv
|
import mpv
|
||||||
import os
|
import os
|
||||||
|
@ -64,16 +65,23 @@ class Player:
|
||||||
|
|
||||||
def queue_next(self, entry: Entry):
|
def queue_next(self, entry: Entry):
|
||||||
self.play_image(f"{__dirname__}/static/background20perc.png", 3)
|
self.play_image(f"{__dirname__}/static/background20perc.png", 3)
|
||||||
|
|
||||||
|
frame = sys._getframe()
|
||||||
|
stream_name = f"__python_mpv_play_generator_{hash(frame)}"
|
||||||
|
|
||||||
|
@self.mpv.python_stream(stream_name)
|
||||||
|
def preview() -> Iterable[bytes]:
|
||||||
subtitle: str = f"""1
|
subtitle: str = f"""1
|
||||||
00:00:00,00 --> 00:05:00,00
|
00:00:00,00 --> 00:05:00,00
|
||||||
{entry.artist} - {entry.title}
|
{entry.artist} - {entry.title}
|
||||||
{entry.performer}"""
|
{entry.performer}"""
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
|
yield subtitle.encode()
|
||||||
print(tmpfile.name)
|
preview.unregister()
|
||||||
tmpfile.write(subtitle.encode())
|
|
||||||
tmpfile.flush()
|
|
||||||
self.mpv.sub_pos = 50
|
self.mpv.sub_pos = 50
|
||||||
self.mpv.sub_add(tmpfile.name)
|
self.mpv.sub_add(f"python://{stream_name}")
|
||||||
|
|
||||||
|
self.mpv.wait_for_property("eof-reached")
|
||||||
|
|
||||||
def play_image(self, image: str, duration: int):
|
def play_image(self, image: str, duration: int):
|
||||||
self.mpv.image_display_duration = duration
|
self.mpv.image_display_duration = duration
|
||||||
|
@ -86,3 +94,4 @@ class Player:
|
||||||
self.mpv.pause = True
|
self.mpv.pause = True
|
||||||
self.mpv.play(video)
|
self.mpv.play(video)
|
||||||
self.mpv.pause = False
|
self.mpv.pause = False
|
||||||
|
self.mpv.wait_for_property("eof-reached")
|
||||||
|
|
|
@ -21,6 +21,8 @@ from typing import Tuple
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
from syng.player_libmpv import Player
|
||||||
|
|
||||||
|
|
||||||
from ..log import logger
|
from ..log import logger
|
||||||
from ..entry import Entry
|
from ..entry import Entry
|
||||||
|
@ -271,7 +273,7 @@ class Source(ABC):
|
||||||
|
|
||||||
self.downloaded_files[entry.ident].ready.set()
|
self.downloaded_files[entry.ident].ready.set()
|
||||||
|
|
||||||
async def play(self, entry: Entry, mpv_options: str) -> None:
|
async def play(self, entry: Entry, player: Player, mpv_options: str) -> None:
|
||||||
"""
|
"""
|
||||||
Play the entry.
|
Play the entry.
|
||||||
|
|
||||||
|
@ -302,13 +304,15 @@ class Source(ABC):
|
||||||
else self.extra_mpv_arguments
|
else self.extra_mpv_arguments
|
||||||
)
|
)
|
||||||
|
|
||||||
self.player = await self.play_mpv(
|
# self.player = await self.play_mpv(
|
||||||
self.downloaded_files[entry.ident].video,
|
# self.downloaded_files[entry.ident].video,
|
||||||
self.downloaded_files[entry.ident].audio,
|
# self.downloaded_files[entry.ident].audio,
|
||||||
*extra_options,
|
# *extra_options,
|
||||||
|
# )
|
||||||
|
player.play(
|
||||||
|
self.downloaded_files[entry.ident].video, self.downloaded_files[entry.ident].audio
|
||||||
)
|
)
|
||||||
await self.player.communicate()
|
# await self.player.wait()
|
||||||
await self.player.wait()
|
|
||||||
self.player = None
|
self.player = None
|
||||||
if self._skip_next:
|
if self._skip_next:
|
||||||
self._skip_next = False
|
self._skip_next = False
|
||||||
|
|
|
@ -18,6 +18,8 @@ from yt_dlp import YoutubeDL
|
||||||
from yt_dlp.utils import DownloadError
|
from yt_dlp.utils import DownloadError
|
||||||
from platformdirs import user_cache_dir
|
from platformdirs import user_cache_dir
|
||||||
|
|
||||||
|
from syng.player_libmpv import Player
|
||||||
|
|
||||||
|
|
||||||
from ..entry import Entry
|
from ..entry import Entry
|
||||||
from ..result import Result
|
from ..result import Result
|
||||||
|
@ -236,7 +238,7 @@ class YoutubeSource(Source):
|
||||||
"""
|
"""
|
||||||
return {"channels": self.channels}
|
return {"channels": self.channels}
|
||||||
|
|
||||||
async def play(self, entry: Entry, mpv_options: str) -> None:
|
async def play(self, entry: Entry, player: Player, mpv_options: str) -> None:
|
||||||
"""
|
"""
|
||||||
Play the given entry.
|
Play the given entry.
|
||||||
|
|
||||||
|
@ -252,18 +254,18 @@ class YoutubeSource(Source):
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
if self.start_streaming and not self.downloaded_files[entry.ident].complete:
|
if self.start_streaming and not self.downloaded_files[entry.ident].complete:
|
||||||
self.player = await self.play_mpv(
|
# self.player = await self.play_mpv(
|
||||||
entry.ident,
|
# entry.ident,
|
||||||
None,
|
# None,
|
||||||
"--script-opts=ytdl_hook-ytdl_path=yt-dlp,ytdl_hook-exclude='%.pls$'",
|
# "--script-opts=ytdl_hook-ytdl_path=yt-dlp,ytdl_hook-exclude='%.pls$'",
|
||||||
f"--ytdl-format={self.formatstring}",
|
# f"--ytdl-format={self.formatstring}",
|
||||||
"--fullscreen",
|
# "--fullscreen",
|
||||||
mpv_options,
|
# mpv_options,
|
||||||
)
|
# )
|
||||||
await self.player.communicate()
|
# await self.player.wait()
|
||||||
await self.player.wait()
|
player.play(entry.ident)
|
||||||
else:
|
else:
|
||||||
await super().play(entry, mpv_options)
|
await super().play(entry, player, mpv_options)
|
||||||
|
|
||||||
async def get_entry(
|
async def get_entry(
|
||||||
self,
|
self,
|
||||||
|
|
Loading…
Add table
Reference in a new issue