Overview
AudioClip handles audio loading, processing, and effects. Audio is stored as float32 in range [-1.0, 1.0] and processed using FFmpeg for accurate seeking and format conversion.
When you load a VideoClip , its audio track is automatically available via the video.audio property.
Defined in: src/movielite/audio/audio_clip.py:15
Constructor
AudioClip(path: str , start: float = 0 , duration: Optional[ float ] = None , volume: float = 1.0 , offset: float = 0 )
Path to the audio file (or video file with audio track)
Start time in the composition timeline (seconds)
Duration to use from the audio. If None, uses the full audio duration
Volume multiplier (0.0 to 1.0+, where 1.0 = 100%)
Start offset within the audio file (seconds)
Example
from movielite import AudioClip
# Load full audio
audio = AudioClip( "music.mp3" )
# Load with volume and offset
audio = AudioClip( "sound.wav" , start = 5 , volume = 0.7 , offset = 2 )
# Load specific duration
audio = AudioClip( "background.mp3" , duration = 30 , volume = 0.5 )
Properties
path
Path to the audio file.
Returns: File path string
Defined in: src/movielite/audio/audio_clip.py:360
volume
@ property
volume -> float
Volume multiplier (0.0 to 1.0+).
Returns: Current volume level
Defined in: src/movielite/audio/audio_clip.py:365
offset
@ property
offset -> float
Offset within the source audio file (seconds).
Returns: Current offset in seconds
Defined in: src/movielite/audio/audio_clip.py:370
sample_rate
@ property
sample_rate -> int
Sample rate in Hz (e.g., 44100, 48000).
Returns: Sample rate
Defined in: src/movielite/audio/audio_clip.py:375
channels
@ property
channels -> int
Number of audio channels (1 = mono, 2 = stereo).
Returns: Channel count
Defined in: src/movielite/audio/audio_clip.py:380
has_audio
@ property
has_audio -> bool
Whether this clip has actual audio (False for silent/no audio clips).
Returns: True if audio exists, False otherwise
Defined in: src/movielite/audio/audio_clip.py:385
Inherited Properties
From MediaClip:
start (float): Start time in the composition
duration (float): Duration in the timeline (accounts for speed)
end (float): End time in the composition
speed (float): Playback speed multiplier
Methods
get_samples
get_samples(start: float = 0 , end: Optional[ float ] = None ) -> np.ndarray
Get audio samples as numpy array. This loads all requested samples into memory at once.
For long audio clips, use iter_chunks() instead to avoid loading everything into memory.
Start time relative to this clip’s offset (seconds)
End time relative to this clip’s offset (seconds, None = until the end)
Numpy array of shape (n_samples, n_channels) with float32 values in [-1, 1]
Example:
audio = AudioClip( "music.mp3" )
samples = audio.get_samples( start = 0 , end = 5 ) # Get first 5 seconds
print (samples.shape) # (220500, 2) for 5s stereo at 44.1kHz
Defined in: src/movielite/audio/audio_clip.py:210
iter_chunks
iter_chunks(chunk_duration: float = 5.0 ) -> Iterator[Tuple[np.ndarray, float ]]
Iterate over audio chunks sequentially. Each chunk is loaded on-demand with effects applied.
Duration of each chunk in seconds (default: 5.0s ≈ 850KB for stereo 44.1kHz)
Tuple of (processed_samples, chunk_start_time) where:
processed_samples: np.ndarray of shape (n_samples, n_channels) with float32 in [-1, 1]
chunk_start_time: Absolute start time of this chunk in the original file
Example:
audio = AudioClip( "long_music.mp3" )
for samples, start_time in audio.iter_chunks( chunk_duration = 10.0 ):
print ( f "Processing chunk at { start_time } s: { samples.shape } " )
# Process chunk (e.g., write to file, apply effect, etc.)
Defined in: src/movielite/audio/audio_clip.py:178
subclip
subclip(start: float , end: float ) -> AudioClip
Extract a portion of this audio clip.
Start time within this clip (seconds)
End time within this clip (seconds)
Raises:
ValueError: If the range is invalid
Example:
audio = AudioClip( "song.mp3" ) # 180 second song
chorus = audio.subclip( 60 , 90 ) # Extract 30-second chorus
Defined in: src/movielite/audio/audio_clip.py:301
set_volume
set_volume(volume: float ) -> Self
Set the volume of this audio clip.
Volume multiplier (0.0 to 1.0+, where 1.0 = 100%, 0.5 = 50%, 2.0 = 200%)
Example:
audio = AudioClip( "music.mp3" )
audio.set_volume( 0.5 ) # 50% volume
audio.set_volume( 2.0 ) # 200% volume (may clip)
Defined in: src/movielite/audio/audio_clip.py:329
set_volume_curve
set_volume_curve(curve: Union[Callable[[ float ], float ], float ]) -> Self
Set a volume curve that changes over time.
curve
Union[float, Callable[[float], float]]
required
Either a float (constant volume) or a function that takes time (seconds) and returns volume multiplier
Example:
# Gradual volume increase (fade in manually)
audio.set_volume_curve( lambda t : min ( 1.0 , t / 5.0 ))
# Fade out
audio.set_volume_curve( lambda t : max ( 0.0 , 1.0 - t / 10.0 ))
# Constant volume
audio.set_volume_curve( 0.7 )
Defined in: src/movielite/audio/audio_clip.py:264
set_offset
set_offset(offset: float ) -> Self
Set the offset within the source audio file.
Offset in seconds (must be >= 0)
Raises:
ValueError: If offset is negative
Example:
audio = AudioClip( "podcast.mp3" )
audio.set_offset( 30 ) # Skip first 30 seconds
Defined in: src/movielite/audio/audio_clip.py:342
loop
loop(enabled: bool = True ) -> Self
Enable or disable looping for this audio clip. When enabled, the audio restarts from the beginning when it reaches the end.
Whether to enable looping
Example:
background_music = AudioClip( "loop.mp3" , duration = 60 )
background_music.loop( True ) # Loop for the full 60 seconds
Defined in: src/movielite/audio/audio_clip.py:390
add_effect
add_effect(effect: AudioEffect) -> Self
Apply an audio effect to this clip.
An AudioEffect instance from movielite.afx
Example:
from movielite import afx
audio = AudioClip( "voice.mp3" )
audio.add_effect(afx.FadeIn( 2.0 )).add_effect(afx.FadeOut( 1.5 ))
Defined in: src/movielite/audio/audio_clip.py:404
add_transform(callback: Callable[[np.ndarray, float , int ], np.ndarray]) -> Self
Apply a custom transformation to audio samples at render time. Multiple transformations can be chained.
callback
Callable[[np.ndarray, float, int], np.ndarray]
required
Function that takes (samples, time, sample_rate) and returns transformed samples:
samples: np.ndarray of shape (n_samples, n_channels) with float32 values in [-1, 1]
time: absolute time in seconds (start time of this sample chunk in the original file)
sample_rate: sample rate in Hz
Example:
import numpy as np
def apply_reverb ( samples , t , sr ):
# Simple delay-based reverb
delay_samples = int ( 0.1 * sr) # 100ms delay
reverb = np.zeros_like(samples)
reverb[delay_samples:] = samples[: - delay_samples] * 0.3
return samples + reverb
audio.add_transform(apply_reverb)
Defined in: src/movielite/audio/audio_clip.py:237
Inherited Methods
From MediaClip:
set_start(start) - Set start time
set_duration(duration) - Set duration
set_speed(speed) - Set playback speed
set_end(end) - Set end time
Speed Control and Audio Processing
How audio speed is handled
Speed Adjustment When you call set_speed(), AudioClip uses FFmpeg’s atempo filter for high-quality time stretching. Defined in audio_clip.py:115-128: # atempo filter only supports range [0.5, 2.0]
# Multiple filters are chained for larger speed changes
if self ._speed != 1.0 :
atempo_filters = []
remaining_speed = self ._speed
while remaining_speed > 2.0 :
atempo_filters.append( "atempo=2.0" )
remaining_speed /= 2.0
while remaining_speed < 0.5 :
atempo_filters.append( "atempo=0.5" )
remaining_speed /= 0.5
if remaining_speed != 1.0 :
atempo_filters.append( f "atempo= { remaining_speed } " )
Example audio = AudioClip( "speech.mp3" )
audio.set_speed( 1.5 ) # 1.5x speed (faster)
audio.set_speed( 0.75 ) # 0.75x speed (slower)
audio.set_speed( 4.0 ) # Uses chained filters: atempo=2.0,atempo=2.0
Complete Examples
Example 1: Background Music with Fade
from movielite import VideoClip, AudioClip, VideoWriter, afx
video = VideoClip( "video.mp4" )
video.audio.set_volume( 0.3 ) # Lower original audio
# Add background music
music = AudioClip( "music.mp3" , start = 0 , duration = video.duration, volume = 0.6 )
music.loop( True ) # Loop to match video duration
music.add_effect(afx.FadeIn( 2.0 ))
music.add_effect(afx.FadeOut( 3.0 ))
writer = VideoWriter( "output.mp4" , fps = video.fps, size = video.size)
writer.add_clip(video)
writer.add_clip(music)
writer.write()
Example 2: Audio Ducking (Lower Music During Speech)
from movielite import AudioClip, VideoWriter
music = AudioClip( "background.mp3" , duration = 60 , volume = 0.7 )
# Duck music volume during speech segments
def volume_curve ( t ):
# Lower volume from 10-20s and 40-50s (when speech plays)
if ( 10 <= t <= 20 ) or ( 40 <= t <= 50 ):
return 0.2 # Reduced volume
return 1.0 # Normal volume
music.set_volume_curve(volume_curve)
Example 3: Speed Ramping
from movielite import VideoClip, VideoWriter
video = VideoClip( "action.mp4" , duration = 10 )
# Gradually speed up from 1x to 2x over 10 seconds
video.set_speed( 1.0 )
video.audio.set_speed( 1.0 )
# Note: For variable speed, you'd need to split into segments
for i in range ( 10 ):
segment = video.subclip(i, i + 1 )
speed = 1.0 + (i / 10.0 ) # 1.0 to 2.0
segment.set_speed(speed)
# Add segment to composition
Example 4: Custom Echo Effect
import numpy as np
from movielite import AudioClip, VideoWriter
audio = AudioClip( "voice.mp3" )
def add_echo ( samples , t , sr ):
"""Add echo effect with 300ms delay and 40% feedback"""
delay_samples = int ( 0.3 * sr) # 300ms
echo = np.zeros_like(samples)
if len (samples) > delay_samples:
echo[delay_samples:] = samples[: - delay_samples] * 0.4
# Mix original with echo, normalize to prevent clipping
result = samples + echo
max_val = np.abs(result).max()
if max_val > 1.0 :
result = result / max_val
return result
audio.add_transform(add_echo)
Example 5: Multi-Track Audio Mixing
from movielite import VideoClip, AudioClip, VideoWriter
video = VideoClip( "video.mp4" )
video.audio.set_volume( 0.0 ) # Mute original audio
# Multiple audio tracks
narration = AudioClip( "narration.mp3" , start = 0 , volume = 1.0 )
music = AudioClip( "music.mp3" , start = 0 , duration = video.duration, volume = 0.4 )
music.loop( True )
sound_effect = AudioClip( "whoosh.wav" , start = 5 , volume = 0.8 )
writer = VideoWriter( "output.mp4" , fps = video.fps, size = video.size)
writer.add_clip(video)
writer.add_clips([narration, music, sound_effect])
writer.write()
AudioClip supports all formats that FFmpeg can decode:
MP3 (.mp3)
WAV (.wav)
AAC (.m4a, .aac)
FLAC (.flac)
OGG (.ogg)
Video files (.mp4, .mov, .avi, etc.) - extracts audio track
See Also