Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Improved logging behavior #216

Merged
merged 1 commit into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ffmpeg_normalize/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from ._streams import AudioStream, MediaStream, SubtitleStream, VideoStream
from ._version import __version__

__module_name__ = "ffmpeg_normalize"

__all__ = [
"FFmpegNormalize",
"FFmpegNormalizeError",
Expand Down
24 changes: 9 additions & 15 deletions ffmpeg_normalize/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

from ._errors import FFmpegNormalizeError
from ._ffmpeg_normalize import NORMALIZATION_TYPES, FFmpegNormalize
from ._logger import setup_custom_logger
from ._logger import setup_cli_logger
from ._version import __version__

logger = setup_custom_logger()
_logger = logging.getLogger(__name__)


def create_parser() -> argparse.ArgumentParser:
Expand Down Expand Up @@ -442,19 +442,13 @@ def create_parser() -> argparse.ArgumentParser:

def main() -> None:
cli_args = create_parser().parse_args()

if cli_args.quiet:
logger.setLevel(logging.ERROR)
elif cli_args.debug:
logger.setLevel(logging.DEBUG)
elif cli_args.verbose:
logger.setLevel(logging.INFO)
setup_cli_logger(arguments=cli_args)

def error(message: object) -> NoReturn:
if logger.getEffectiveLevel() == logging.DEBUG:
logger.error(f"FFmpegNormalizeError: {message}")
if _logger.getEffectiveLevel() == logging.DEBUG:
_logger.error(f"FFmpegNormalizeError: {message}")
else:
logger.error(message)
_logger.error(message)
sys.exit(1)

def _split_options(opts: str) -> list[str]:
Expand Down Expand Up @@ -515,7 +509,7 @@ def _split_options(opts: str) -> list[str]:
)

