feat: init python mpv intergration for next and prev episode

This commit is contained in:
Benex254
2024-08-07 11:01:11 +03:00
parent 28db40bb8b
commit 5718ed4f32
6 changed files with 170 additions and 44 deletions

View File

@@ -14,7 +14,7 @@ if TYPE_CHECKING:
def downloads(config: "Config", path: bool):
import os
from ...cli.utils.mpv import mpv
from ...cli.utils.mpv import run_mpv
from ...libs.fzf import fzf
from ...libs.rofi import Rofi
from ..utils.tools import exit_app
@@ -41,7 +41,7 @@ def downloads(config: "Config", path: bool):
exit_app()
return
playlist = os.path.join(USER_VIDEOS_DIR, playlist_name)
mpv(playlist)
run_mpv(playlist)
stream()
stream()

View File

@@ -23,7 +23,7 @@ def search(config: Config, anime_title: str, episode_range: str):
from ...libs.anime_provider.types import Anime
from ...libs.fzf import fzf
from ...libs.rofi import Rofi
from ..utils.mpv import mpv
from ..utils.mpv import run_mpv
from ..utils.tools import exit_app
from ..utils.utils import clear, fuzzy_inquirer
@@ -138,7 +138,7 @@ def search(config: Config, anime_title: str, episode_range: str):
print(f"[purple]Now Playing:[/] {search_result} Episode {episode}")
mpv(link, search_result)
run_mpv(link, search_result)
stream_anime()
stream_anime()

View File

@@ -47,6 +47,7 @@ class Config(object):
"rofi_theme": "",
"rofi_theme_input": "",
"rofi_theme_confirm": "",
"use_mpv_mod": "true",
}
)
self.configparser.add_section("stream")
@@ -71,6 +72,7 @@ class Config(object):
self.continue_from_history = self.get_continue_from_history()
self.auto_next = self.get_auto_next()
self.auto_select = self.get_auto_select()
self.use_mpv_mod = self.get_use_mpv_mod()
self.quality = self.get_quality()
self.notification_duration = self.get_notification_duration()
self.error = self.get_error()
@@ -170,6 +172,9 @@ class Config(object):
def get_quality(self):
return self.configparser.getint("stream", "quality")
def get_use_mpv_mod(self):
return self.configparser.getboolean("stream", "use_mpv_mod")
def get_notification_duration(self):
return self.configparser.getint("general", "notification_duration")

View File

