diff --git a/src/edge_playback/__main__.py b/src/edge_playback/__main__.py index 9fe4ce5..d027fec 100644 --- a/src/edge_playback/__main__.py +++ b/src/edge_playback/__main__.py @@ -6,13 +6,12 @@ import subprocess import sys import tempfile from shutil import which +from typing import List, Optional, Tuple from .util import pr_err -def _main() -> None: - depcheck_failed = False - +def _parse_args() -> Tuple[bool, List[str]]: parser = argparse.ArgumentParser( prog="edge-playback", description="Speak text using Microsoft Edge's online text-to-speech API", @@ -24,9 +23,12 @@ def _main() -> None: help="Use mpv to play audio. By default, false on Windows and true on all other platforms", ) args, tts_args = parser.parse_known_args() - use_mpv = sys.platform != "win32" or args.mpv + return use_mpv, tts_args + +def _check_deps(use_mpv: bool) -> None: + depcheck_failed = False deps = ["edge-tts"] if use_mpv: deps.append("mpv") @@ -40,54 +42,88 @@ def _main() -> None: pr_err("Please install the missing dependencies.") sys.exit(1) + +def _create_temp_files( + use_mpv: bool, mp3_fname: Optional[str], srt_fname: Optional[str], debug: bool +) -> Tuple[str, Optional[str]]: + media = subtitle = None + if not mp3_fname: + media = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) + media.close() + mp3_fname = media.name + if debug: + print(f"Media file: {mp3_fname}") + + if not srt_fname and use_mpv: + subtitle = tempfile.NamedTemporaryFile(suffix=".srt", delete=False) + subtitle.close() + srt_fname = subtitle.name + + if debug and srt_fname: + print(f"Subtitle file: {srt_fname}\n") + + return mp3_fname, srt_fname + + +def _run_edge_tts( + mp3_fname: str, srt_fname: Optional[str], tts_args: List[str] +) -> None: + edge_tts_cmd = ["edge-tts", f"--write-media={mp3_fname}"] + if srt_fname: + edge_tts_cmd.append(f"--write-subtitles={srt_fname}") + edge_tts_cmd = edge_tts_cmd + tts_args + with subprocess.Popen(edge_tts_cmd) as process: + process.communicate() + + +def _play_media(use_mpv: bool, mp3_fname: str, srt_fname: Optional[str]) -> None: + if sys.platform == "win32" and not use_mpv: + # pylint: disable-next=import-outside-toplevel + from .win32_playback import play_mp3_win32 + + play_mp3_win32(mp3_fname) + return + + mpv_cmd = [ + "mpv", + "--msg-level=all=error,statusline=status", + ] + if srt_fname: + mpv_cmd.append(f"--sub-file={srt_fname}") + mpv_cmd.append(mp3_fname) + with subprocess.Popen(mpv_cmd) as process: + process.communicate() + + +def _cleanup(mp3_fname: Optional[str], srt_fname: Optional[str], keep: bool) -> None: + if keep and mp3_fname is not None: + print(f"\nKeeping temporary files: {mp3_fname}", end="") + if srt_fname: + print(f" and {srt_fname}", end="") + print() + return + + if mp3_fname is not None and os.path.exists(mp3_fname): + os.unlink(mp3_fname) + if srt_fname is not None and os.path.exists(srt_fname): + os.unlink(srt_fname) + + +def _main() -> None: + use_mpv, tts_args = _parse_args() + _check_deps(use_mpv) + + debug = os.environ.get("EDGE_PLAYBACK_DEBUG") is not None keep = os.environ.get("EDGE_PLAYBACK_KEEP_TEMP") is not None mp3_fname = os.environ.get("EDGE_PLAYBACK_MP3_FILE") srt_fname = os.environ.get("EDGE_PLAYBACK_SRT_FILE") - media, subtitle = None, None + try: - if not mp3_fname: - media = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) - media.close() - mp3_fname = media.name - - if not srt_fname and use_mpv: - subtitle = tempfile.NamedTemporaryFile(suffix=".srt", delete=False) - subtitle.close() - srt_fname = subtitle.name - - print(f"Media file: {mp3_fname}") - if srt_fname: - print(f"Subtitle file: {srt_fname}\n") - - edge_tts_cmd = ["edge-tts", f"--write-media={mp3_fname}"] - if srt_fname: - edge_tts_cmd.append(f"--write-subtitles={srt_fname}") - edge_tts_cmd = edge_tts_cmd + tts_args - with subprocess.Popen(edge_tts_cmd) as process: - process.communicate() - - if sys.platform == "win32" and not use_mpv: - # pylint: disable-next=import-outside-toplevel - from .win32_playback import play_mp3_win32 - - play_mp3_win32(mp3_fname) - else: - with subprocess.Popen( - [ - "mpv", - f"--sub-file={srt_fname}", - mp3_fname, - ] - ) as process: - process.communicate() + mp3_fname, srt_fname = _create_temp_files(use_mpv, mp3_fname, srt_fname, debug) + _run_edge_tts(mp3_fname, srt_fname, tts_args) + _play_media(use_mpv, mp3_fname, srt_fname) finally: - if keep: - print(f"\nKeeping temporary files: {mp3_fname} and {srt_fname}") - else: - if mp3_fname is not None and os.path.exists(mp3_fname): - os.unlink(mp3_fname) - if srt_fname is not None and os.path.exists(srt_fname): - os.unlink(srt_fname) + _cleanup(mp3_fname, srt_fname, keep) if __name__ == "__main__":