if cli_args.output and len(cli_args.input) > len(cli_args.output):
logger.warning(
_logger.warning(
"There are more input files than output file names given. "
"Please specify one output file name per input file using -o <output1> <output2> ... "
"Will apply default file naming for the remaining ones."
Expand All @@ -524,7 +518,7 @@ def _split_options(opts: str) -> list[str]:
for index, input_file in enumerate(cli_args.input):
if cli_args.output is not None and index < len(cli_args.output):
if cli_args.output_folder and cli_args.output_folder != "normalized":
logger.warning(
_logger.warning(
f"Output folder {cli_args.output_folder} is ignored for "
f"input file {input_file}"
)
Expand All @@ -540,7 +534,7 @@ def _split_options(opts: str) -> list[str]:
+ cli_args.extension,
)
if not os.path.isdir(cli_args.output_folder) and not cli_args.dry_run:
logger.warning(
_logger.warning(
f"Output directory '{cli_args.output_folder}' does not exist, will create"
)
os.makedirs(cli_args.output_folder, exist_ok=True)
Expand Down
15 changes: 7 additions & 8 deletions ffmpeg_normalize/_cmd_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
from ffmpeg_progress_yield import FfmpegProgress

from ._errors import FFmpegNormalizeError
from ._logger import setup_custom_logger

logger = setup_custom_logger()
_logger = logging.getLogger(__name__)

NUL = "NUL" if system() in ("Windows", "cli") else "/dev/null"
DUR_REGEX = re.compile(
Expand Down Expand Up @@ -75,14 +74,14 @@ def run_ffmpeg_command(self, cmd: list[str]) -> Iterator[int]:
int: Progress percentage
"""
# wrapper for 'ffmpeg-progress-yield'
logger.debug(f"Running command: {cmd}")
_logger.debug(f"Running command: {cmd}")
ff = FfmpegProgress(cmd, dry_run=self.dry)
yield from ff.run_command_with_progress()

self.output = ff.stderr

if logger.getEffectiveLevel() == logging.DEBUG and self.output is not None:
logger.debug(
if _logger.getEffectiveLevel() == logging.DEBUG and self.output is not None:
_logger.debug(
f"ffmpeg output: {CommandRunner.prune_ffmpeg_progress_from_output(self.output)}"
)

Expand All @@ -97,10 +96,10 @@ def run_command(self, cmd: list[str]) -> CommandRunner:
Raises:
RuntimeError: If command returns non-zero exit code
"""
logger.debug(f"Running command: {cmd}")
_logger.debug(f"Running command: {cmd}")

if self.dry:
logger.debug("Dry mode specified, not actually running command")
_logger.debug("Dry mode specified, not actually running command")
return self

p = subprocess.Popen(
Expand Down Expand Up @@ -187,7 +186,7 @@ def ffmpeg_has_loudnorm() -> bool:
output = CommandRunner().run_command([get_ffmpeg_exe(), "-filters"]).get_output()
supports_loudnorm = "loudnorm" in output
if not supports_loudnorm:
logger.error(
_logger.error(
"Your ffmpeg does not support the 'loudnorm' filter. "
"Please make sure you are running ffmpeg v4.2 or above."
)
Expand Down
13 changes: 7 additions & 6 deletions ffmpeg_normalize/_ffmpeg_normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

import json
import os
import logging
from typing import TYPE_CHECKING, Literal

from tqdm import tqdm

from ._cmd_utils import ffmpeg_has_loudnorm, get_ffmpeg_exe
from ._errors import FFmpegNormalizeError
from ._logger import setup_custom_logger

from ._media_file import MediaFile

if TYPE_CHECKING:
from ._streams import LoudnessStatisticsWithMetadata

logger = setup_custom_logger()
_logger = logging.getLogger(__name__)

NORMALIZATION_TYPES = ("ebu", "rms", "peak")
PCM_INCOMPATIBLE_FORMATS = {"flac", "mp3", "mp4", "ogg", "oga", "opus", "webm"}
Expand Down Expand Up @@ -142,7 +143,7 @@ def __init__(
self.keep_loudness_range_target = keep_loudness_range_target

if self.keep_loudness_range_target and loudness_range_target != 7.0:
logger.warning(
_logger.warning(
"Setting --keep-loudness-range-target will override your set loudness range target value! "
"Remove --keep-loudness-range-target or remove the --lrt/--loudness-range-target option."
)
Expand Down Expand Up @@ -219,7 +220,7 @@ def run_normalization(self) -> None:
for index, media_file in enumerate(
tqdm(self.media_files, desc="File", disable=not self.progress, position=0)
):
logger.info(
_logger.info(
f"Normalizing file {media_file} ({index + 1} of {self.file_count})"
)

Expand All @@ -228,15 +229,15 @@ def run_normalization(self) -> None:
except Exception as e:
if len(self.media_files) > 1:
# simply warn and do not die
logger.error(
_logger.error(
f"Error processing input file {media_file}, will "
f"continue batch-processing. Error was: {e}"
)
else:
# raise the error so the program will exit
raise e

logger.info(f"Normalized file written to {media_file.output_file}")
_logger.info(f"Normalized file written to {media_file.output_file}")

if self.print_stats and self.stats:
print(json.dumps(self.stats, indent=4))
58 changes: 28 additions & 30 deletions ffmpeg_normalize/_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import logging
import sys
from platform import system
import colorlog
import argparse
from ffmpeg_normalize import __module_name__ as LOGGER_NAME

from tqdm import tqdm

_global_log: logging.Logger | None = None


# https://stackoverflow.com/questions/38543506/
class TqdmLoggingHandler(logging.StreamHandler):
Expand Down Expand Up @@ -37,37 +37,35 @@ def set_mp_lock() -> None:
pass


def setup_custom_logger() -> logging.Logger:
"""
Grab or create the global logger
def setup_cli_logger(arguments: argparse.Namespace) -> None:
"""Configurs the CLI logger.

Args:
arguments (argparse.Namespace): The CLI arguments.
"""

# \033[1;30m - black
# \033[1;31m - red
# \033[1;32m - green
# \033[1;33m - yellow
# \033[1;34m - blue
# \033[1;35m - magenta
# \033[1;36m - cyan
# \033[1;37m - white

global _global_log
if _global_log is not None:
return _global_log

if system() not in ("Windows", "cli"):
logging.addLevelName(logging.ERROR, "ERROR")
logging.addLevelName(logging.WARNING, "WARNING")
logging.addLevelName(logging.INFO, "INFO")
logging.addLevelName(logging.DEBUG, "DEBUG")

logger = logging.Logger("ffmpeg_normalize")
logger.setLevel(logging.WARNING)

logger = colorlog.getLogger(LOGGER_NAME)


handler = TqdmLoggingHandler()
handler.setFormatter(logging.Formatter(fmt="%(levelname)s: %(message)s"))
handler.setFormatter(colorlog.ColoredFormatter(
"%(log_color)s%(levelname)s: %(message)s",
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red,bg_white',
})
)
logger.addHandler(handler)

_global_log = logger
logger.setLevel(logging.WARNING)

return logger
if arguments.quiet:
logger.setLevel(logging.ERROR)
elif arguments.debug:
logger.setLevel(logging.DEBUG)
elif arguments.verbose:
logger.setLevel(logging.INFO)
Loading