Skip to content

Commit

Permalink
fix, feat: Quality is not defined, move get_quality to Media()
Browse files Browse the repository at this point in the history
…and only run `ffprobe` once.
  • Loading branch information
THEGOLDENPRO committed Jun 1, 2024
1 parent 2934b36 commit 5eddb17
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 55 deletions.
10 changes: 4 additions & 6 deletions mov_cli/cli/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ def play(media: Media, metadata: Metadata, scraper: Scraper, episode: EpisodeSel

chosen_player = config.player

episode_details_string = ""

quality_string = ""
episode_details_string = ""

if metadata.type == MetadataType.MULTI:
season_string = Colours.CLAY.apply(str(episode.season))
Expand All @@ -36,15 +35,14 @@ def play(media: Media, metadata: Metadata, scraper: Scraper, episode: EpisodeSel
episode_details_string = f"episode {episode_string} in season {season_string} of " if episode.season > 1 else f"episode {episode_string} of "

if config.print_quality:
quality = media.quality
quality = media.get_quality()

if quality:
if quality is not None:
quality_string = f"in {Colours.GREEN.apply(quality.name)} "

mov_cli_logger.info(
f"Playing {episode_details_string}'{Colours.BLUE.apply(media.title)}' " \
f"{quality_string}" \
f"with {chosen_player.display_name}..."
f"{quality_string} with {chosen_player.display_name}..."
)
mov_cli_logger.debug(f"Streaming with this url -> '{hide_ip(media.url, config)}'")

Expand Down
54 changes: 45 additions & 9 deletions mov_cli/media/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
if TYPE_CHECKING:
from typing import Optional
from ..utils import EpisodeSelector
from .quality import Quality

from abc import abstractmethod
import json
import shutil
import subprocess
from .quality import Quality

from .quality import get_quality
from abc import abstractmethod

__all__ = (
"Media",
Expand All @@ -27,7 +29,7 @@ def __init__(
subtitles: Optional[str]
) -> None:
self.url = url
"""The stream-able url of the media."""
"""The stream-able url of the media (Can also be a path to a file). """
self.title = title
"""A title to represent this stream-able media."""
self.audio_url = audio_url
Expand All @@ -37,16 +39,50 @@ def __init__(
self.subtitles = subtitles
"""The url or file path to the subtitles."""

self.__stream_quality: Optional[Quality] = None

@property
@abstractmethod
def display_name(self) -> str:
"""The title that should be displayed by the player."""
...

@property
def quality(self) -> Quality | None:
"""The selected quality of media."""
return get_quality(self.url)

def get_quality(self) -> Optional[Quality]:
"""Uses ffprode to grab the quality of the stream."""

if self.__stream_quality is None:

if not shutil.which("ffprobe"):
return None

args = [
"ffprobe",
"-v",
"error",
"-select_streams",
"v",
"-show_entries",
"stream=width,height",
"-of",
"json",
self.url
]

out = str(subprocess.check_output(args), "utf-8")

stream = json.loads(out).get("streams", [])

if stream:
height = stream[0]["height"]
width = stream[0]["width"]

if height in Quality._value2member_map_:
self.__stream_quality = Quality(height)

if width in Quality._value2member_map_:
self.__stream_quality = Quality(width)

return self.__stream_quality

class Multi(Media):
"""Represents a media that has multiple episodes like a TV Series, Anime or Cartoon."""
Expand Down
43 changes: 3 additions & 40 deletions mov_cli/media/quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from pathlib import Path
...

from enum import Enum
import subprocess
import shutil
import json


__all__ = ("Quality", "get_quality",)
__all__ = ("Quality", )

class Quality(Enum):
SD = 480
Expand All @@ -29,37 +25,4 @@ def __init__(self, pixel: int) -> None:

def apply_p(self) -> str:
"""Returns that enum but with an ending p."""
return f"{self.value}p"

def get_quality(url: str | Path) -> Quality | None:
if not shutil.which("ffprobe"):
return None

args = [
"ffprobe",
"-v",
"error",
"-select_streams",
"v",
"-show_entries",
"stream=width,height",
"-of",
"json",
url
]

out = str(subprocess.check_output(args), "utf-8")

stream = json.loads(out).get("streams", [])

if stream:
height = stream[0]["height"]
width = stream[0]["width"]

if height in Quality._value2member_map_:
return Quality(height)

if width in Quality._value2member_map_:
return Quality(width)

return None
return f"{self.value}p"

0 comments on commit 5eddb17

Please sign in to comment.