deepctl-cmd-debug-audio 0.1.14__tar.gz → 0.1.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/PKG-INFO +1 -1
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/pyproject.toml +1 -1
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio/command.py +31 -7
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/PKG-INFO +1 -1
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/README.md +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/setup.cfg +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio/__init__.py +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio/models.py +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/SOURCES.txt +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/dependency_links.txt +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/entry_points.txt +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/requires.txt +0 -0
- {deepctl_cmd_debug_audio-0.1.14 → deepctl_cmd_debug_audio-0.1.15}/src/deepctl_cmd_debug_audio.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deepctl-cmd-debug-audio"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.15" # x-release-please-version
|
|
8
8
|
description = "Audio debug subcommand for deepctl"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
-
import
|
|
5
|
+
import shlex
|
|
6
6
|
import subprocess
|
|
7
7
|
import tempfile
|
|
8
8
|
from typing import Any
|
|
@@ -19,12 +19,24 @@ from deepctl_core import (
|
|
|
19
19
|
get_output_format,
|
|
20
20
|
get_status_console,
|
|
21
21
|
)
|
|
22
|
+
from deepctl_core.tools import resolve_tool
|
|
22
23
|
from rich import box
|
|
23
24
|
from rich.panel import Panel
|
|
24
25
|
from rich.table import Table
|
|
25
26
|
|
|
26
27
|
from .models import AudioDebugResult, AudioFormat, AudioInfo, AudioStream
|
|
27
28
|
|
|
29
|
+
|
|
30
|
+
def _ffprobe_input(file_path: str) -> str:
|
|
31
|
+
"""Name ``file_path`` for ffprobe as an input file, never as an option.
|
|
32
|
+
|
|
33
|
+
ffprobe has no ``--`` end-of-options marker, so a file named ``-f lavfi``
|
|
34
|
+
would be read as options. The ``file:`` protocol prefix with an absolute
|
|
35
|
+
path makes ffprobe treat it as a plain file, whatever it is called.
|
|
36
|
+
"""
|
|
37
|
+
return "file:" + os.path.abspath(file_path)
|
|
38
|
+
|
|
39
|
+
|
|
28
40
|
# Two channels, deliberately (#104):
|
|
29
41
|
# console -> stdout, the human rendering of the analysis. Only
|
|
30
42
|
# written in default (human) output mode; in json/yaml/
|
|
@@ -97,7 +109,14 @@ class AudioCommand(BaseCommand):
|
|
|
97
109
|
|
|
98
110
|
def check_ffmpeg_installed(self) -> bool:
|
|
99
111
|
"""Check if ffmpeg/ffprobe is installed."""
|
|
100
|
-
return
|
|
112
|
+
return self._ffprobe_bin() is not None
|
|
113
|
+
|
|
114
|
+
def _ffprobe_bin(self) -> str | None:
|
|
115
|
+
"""Absolute ffprobe path: the user config's, or one found on PATH
|
|
116
|
+
(never in the current directory)."""
|
|
117
|
+
return resolve_tool(
|
|
118
|
+
getattr(self, "_config", None), "ffprobe", "tools.ffprobe_path"
|
|
119
|
+
)
|
|
101
120
|
|
|
102
121
|
def _is_url(self, path: str) -> bool:
|
|
103
122
|
"""Check if the path is a URL."""
|
|
@@ -210,12 +229,16 @@ class AudioCommand(BaseCommand):
|
|
|
210
229
|
self, file_path: str, custom_args: str | None = None
|
|
211
230
|
) -> dict[str, Any]:
|
|
212
231
|
"""Run ffprobe on the given file."""
|
|
232
|
+
ffprobe_bin = self._ffprobe_bin()
|
|
233
|
+
if ffprobe_bin is None:
|
|
234
|
+
raise Exception("Failed to probe file: ffprobe not found")
|
|
213
235
|
try:
|
|
214
236
|
if custom_args:
|
|
215
|
-
#
|
|
216
|
-
|
|
217
|
-
cmd
|
|
218
|
-
cmd.
|
|
237
|
+
# Split custom arguments like a POSIX shell on every OS, so a quoted
|
|
238
|
+
# value stays one argument, and run ffprobe directly
|
|
239
|
+
cmd = [ffprobe_bin, "-v", "quiet", "-print_format", "json"]
|
|
240
|
+
cmd.extend(shlex.split(custom_args))
|
|
241
|
+
cmd.append(_ffprobe_input(file_path))
|
|
219
242
|
|
|
220
243
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
221
244
|
if result.returncode != 0:
|
|
@@ -224,7 +247,7 @@ class AudioCommand(BaseCommand):
|
|
|
224
247
|
return dict(json.loads(result.stdout))
|
|
225
248
|
else:
|
|
226
249
|
# Use python-ffmpeg for standard probe
|
|
227
|
-
probe = ffmpeg.probe(file_path)
|
|
250
|
+
probe = ffmpeg.probe(_ffprobe_input(file_path), cmd=ffprobe_bin)
|
|
228
251
|
return dict(probe)
|
|
229
252
|
except Exception as e:
|
|
230
253
|
raise Exception(f"Failed to probe file: {e!s}")
|
|
@@ -409,6 +432,7 @@ class AudioCommand(BaseCommand):
|
|
|
409
432
|
**kwargs: Any,
|
|
410
433
|
) -> Any:
|
|
411
434
|
"""Handle audio debug command execution."""
|
|
435
|
+
self._config = config
|
|
412
436
|
audio_file = kwargs.get("file")
|
|
413
437
|
verbose = kwargs.get("verbose", False)
|
|
414
438
|
extra_verbose = kwargs.get("extra_verbose", False)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|