feat(analyzer): analyze replaygain using ffmpeg

- remove pycairo pip install
- fix py36 compatibility
- reraise when executable was not found

BREAKING CHANGE: The analyzer requires 'ffmpeg'. The 'rgain3' python package and it's system dependencies can be removed.
This commit is contained in:
jo 2022-01-21 09:07:27 +01:00 committed by Kyle Robbertze
parent bf7b0d44fb
commit ceab19271d
8 changed files with 141 additions and 77 deletions

View file

@ -1,42 +1,27 @@
import re
import subprocess
from subprocess import CalledProcessError
from typing import Any, Dict
from loguru import logger
REPLAYGAIN_EXECUTABLE = "replaygain" # From the rgain3 python package
from ..ffmpeg import compute_replaygain, probe_replaygain
def analyze_replaygain(filename: str, metadata: Dict[str, Any]):
"""Extracts the Replaygain loudness normalization factor of a track.
:param filename: The full path to the file to analyzer
:param metadata: A metadata dictionary where the results will be put
:return: The metadata dictionary
def analyze_replaygain(filepath: str, metadata: Dict[str, Any]):
"""
""" The -d flag means do a dry-run, ie. don't modify the file directly.
Extracts the Replaygain loudness normalization factor of a track using ffmpeg.
"""
command = [REPLAYGAIN_EXECUTABLE, "-d", filename]
try:
results = subprocess.check_output(
command,
stderr=subprocess.STDOUT,
close_fds=True,
universal_newlines=True,
)
gain_match = (
r"Calculating Replay Gain information \.\.\.(?:\n|.)*?:([\d.-]*) dB"
)
replaygain = re.search(gain_match, results).group(1)
metadata["replay_gain"] = float(replaygain)
# First probe for existing replaygain metadata.
track_gain = probe_replaygain(filepath)
if track_gain is not None:
metadata["replay_gain"] = track_gain
return metadata
except (CalledProcessError, OSError):
pass
except OSError as e: # replaygain was not found
logger.warning(
"Failed to run: %s - %s. %s"
% (command[0], e.strerror, "Do you have python-rgain installed?")
)
except subprocess.CalledProcessError as e: # replaygain returned an error code
logger.warning("%s %s %s", e.cmd, e.output, e.returncode)
except Exception as e:
logger.warning(e)
try:
track_gain = compute_replaygain(filepath)
if track_gain is not None:
metadata["replay_gain"] = track_gain
except (CalledProcessError, OSError):
pass
return metadata