deepctl-cmd-debug-audio 0.1.13__tar.gz → 0.1.14__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-cmd-debug-audio
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Audio debug subcommand for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>
@@ -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.13" # x-release-please-version
7
+ version = "0.1.14" # x-release-please-version
8
8
  description = "Audio debug subcommand for deepctl"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -10,15 +10,34 @@ from urllib.parse import urlparse
10
10
 
11
11
  import ffmpeg # type: ignore[import-untyped]
12
12
  import httpx
13
- from deepctl_core import AuthManager, BaseCommand, Config, DeepgramClient
13
+ from deepctl_core import (
14
+ AuthManager,
15
+ BaseCommand,
16
+ Config,
17
+ DeepgramClient,
18
+ get_console,
19
+ get_output_format,
20
+ get_status_console,
21
+ )
14
22
  from rich import box
15
- from rich.console import Console
16
23
  from rich.panel import Panel
17
24
  from rich.table import Table
18
25
 
19
26
  from .models import AudioDebugResult, AudioFormat, AudioInfo, AudioStream
20
27
 
21
- console = Console()
28
+ # Two channels, deliberately (#104):
29
+ # console -> stdout, the human rendering of the analysis. Only
30
+ # written in default (human) output mode; in json/yaml/
31
+ # csv/table mode the serialized AudioDebugResult is the
32
+ # whole of stdout, so `dg -o json debug audio | jq` parses.
33
+ # status_console -> stderr, always: progress lines and failure panels.
34
+ console = get_console()
35
+ status_console = get_status_console()
36
+
37
+
38
+ def _human_output() -> bool:
39
+ """True when stdout is for a person, not a parser."""
40
+ return get_output_format() == "default"
22
41
 
23
42
 
24
43
  class AudioCommand(BaseCommand):
@@ -87,7 +106,7 @@ class AudioCommand(BaseCommand):
87
106
 
88
107
  def _download_url(self, url: str) -> str:
89
108
  """Download a URL to a temporary file and return the path."""
90
- console.print(f"[blue]Downloading:[/blue] {url}")
109
+ status_console.print(f"[blue]Downloading:[/blue] {url}")
91
110
 
92
111
  parsed = urlparse(url)
93
112
  ext = os.path.splitext(parsed.path)[1] or ".audio"
@@ -107,7 +126,7 @@ class AudioCommand(BaseCommand):
107
126
  tmp.write(chunk)
108
127
  total += len(chunk)
109
128
  size_mb = total / (1024 * 1024)
110
- console.print(
129
+ status_console.print(
111
130
  f"[green]Downloaded[/green] {size_mb:.2f} MB → {tmp_name}"
112
131
  )
113
132
  return tmp_name
@@ -406,7 +425,7 @@ class AudioCommand(BaseCommand):
406
425
 
407
426
  # Check if ffmpeg is installed
408
427
  if not self.check_ffmpeg_installed():
409
- console.print(
428
+ status_console.print(
410
429
  Panel(
411
430
  "[red]✗ FFmpeg not found![/red]\n\n"
412
431
  "The audio debug command requires FFmpeg to be installed "
@@ -438,7 +457,7 @@ class AudioCommand(BaseCommand):
438
457
  downloaded_file = self._download_url(audio_file)
439
458
  file_to_analyze = downloaded_file
440
459
  except Exception as e:
441
- console.print(
460
+ status_console.print(
442
461
  Panel(
443
462
  f"[red]✗ Failed to download URL[/red]\n\n[dim]{e!s}[/dim]",
444
463
  title="Download Failed",
@@ -454,7 +473,9 @@ class AudioCommand(BaseCommand):
454
473
 
455
474
  # Process the audio file
456
475
  try:
457
- console.print(f"[blue]Analyzing audio file:[/blue] {file_to_analyze}")
476
+ status_console.print(
477
+ f"[blue]Analyzing audio file:[/blue] {file_to_analyze}"
478
+ )
458
479
 
459
480
  # Run ffprobe
460
481
  probe_data = self.run_ffprobe(file_to_analyze, ffprobe_args)
@@ -462,45 +483,52 @@ class AudioCommand(BaseCommand):
462
483
  # Parse the data
463
484
  audio_info = self.parse_audio_info(probe_data)
464
485
 
465
- # Display results based on verbosity
466
- if extra_verbose or ffprobe_args:
467
- self.display_extra_verbose_info(audio_info)
468
- elif verbose:
469
- self.display_verbose_info(audio_info)
470
- else:
471
- self.display_basic_info(audio_info)
472
-
473
- # Check for Deepgram compatibility
474
- console.print("\n[bold]Deepgram Compatibility Check:[/bold]")
475
- compatibility_issues = []
476
-
477
- if audio_info.streams:
478
- for stream in audio_info.streams:
479
- # Check sample rate
480
- if stream.sample_rate and int(stream.sample_rate) < 8000:
481
- compatibility_issues.append(
482
- f"⚠️ Low sample rate ({stream.sample_rate} Hz) - "
483
- f"Deepgram works best with 8kHz or higher"
484
- )
485
-
486
- # Check channels
487
- if stream.channels and stream.channels > 2:
488
- compatibility_issues.append(
489
- f"⚠️ Multi-channel audio ({stream.channels} "
490
- f"channels) - Consider converting to mono or "
491
- f"stereo"
492
- )
493
-
494
- if compatibility_issues:
495
- for issue in compatibility_issues:
496
- console.print(f" {issue}")
497
- else:
498
- console.print(
499
- " [green]✓[/green] Audio appears to be compatible with Deepgram"
500
- )
486
+ # Everything below is the human rendering of the analysis. It is
487
+ # the same information the returned AudioDebugResult carries, so
488
+ # in a machine-readable format it would be duplicate prose sitting
489
+ # in front of the payload -- exactly the #104 break. Print it only
490
+ # when stdout is for a person.
491
+ if _human_output():
492
+ # Display results based on verbosity
493
+ if extra_verbose or ffprobe_args:
494
+ self.display_extra_verbose_info(audio_info)
495
+ elif verbose:
496
+ self.display_verbose_info(audio_info)
497
+ else:
498
+ self.display_basic_info(audio_info)
499
+
500
+ # Check for Deepgram compatibility
501
+ console.print("\n[bold]Deepgram Compatibility Check:[/bold]")
502
+ compatibility_issues = []
503
+
504
+ if audio_info.streams:
505
+ for stream in audio_info.streams:
506
+ # Check sample rate
507
+ if stream.sample_rate and int(stream.sample_rate) < 8000:
508
+ compatibility_issues.append(
509
+ f"⚠️ Low sample rate ({stream.sample_rate} Hz) - "
510
+ f"Deepgram works best with 8kHz or higher"
511
+ )
512
+
513
+ # Check channels
514
+ if stream.channels and stream.channels > 2:
515
+ compatibility_issues.append(
516
+ f"⚠️ Multi-channel audio ({stream.channels} "
517
+ f"channels) - Consider converting to mono or "
518
+ f"stereo"
519
+ )
520
+
521
+ if compatibility_issues:
522
+ for issue in compatibility_issues:
523
+ console.print(f" {issue}")
524
+ else:
525
+ console.print(
526
+ " [green]✓[/green] Audio appears to be compatible "
527
+ "with Deepgram"
528
+ )
501
529
 
502
- # Encoding suggestions
503
- self._suggest_encoding(audio_info)
530
+ # Encoding suggestions
531
+ self._suggest_encoding(audio_info)
504
532
 
505
533
  return AudioDebugResult(
506
534
  status="success",
@@ -510,7 +538,7 @@ class AudioCommand(BaseCommand):
510
538
  )
511
539
 
512
540
  except Exception as e:
513
- console.print(
541
+ status_console.print(
514
542
  Panel(
515
543
  f"[red]✗ Error analyzing audio file[/red]\n\n[dim]{e!s}[/dim]",
516
544
  title="Analysis Failed",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepctl-cmd-debug-audio
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Audio debug subcommand for deepctl
5
5
  Author-email: Deepgram <devrel@deepgram.com>
6
6
  Maintainer-email: Deepgram <devrel@deepgram.com>