@@ -17,7 +17,8 @@ from ...libs.fzf import fzf
from ...libs.rofi import Rofi
from ...Utility.data import anime_normalizer
from ...Utility.utils import anime_title_percentage_match, sanitize_filename
from ..utils.mpv import mpv
from ..utils.mpv import run_mpv
from ..utils.player import player
from ..utils.tools import QueryDict, exit_app
from ..utils.utils import clear, fuzzy_inquirer
from .utils import aniskip
@@ -75,7 +76,7 @@ def player_controls(config: "Config", anilist_config: QueryDict):
anilist_config.selected_anime_anilist["idMal"], current_episode
):
custom_args = args
stop_time, total_time = mpv(
stop_time, total_time = run_mpv(
current_link,
selected_server["episode_title"],
start_time=start_time,
@@ -341,18 +342,28 @@ def fetch_streams(config: "Config", anilist_config: QueryDict):
if start_time != "0":
print("[green]Continuing from:[/] ", start_time)
custom_args = []
if config.skip:
if args := aniskip(
anilist_config.selected_anime_anilist["idMal"], episode_number
):
custom_args = args
if config.use_mpv_mod:
mpv = player.create_player(
anime_provider, anilist_config, config, selected_server["episode_title"]
)
mpv.play(stream_link)
mpv.wait_for_shutdown()
mpv.terminate()
stop_time = player.last_stop_time
total_time = player.last_total_time
stop_time, total_time = mpv(
stream_link,
selected_server["episode_title"],
start_time=start_time,
custom_args=custom_args,
)
else:
if config.skip:
if args := aniskip(
anilist_config.selected_anime_anilist["idMal"], episode_number
):
custom_args.extend(args)
stop_time, total_time = run_mpv(
stream_link,
selected_server["episode_title"],
start_time=start_time,
custom_args=custom_args,
)
print("Finished at: ", stop_time)
# update_watch_history
@@ -541,7 +552,7 @@ def anilist_options(config, anilist_config: QueryDict):
if trailer := selected_anime.get("trailer"):
trailer_url = "https://youtube.com/watch?v=" + trailer["id"]
print("[bold magenta]Watching Trailer of:[/]", selected_anime_title)
mpv(
run_mpv(
trailer_url,
ytdl_format=config.format,
)

View File

@@ -1,29 +1,6 @@
import re
import shutil
import subprocess
from typing import Optional
# legacy
# def mpv(link, title: None | str = "anime", *custom_args):
# MPV = shutil.which("mpv")
# if not MPV:
# args = [
# "nohup",
# "am",
# "start",
# "--user",
# "0",
# "-a",
# "android.intent.action.VIEW",
# "-d",
# link,
# "-n",
# "is.xyz.mpv/.MPVActivity",
# ]
# subprocess.run(args)
# else:
# subprocess.run([MPV, *custom_args, f"--title={title}", link])
#
def stream_video(MPV, url, mpv_args, custom_args):
@@ -69,9 +46,9 @@ def stream_video(MPV, url, mpv_args, custom_args):
return last_time, total_time
def mpv(
def run_mpv(
link: str,
title: Optional[str] = "",
title: str | None = "",
start_time: str = "0",
ytdl_format="",
custom_args=[],
@@ -135,7 +112,7 @@ def mpv(
# Example usage
if __name__ == "__main__":
mpv(
run_mpv(
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"Example Video",
"--fullscreen",

View File

@@ -0,0 +1,133 @@
from typing import TYPE_CHECKING
import mpv
from ...anilist import AniList
if TYPE_CHECKING:
from typing import Literal
from ...AnimeProvider import AnimeProvider
from ..config import Config
def format_time(duration_in_secs: float):
h = duration_in_secs // 3600
m = duration_in_secs // 60
s = duration_in_secs - ((h * 3600) + (m * 60))
return f"{int(h):2d}:{int(m):2d}:{int(s):2d}".replace(" ", "0")
class MpvPlayer(object):
anime_provider: "AnimeProvider"
config: "Config"
mpv_player: "mpv.MPV"
last_stop_time: str = "0"
last_total_time: str = "0"
last_stop_time_secs = 0
last_total_time_secs = 0
current_media_title = ""
def get_episode(self, type: "Literal['next','previous']"):
anilist_config = self.anilist_config
config = self.config
episode_number: str = anilist_config.episode_number
quality = config.quality
episodes: list = sorted(anilist_config.episodes, key=float)
anime_id: int = anilist_config.anime_id
anime = anilist_config.anime
translation_type = config.translation_type
anime_provider = config.anime_provider
if type == "next":
next_episode = episodes.index(episode_number) + 1
if next_episode >= len(episodes):
next_episode = len(episodes) - 1
anilist_config.episode_number = episodes[next_episode]
episode_number = anilist_config.episode_number
config.update_watch_history(anime_id, episodes[next_episode])
else:
prev_episode = episodes.index(episode_number) - 1
if prev_episode <= 0:
prev_episode = 0
anilist_config.episode_number = episodes[prev_episode]
episode_number = anilist_config.episode_number
config.update_watch_history(anime_id, episodes[prev_episode])
if config.user and episode_number:
AniList.update_anime_list(
{
"mediaId": anime_id,
"progress": episode_number,
}
)
episode_streams = anime_provider.get_episode_streams(
anime,
episode_number,
translation_type,
anilist_config.selected_anime_anilist,
)
if not episode_streams:
self.mpv_player.print_text("No streams were found")
return None
selected_server = next(episode_streams)
self.current_media_title = selected_server["episode_title"]
self.mpv_player.script_message(f"{self.current_media_title}")
links = selected_server["links"]
if quality > len(links) - 1:
quality = config.quality = len(links) - 1
elif quality < 0:
quality = config.quality = 0
stream_link = links[quality]["link"]
return stream_link
def create_player(
self, anime_provider: "AnimeProvider", anilist_config, config: "Config", title
):
self.anime_provider = anime_provider
self.anilist_config = anilist_config
self.config = config
mpv_player = mpv.MPV(
config=True,
input_default_bindings=True,
input_vo_keyboard=True,
osc=True,
ytdl=True,
)
mpv_player.title = title
@mpv_player.on_key_press("shift+n")
def _next_episode():
url = self.get_episode("next")
if url:
mpv_player.loadfile(url, options=f"title={self.current_media_title}")
mpv_player.title = self.current_media_title
@mpv_player.on_key_press("shift+p")
def _previous_episode():
url = self.get_episode("previous")
if url:
mpv_player.loadfile(url, options=f"title={self.current_media_title}")
mpv_player.title = self.current_media_title
@mpv_player.property_observer("time-pos")
def handle_time_start_update(*args):
if len(args) > 1:
value = args[1]
if value is not None:
self.last_stop_time = format_time(value)
@mpv_player.property_observer("time-remaining")
def handle_time_remaining_update(*args):
if len(args) > 1:
value = args[1]
if value is not None:
self.last_total_time = format_time(value)
mpv_player.observe_property("time-pos", handle_time_start_update)
mpv_player.observe_property("time-remaining", handle_time_remaining_update)
self.mpv_player = mpv_player
return mpv_player
player = MpvPlayer()