feat(analyzer): analyze cuepoint using ffmpeg
- store cue(in|out) as strings - reraise when executable was not found BREAKING CHANGE: The analyzer requires 'ffmpeg'. The 'silan' system dependency can be removed.
This commit is contained in:
parent
ceab19271d
commit
d93fb44356
5 changed files with 200 additions and 121 deletions
|
@ -1,6 +1,7 @@
|
|||
import re
|
||||
from math import inf
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from .utils import run_
|
||||
|
||||
|
@ -54,3 +55,56 @@ def compute_replaygain(filepath: Path) -> Optional[float]:
|
|||
|
||||
if track_gain_match:
|
||||
return float(track_gain_match.group(1))
|
||||
|
||||
|
||||
_SILENCE_DETECT_RE = re.compile(
|
||||
r"\[silencedetect.*\] silence_(start|end): (-?\d+(?:\.\d+)?)(?: \| silence_duration: (\d+(?:\.\d+)?))?"
|
||||
)
|
||||
|
||||
|
||||
def compute_silences(filepath: Path) -> List[Tuple[float, float]]:
|
||||
"""
|
||||
Compute silence will analyse the given audio file and return a list of silences.
|
||||
"""
|
||||
cmd = _ffmpeg(
|
||||
*("-i", filepath),
|
||||
"-vn",
|
||||
*("-filter", "highpass=frequency=1000"),
|
||||
*("-filter", "silencedetect=noise=0.15:duration=1"),
|
||||
)
|
||||
|
||||
starts, ends = [], []
|
||||
for line in cmd.stderr.splitlines():
|
||||
match = _SILENCE_DETECT_RE.search(line)
|
||||
if match is None:
|
||||
continue
|
||||
|
||||
kind = match.group(1)
|
||||
if kind == "start":
|
||||
start = float(match.group(2))
|
||||
start = max(start, 0.0)
|
||||
starts.append(start)
|
||||
elif kind == "end":
|
||||
end = float(match.group(2))
|
||||
ends.append(end)
|
||||
|
||||
# ffmpeg v3 (bionic) does not warn about silence end when the track ends.
|
||||
# Set the last silence ending to infinity, and clamp it to the track duration before
|
||||
# using this value.
|
||||
if len(starts) - 1 == len(ends):
|
||||
ends.append(inf)
|
||||
|
||||
return list(zip(starts, ends))
|
||||
|
||||
|
||||
def probe_duration(filepath: Path) -> float:
|
||||
"""
|
||||
Probe duration will probe the given audio file and return the duration.
|
||||
"""
|
||||
cmd = _ffprobe(
|
||||
*("-i", filepath),
|
||||
*("-show_entries", "format=duration"),
|
||||
*("-v", "quiet"),
|
||||
*("-of", "csv=p=0"),
|
||||
)
|
||||
return float(cmd.stdout.strip("\n"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue