Source code for camtasia.timeline.clips.audio

"""Audio media clip (AMFile)."""
from __future__ import annotations

from typing import Any
import sys
if sys.version_info >= (3, 11):  # pragma: no cover
    from typing import Self
else:  # pragma: no cover
    from typing_extensions import Self

from .base import BaseClip


[docs] class AMFile(BaseClip): """Audio media file clip. Wraps an ``AMFile`` JSON dict. Adds audio-specific properties for channel selection, gain, and loudness normalization. Args: data: The raw clip dict. """ @property def channel_number(self) -> str: """Channel number string (e.g. ``'0'``, ``'0,1'``).""" return self._data.get('channelNumber', '0') @channel_number.setter def channel_number(self, value: str) -> None: """Set the channel number string.""" self._data['channelNumber'] = value @property def attributes(self) -> dict[str, Any]: """Audio attributes dict (ident, gain, mixToMono, etc.).""" return self._data.get('attributes', {}) @property def gain(self) -> float: """Audio gain multiplier.""" return float(self.attributes.get('gain', 1.0)) @gain.setter def gain(self, value: float) -> None: """Set the audio gain multiplier.""" self._data.setdefault('attributes', {})['gain'] = value @property def loudness_normalization(self) -> bool: """Whether loudness normalization is enabled.""" return bool(self.attributes.get('loudnessNormalization', False)) @loudness_normalization.setter def loudness_normalization(self, value: bool) -> None: """Set whether loudness normalization is enabled.""" self._data.setdefault('attributes', {})['loudnessNormalization'] = value @property def is_muted(self) -> bool: """Whether the clip's gain is zero.""" return self.gain == 0.0
[docs] def normalize_gain(self, target_db: float = -23.0) -> Self: """Set loudness normalization target. Camtasia uses LUFS for loudness normalization. Common targets: -23 LUFS (EBU R128), -16 LUFS (podcast). Args: target_db: Target loudness in LUFS (default -23.0). Returns: self for chaining. """ self._data.setdefault('attributes', {})['loudnessNormalization'] = True self._data.setdefault('metadata', {})['targetLoudness'] = target_db return self
[docs] def set_gain(self, gain: float) -> Self: """Set the audio gain (volume multiplier). Args: gain: Volume multiplier (0.0 = silent, 1.0 = normal, 2.0 = double). Returns: self for chaining. """ if gain < 0: raise ValueError(f'Gain must be non-negative, got {gain}') self._data.setdefault('attributes', {})['gain'] = gain return self