Tools for video and audio editing
Project description
mixing
Tools for video and audio editing
To install: pip install mixing
Quick Start
# Audio editing
from mixing.audio import Audio, fade_in, concatenate_audio
audio = Audio("song.mp3")
segment = audio[10:30] # Get 10s-30s segment
faded = segment.fade_in(2).fade_out(3) # Apply fades
faded.save("edited.mp3")
# Video editing
from mixing.video import Video, loop_video, replace_audio
video = Video("clip.mp4")
trimmed = video[5:15] # Get 5s-15s segment
looped = loop_video("intro.mp4", n_loops=3) # Repeat 3 times
mixed = replace_audio("video.mp4", "music.mp3", mix_ratio=0.7) # Mix audio
Examples
mixing.audio (NEW!)
Audio: Sliceable audio editing interface
The Audio class provides a clean, Pythonic interface for audio editing with slice notation and chainable operations.
from mixing.audio import Audio
# Load audio file
audio = Audio("song.mp3")
# Slice audio (lazy evaluation - no copying)
intro = audio[0:10] # First 10 seconds
chorus = audio[30:60] # 30s to 60s
outro = audio[-10:] # Last 10 seconds
# Use different time units
audio_samples = Audio("song.mp3", time_unit="samples")
segment = audio_samples[0:44100] # First 44100 samples (1s at 44.1kHz)
audio_ms = Audio("song.mp3", time_unit="milliseconds")
segment = audio_ms[0:5000] # First 5000ms (5 seconds)
# Chain operations
edited = audio[10:120].fade_in(2).fade_out(3)
edited.save("edited.mp3")
# Access properties
print(f"Duration: {audio.duration}s")
print(f"Sample rate: {audio.sample_rate}Hz")
print(f"Channels: {audio.channels}")
Audio Editing Functions
from mixing.audio import fade_in, fade_out, crop_audio, concatenate_audio, overlay_audio
# Apply fade effects
faded_in = fade_in("song.mp3", duration=2.0)
faded_out = fade_out("song.mp3", duration=3.0)
# Crop/trim audio
crop_audio("song.mp3", start=10, end=30, output_path="segment.mp3")
# Concatenate multiple audio files
combined = concatenate_audio(
"intro.mp3",
"main.mp3",
"outro.mp3",
crossfade=0.5 # 500ms crossfade between segments
)
combined.save("full_song.mp3")
# Overlay/mix audio tracks
# mix_ratio controls the balance: 0.0=only background, 1.0=only overlay, 0.5=equal mix
mixed = overlay_audio(
background="music.mp3",
overlay="voice.mp3",
position=5.0, # Start overlay at 5 seconds
mix_ratio=0.7 # 70% overlay, 30% background
)
mixed.save("mixed.mp3")
Audio Alignment: Find where one recording fits inside another
find_audio_offset uses cross-correlation to find the best time offset where a
query audio aligns within a reference audio. Useful for aligning different
recordings of the same performance — e.g., a studio mix (voice + instruments)
with a camera recording (voice only).
from mixing.audio import find_audio_offset
# Find where the studio recording aligns with the camera audio
offset = find_audio_offset("camera_recording.wav", "studio_mix.mp3")
print(f"Studio recording starts at {offset:.2f}s into the camera audio")
# Then use the offset to splice the studio audio into the video
from pydub import AudioSegment
video_audio = AudioSegment.from_file("camera_recording.mov")
studio_audio = AudioSegment.from_file("studio_mix.mp3")
offset_ms = int(offset * 1000)
composite = (
video_audio[:offset_ms]
+ studio_audio
+ video_audio[offset_ms + len(studio_audio):]
)
composite.export("composite_audio.wav", format="wav")
AudioSamples: Sample-level access
Access individual audio samples through a Mapping interface:
audio = Audio("song.mp3")
samples = audio.samples
# Access individual samples
first_sample = samples[0]
last_sample = samples[-1]
# Slice samples
sample_range = samples[1000:2000] # Returns numpy array
# Get properties
print(f"Total samples: {len(samples)}")
mixing.video
Video: Sliceable video editing interface (Enhanced!)
from mixing.video import Video
# Load and slice video
video = Video("movie.mp4")
clip = video[10:30] # Get 10s-30s segment
clip.save("clip.mp4")
# Use frame numbers
video_frames = Video("movie.mp4", time_unit="frames")
segment = video_frames[100:500] # Frames 100-500
# Extract single frames
frame = video[15] # Returns numpy array (frame at 15s)
NEW: Loop Video
Repeat a video multiple times:
from mixing.video import loop_video
# Loop video 3 times
looped = loop_video("intro.mp4", n_loops=3)
print(f"Looped video saved to: {looped}")
# Custom output path
looped = loop_video("clip.mp4", n_loops=5, output_path="extended_clip.mp4")
NEW: Replace/Mix Video Audio
Replace or mix audio in videos with fine control:
from mixing.video import replace_audio
# Complete audio replacement
replace_audio("video.mp4", "new_music.mp3", mix_ratio=1.0)
# Equal mix of original and new audio
replace_audio("video.mp4", "music.mp3", mix_ratio=0.5)
# Mostly new audio with some original (70% new, 30% original)
replace_audio("video.mp4", "voice.mp3", mix_ratio=0.7)
# Keep only original audio (no change)
replace_audio("video.mp4", "music.mp3", mix_ratio=0.0)
# Auto-adjust audio length to match video
replace_audio(
"video.mp4",
"short_music.mp3",
mix_ratio=1.0,
normalize_audio=True # Loops/trims audio to match video length
)
NEW: Normalize Audio Levels
Reduce volume fluctuations in video audio (perfect for narration with varying volume):
from mixing.video import normalize_audio
# Normalize audio in a video with varying narrator volume
normalize_audio("lecture.mp4") # Creates lecture_normalized.mp4
# Custom output path
normalize_audio("interview.mp4", output_path="interview_fixed.mp4")
# The function adjusts audio so loudest parts reach a consistent level,
# reducing variation between quiet and loud sections
VideoFrames: Dictionary-like access to video frames
VideoFrames provides a Mapping interface to access individual frames from a video file by index. Frames are returned as numpy arrays (BGR format).
from mv.util import VideoFrames
# Create frame accessor
frames = VideoFrames("my_video.mp4")
# Access frames by index
first_frame = frames[0]
last_frame = frames[-1] # Negative indexing supported
middle_frame = frames[len(frames) // 2]
# Slice to get multiple frames (returns an iterator, not a list)
for frame in frames[10:50]:
# Process frames 10 through 49
pass
# Get every 5th frame
for frame in frames[::5]:
# Process every 5th frame
pass
save_frame: Extract and save video frames as images
Convenience function to extract a single frame from a video and save it as an image.
from mv.util import save_frame
# Save first frame with auto-generated filename (video_0.png)
save_frame("my_video.mp4")
# Save frame 100 as JPEG
save_frame("my_video.mp4", 100, saveas=".jpg") # Saves as my_video_000100.jpg
# Save last frame to specific path
save_frame("my_video.mp4", -1, saveas="output/last_frame.png")
The saveas parameter accepts:
None(default): Auto-generate filename in video's directory.ext: Use this extension with auto-generated filename- Full path: Save to this specific location
write_subtitles_in_video
Write subtitles in a video.
Example usage:
>>> from mixing import write_subtitles_in_video
>>> output_path = write_subtitles_in_video("~/Downloads/some_video.mp4")
Which is syntactic sugar for the more explicit:
>>> output_path = write_subtitles_in_video(
... "~/Downloads/some_video.mp4",
... subtitles="~/Downloads/some_video.srt",
... output_video="~/Downloads/some_video.mp4"
... )
AI Video Generation with Google Vertex AI Veo
Generate videos using Google's state-of-the-art Veo models. The simplest approach generates videos and returns file paths in one call.
Quick Start
from mixing.video.video_gen import generate_video
# Generate video and get file path in one call
video_path = generate_video("A serene forest at dawn with golden sunlight filtering through mist")
print(f"Video saved to: {video_path}")
Authentication Setup
Before using video generation, set up Google Cloud authentication:
# Service account (recommended for production)
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"
export GOOGLE_CLOUD_PROJECT="your-project-id"
# Or use gcloud CLI (for development)
gcloud auth application-default login
export GOOGLE_CLOUD_PROJECT="your-project-id"
Advanced Examples
# Save to specific location
video_path = generate_video(
prompt="The camera slowly zooms out revealing a vast landscape",
first_frame="/path/to/image.jpg",
save_video="/my/custom/video.mp4",
duration_seconds=8
)
# Video-to-video: Use frames from existing videos
video_path = generate_video(
prompt="Smooth transition with swirling particles",
first_frame="video1.mp4", # Uses last frame as start
last_frame="video2.mp4", # Uses first frame as end
model="veo-2.0-generate-001"
)
# Handle multiple generated videos (some models create variations)
video_paths = generate_video(
"A magical forest with dancing fireflies",
save_video="/output/directory/" # Auto-indexed files
)
# Get raw operation for custom processing
operation = generate_video("Epic landscape", save_video=False)
# Process operation.response.generated_videos as needed
Flexible Egress Control
The save_video parameter controls how videos are processed:
# Default: Auto-save to temp files and return path(s)
path = generate_video("prompt")
# Save to specific file or directory
path = generate_video("prompt", save_video="/path/to/video.mp4")
path = generate_video("prompt", save_video="/output/dir/")
# Just get the operation (no saving)
op = generate_video("prompt", save_video=False)
# Custom processing function
def custom_processor(operation):
# Your custom logic here
return processed_result
result = generate_video("prompt", save_video=custom_processor)
Further requirements
Google Cloud Setup (for AI Video Generation)
To use the AI video generation features:
- Google Cloud Project: Create a project with billing enabled
- Enable APIs: Enable the Vertex AI API in your project
- Authentication: Set up service account credentials or use application default credentials
- Quotas: Ensure sufficient Vertex AI quotas for video generation
For detailed setup instructions, see the video generation authentication guide.
FFmpeg
Many of the tools also require ffmeg.
To install FFmpeg on your system, follow the instructions for your operating system below.
macOS
- Using Homebrew:
- Open Terminal.
- Run the following command:
brew install ffmpeg
For more details, visit the FFmpeg installation page for macOS.
Linux
- Using the package manager:
- For Debian/Ubuntu-based distributions, run:
sudo apt update sudo apt install ffmpeg
- For Fedora, run:
sudo dnf install ffmpeg
- For Arch Linux, run:
sudo pacman -S ffmpeg
- For Debian/Ubuntu-based distributions, run:
For more details, visit the FFmpeg installation page for Linux.
Windows
- Using Windows builds:
- Download the executable from FFmpeg for Windows.
- Extract the downloaded files and add the
bindirectory to your system's PATH.
For more details, visit the FFmpeg installation page for Windows.
Optional Dependencies
For additional functionality, you can install optional dependencies:
# For testing
pip install mixing[testing]
# For clipboard functionality (get file paths from clipboard)
pip install mixing[clipboard]
# For audio editing functionality
pip install mixing[audio]
# Install multiple extras
pip install mixing[testing,clipboard,audio]
Audio Editing Requirements
The audio editing features require:
- pydub: Python audio manipulation library
- ffmpeg: Audio/video processing (see installation below)
Install audio extras:
pip install mixing[audio]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mixing-0.0.5.tar.gz.
File metadata
- Download URL: mixing-0.0.5.tar.gz
- Upload date:
- Size: 19.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab8218683f544bd0cbeb286e11f7aa26966ca623f8ffd9541febd54d7042a283
|
|
| MD5 |
b02fa1db963cd6374d44ae6f5ef0b20c
|
|
| BLAKE2b-256 |
3e047fb0ee960d212c509c3939a3e974844f4842d04f50875bcec8c0978ecbe4
|
File details
Details for the file mixing-0.0.5-py3-none-any.whl.
File metadata
- Download URL: mixing-0.0.5-py3-none-any.whl
- Upload date:
- Size: 87.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9435f9986fc25b851fb93571df818b5cd1f57662719c43fbe48d4c669cfab38
|
|
| MD5 |
05cd0fe20b9861075f8d2849d1881a56
|
|
| BLAKE2b-256 |
67f8346eafe29a801768b7cefef379b424db30ad99f011e9102326eeb679caaa
|