Interdimensional Cable Video Format - A custom video format inspired by Rick & Morty
Project description
.sanchez Video Format
Interdimensional Cable Video Format - A custom video format inspired by Rick & Morty
"Nobody exists on purpose. Nobody belongs anywhere. Everybody's gonna die. Come watch TV." - Morty
Overview
The .sanchez format is a simple, human-readable video/image format where each pixel is stored as RGB hex values. This implementation includes zlib compression to reduce file sizes from ~14.5MB per frame to typically <1MB per frame.
Format Specification
Line 1: Metadata (JSON, one line)
Line 2: Config (WWWWHHHH + 7-digit frame count)
Line 3+: Frame data (compressed or hex pixels)
Example:
{"title":"MyVideo","creator":"cbx","created_at":"2026-01-02T01:30:43Z","seconds":"2.0"}
03200240000048
eJzLzklMT8...base64 compressed data...
Installation
# Install dependencies
pip install -r requirements.txt
# Also need ffmpeg for audio extraction/muxing either from website or;
# Windows: choco install ffmpeg / winget install ffmpeg
# Mac: brew install ffmpeg
# Linux: sudo apt install ffmpeg
Usage
Command Line
# Encode video to .sanchez
python -m sanchez encode video.mp4 output.sanchez
# Encode with resize
python -m sanchez encode video.mp4 -r 640x480
# Encode image to .sanchez
python -m sanchez encode image.png output.sanchez
# Decode .sanchez to MP4
python -m sanchez decode input.sanchez output.mp4
# Decode with audio
python -m sanchez decode input.sanchez -a audio.mp3
# Extract single frame
python -m sanchez decode input.sanchez -f 0 -o frame.png
# Extract all frames
python -m sanchez decode input.sanchez --frames
# Play .sanchez file
python -m sanchez play video.sanchez
# Show file info
python -m sanchez info video.sanchez
Python API
from sanchez import SanchezFile, SanchezEncoder, SanchezDecoder, SanchezPlayer
# Encode a video
encoder = SanchezEncoder()
encoder.encode("input.mp4", "output.sanchez", title="My Video", creator="cbx")
# Decode back to MP4
decoder = SanchezDecoder()
decoder.decode("output.sanchez", "decoded.mp4", audio_path="output.mp3")
# Play a .sanchez file
player = SanchezPlayer()
player.play("output.sanchez")
# Create .sanchez from scratch
import numpy as np
sanchez = SanchezFile.create("MyVideo", "cbx", width=320, height=240)
frame = np.random.randint(0, 255, (240, 320, 3), dtype=np.uint8)
sanchez.add_frame(frame)
sanchez.save("custom.sanchez")
# Read .sanchez file
sanchez = SanchezFile.load("custom.sanchez")
for frame in sanchez.get_frames():
# Process frame (numpy array)
pass
Player Controls
When playing with python -m sanchez play:
| Key | Action |
|---|---|
| Space | Pause/Resume |
| Left Arrow | Seek backward 5 seconds |
| Right Arrow | Seek forward 5 seconds |
| , | Previous frame (when paused) |
| . | Next frame (when paused) |
| R | Restart |
| I | Toggle info overlay |
| F | Toggle fullscreen |
| M | Mute/unmute audio |
| Q / Esc | Quit |
Compression
The format uses zlib compression with base64 encoding to store frame data efficiently:
- Uncompressed: ~6.2 MB per 1920x1080 frame (raw RGB bytes)
- Compressed: Typically 0.5-2 MB per frame depending on content
- Compression ratio: 3-10x typical
For maximum compatibility with the original spec (hex per pixel), use --no-compression flag, but note this creates much larger files.
File Structure
Metadata (Line 1)
{"title":"Example","creator":"cbx","created_at":"2026-01-02T01:30:43Z","seconds":"2.0"}
Config (Line 2)
WWWWHHHH + FFFFFFF
- WWWW: Width (4 digits, zero-padded)
- HHHH: Height (4 digits, zero-padded)
- FFFFFFF: Frame count (7 digits, zero-padded)
Example: 192010800000048 = 1920x1080, 48 frames
Frame Data (Lines 3+)
Each line is one frame, either:
- Compressed: Base64-encoded zlib-compressed RGB bytes
- Uncompressed:
{RRGGBB,RRGGBB,...}hex format
๐ Audio Support
The .sanchez format stores video only - audio is kept as a separate .mp3 file with the same base name. This separation allows for flexible audio handling and efficient streaming.
How Audio Works
video.sanchez โ Video frames (compressed RGB data)
video.mp3 โ Audio track (MP3 format)
Encoding with Audio
When encoding from MP4 or other video formats, audio is automatically extracted:
# Audio automatically extracted to output.mp3
python -m sanchez encode video.mp4 output.sanchez
# Results in:
# output.sanchez (video)
# output.mp3 (audio)
Decoding with Audio
When decoding, audio is automatically detected and muxed back:
# Auto-detects input.mp3 and muxes it
python -m sanchez decode input.sanchez output.mp4
# Or specify audio explicitly
python -m sanchez decode input.sanchez output.mp4 -a custom_audio.mp3
Playing with Audio
The player automatically finds and plays the matching .mp3 file:
# Plays video.sanchez with video.mp3 audio
python -m sanchez play video.sanchez
# Or specify audio explicitly
python -m sanchez play video.sanchez -a other_audio.mp3
Streaming with Audio
Audio is automatically streamed alongside video:
# Server auto-detects video.mp3 and streams it
python -m sanchez serve video.sanchez
# Or specify audio explicitly
python -m sanchez serve video.sanchez -a custom_audio.mp3
# Client receives both video and audio
python -m sanchez receive 192.168.1.100 9999
# Recording a stream saves both files
python -m sanchez receive 192.168.1.100 9999 -o recorded.sanchez
# Results in: recorded.sanchez + recorded.mp3
Audio in Python API
from sanchez import SanchezEncoder, SanchezDecoder, SanchezPlayer
from sanchez import SanchezStreamServer, SanchezStreamClient
# Encoding extracts audio automatically
encoder = SanchezEncoder()
sanchez_path, audio_path = encoder.encode("video.mp4", "output.sanchez")
print(f"Video: {sanchez_path}, Audio: {audio_path}")
# Decoding muxes audio back
decoder = SanchezDecoder()
decoder.decode("output.sanchez", "final.mp4", audio_path="output.mp3")
# Player handles audio automatically
player = SanchezPlayer()
player.play("output.sanchez") # Finds output.mp3 automatically
# Streaming includes audio
server = SanchezStreamServer()
server.stream_file("video.sanchez", audio_path="video.mp3") # Or auto-detect
# Client receives audio
client = SanchezStreamClient()
for frame_idx, frame_array in client.receive_stream("192.168.1.100", 9999):
process_frame(frame_array)
# After stream ends:
if client.audio_data:
with open("received.mp3", "wb") as f:
f.write(client.audio_data)
Why Separate Audio?
- Flexibility: Use different audio tracks with the same video
- Streaming efficiency: Audio can be buffered before playback starts
- Format simplicity: Keeps
.sanchezformat focused on video - Standard format: MP3 is universally supported
๐ก Streaming
The sanchez format supports video streaming over network and satellite connections!
Streaming Modes
| Mode | Description | Use Case |
|---|---|---|
| TCP | Reliable point-to-point | Local network, guaranteed delivery |
| UDP | Low-latency point-to-point | Direct connections, live streaming |
| Multicast | One-to-many broadcast | Satellite, IPTV, campus networks |
| Broadcast | Local network broadcast | LAN streaming, discovery |
Command Line Streaming
# Start a TCP stream server
python -m sanchez serve video.sanchez
# Stream on specific port
python -m sanchez serve video.sanchez -p 8080
# UDP multicast for satellite/broadcast
python -m sanchez serve video.sanchez -m multicast -H 239.0.0.1
# Satellite mode with FEC and smaller packets
python -m sanchez serve video.sanchez -m multicast -H 239.0.0.1 --satellite --loop
# Receive and play a stream
python -m sanchez receive 192.168.1.100 9999
# Receive multicast stream
python -m sanchez receive 239.0.0.1 9999 -m multicast
# Record stream to file
python -m sanchez receive 192.168.1.100 9999 -o recorded.sanchez
Python Streaming API
from sanchez import (
SanchezStreamServer,
SanchezStreamClient,
SanchezStreamPlayer,
StreamMode
)
# Start a streaming server
server = SanchezStreamServer(mode=StreamMode.TCP_UNICAST)
server.stream_file("video.sanchez", host="0.0.0.0", port=9999, loop=True)
# For satellite/multicast streaming
server = SanchezStreamServer(mode=StreamMode.UDP_MULTICAST)
server.stream_file(
"video.sanchez",
host="239.0.0.1", # Multicast group
port=9999,
loop=True,
satellite_mode=True # Enables FEC and smaller packets
)
# Receive and process stream frames
client = SanchezStreamClient(mode=StreamMode.TCP_UNICAST)
for frame_idx, frame_array in client.receive_stream("192.168.1.100", 9999):
# frame_array is a numpy RGB array
process_frame(frame_array)
# Play stream directly
player = SanchezStreamPlayer(mode=StreamMode.UDP_MULTICAST)
player.play_stream("239.0.0.1", 9999)
Satellite Features
The streaming module includes features designed for satellite/high-latency links:
- Forward Error Correction (FEC): XOR-based parity packets to recover lost data
- Smaller MTU-friendly packets: 1400-byte chunks for satellite links
- Sync packets: Periodic timing beacons for receiver synchronization
- CRC32 checksums: Packet integrity verification
- Sequence numbers: Lost packet detection
Streaming Protocol
The Sanchez streaming protocol uses a custom packet format:
โโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโฌโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโฌโโโโโโโโโโโ
โ MAGIC โ VERSION โ TYPE โ SEQ โ TIMESTAMP โ PAYLOAD_LEN โ PAYLOAD โ CHECKSUM โ
โ 4 bytes โ 1 byte โ 1 B โ 4 B โ 8 bytes โ 4 bytes โ N bytes โ 4 bytes โ
โโโโโโโโโโโดโโโโโโโโโโดโโโโโโโดโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโดโโโโโโโโโโโ
Packet Types:
0x01METADATA - Stream metadata (title, creator)0x02CONFIG - Video configuration (dimensions)0x10FRAME_START - Beginning of a frame0x11FRAME_CHUNK - Frame data chunk0x12FRAME_END - End of frame marker0x20SYNC - Synchronization heartbeat0x30FEC_DATA - Error correction parity0x40AUDIO_CONFIG - Audio format and size0x41AUDIO_CHUNK - Audio data chunk0xFFEND_STREAM - Stream termination
๐ฌ Live Streaming
Stream live video feeds directly - cameras, screens, windows, or video files without pre-conversion!
Interactive Feed Picker
Run without arguments to see a nice UI listing all available feeds:
python -m sanchez live
============================================================
๐ฌ Sanchez Live Feed Selector
============================================================
Discovering available feeds...
๐ท Cameras (2 found):
[1] Camera 0 (1280x720)
[2] Camera 1 (640x480)
๐ฅ๏ธ Screens (3 found):
[3] All Screens (3840x1080)
[4] Screen 1 (1920x1080)
[5] Screen 2 (1920x1080)
๐ช Windows (5 found):
[6] Visual Studio Code
[7] Google Chrome
[8] Discord
...
[0] Enter video file path
[q] Quit
------------------------------------------------------------
Select feed number: _
Command Line Live Streaming
# Stream a video file directly (no .sanchez conversion needed)
python -m sanchez live video.mp4
# Stream from camera (default: camera 0)
python -m sanchez live --camera
python -m sanchez live --camera 1
# Stream screen capture (default: all screens)
python -m sanchez live --screen
python -m sanchez live --screen 1
# Stream a specific window by title
python -m sanchez live --window "Visual Studio Code"
# With options
python -m sanchez live --camera -p 8080 --fps 30 -r 1280x720
python -m sanchez live video.mp4 -m multicast -H 239.0.0.1 --loop
Live Streaming Options
| Option | Description |
|---|---|
--camera [ID] |
Stream from camera device (default: 0) |
--screen [ID] |
Stream screen capture (default: 0 = all screens) |
--window TITLE |
Stream a specific window by title |
-H, --host |
Host/IP to stream to (default: 0.0.0.0) |
-p, --port |
Port number (default: 9999) |
-m, --mode |
tcp, udp, multicast, or broadcast |
--fps |
Frames per second (default: 24) |
-r, --resize |
Resize output (e.g., 1280x720) |
--loop |
Loop video files continuously |
Python Live Streaming API
from sanchez import (
LiveStreamServer,
FeedCapture,
FeedDiscovery,
VideoFeed,
FeedType,
interactive_feed_picker,
StreamMode
)
# Discover available feeds
feeds = FeedDiscovery.discover_all()
print(f"Cameras: {feeds['cameras']}")
print(f"Screens: {feeds['screens']}")
print(f"Windows: {feeds['windows']}")
# Stream from camera
from sanchez import stream_camera
stream_camera(device_id=0, host="0.0.0.0", port=9999, fps=24)
# Stream screen capture
from sanchez import stream_screen
stream_screen(monitor_id=0, host="0.0.0.0", port=9999, fps=15)
# Stream video file directly
from sanchez import stream_video_file
stream_video_file("video.mp4", host="0.0.0.0", port=9999, loop=True)
# Custom feed handling
feed = VideoFeed(
feed_type=FeedType.CAMERA,
name="Webcam",
description="USB Camera",
device_id=0
)
capture = FeedCapture(feed, fps=24)
with capture:
for frame in capture.frames():
# Process each frame (numpy RGB array)
process_frame(frame)
๐บ TV Channels & Playlists
Stream multiple videos sequentially like a TV channel! Mix .sanchez and .mp4 files in playlists for continuous streaming.
Channel Guide (Receiver Side)
Save your favorite channels and quickly tune in with an interactive selector!
Managing Channels
# Add a channel
python -m sanchez channels add "Rick's TV" 192.168.1.100 9999
# Add a multicast/satellite channel
python -m sanchez channels add "Satellite TV" 239.0.0.1 9999 -m multicast
# Add with description and mark as favorite
python -m sanchez channels add "Local News" 192.168.1.50 8080 -d "Morning news" -f
# List all saved channels
python -m sanchez channels list
# Remove a channel
python -m sanchez channels remove "Rick's TV"
# Toggle favorite status
python -m sanchez channels favorite "Satellite TV"
Watching Channels
# Interactive channel selector (with arrow key navigation!)
python -m sanchez watch
# Watch by channel name
python -m sanchez watch "Rick's TV"
# Watch by channel number
python -m sanchez watch 1
# Watch in fullscreen
python -m sanchez watch "Rick's TV" --fullscreen
# Record a channel to file
python -m sanchez watch "Rick's TV" -o recording.sanchez
Interactive Channel Selector
Run python -m sanchez watch to get a nice interactive UI:
============================================================
๐บ Sanchez Channel Guide
============================================================
โถ [1] โญ ๐บ Rick's TV 192.168.1.100:9999 (tcp)
[2] โญ ๐บ Satellite Feed 239.0.0.1:9999 (multicast)
[3] ๐ Local Server localhost:9999 (tcp)
[4] ๐ก UDP Stream 10.0.0.5:8080 (udp)
------------------------------------------------------------
โ/โ Navigate | Enter Select | 0-9 Channel #
Q Quit | A Add New | F Toggle Favorite
============================================================
3-Digit Channel Entry:
When you press number keys, a channel input overlay appears in the bottom-right:
โโโโโโโโโโโโโโโ
โ CH: 12_ โ
โ โโโโโโโโโโ โ
โโโโโโโโโโโโโโโ
- Type up to 3 digits to enter a channel number (supports channels 1-999)
- A countdown bar shows time remaining before auto-tuning
- After 2 seconds of no input, automatically tunes to that channel
- If you enter 3 digits, it tunes immediately
- Press Backspace to correct mistakes
- The overlay disappears after tuning
Navigation:
- Use โ/โ arrow keys to navigate
- Press Enter to watch the selected channel
- Press 0-9 to enter channel numbers (with overlay)
- Press F to toggle favorite (favorites appear first with โญ)
- Press Q to quit
Python Channel Guide API
from sanchez import ChannelGuide, SavedChannel, interactive_channel_selector
# Create/load channel guide
guide = ChannelGuide()
# Add a channel
channel = SavedChannel(
name="Rick's TV",
host="192.168.1.100",
port=9999,
mode="tcp",
description="Interdimensional Cable",
favorite=True
)
guide.add(channel)
# List channels
for ch in guide.list_channels():
print(f"{ch.name}: {ch.connection_string()}")
# Get channel by name or number
ch = guide.get("Rick's TV")
ch = guide.get_by_index(1)
# Interactive selector
selected = interactive_channel_selector()
if selected:
print(f"Tuning to: {selected.name}")
Playlist Formats
The channel feature supports multiple playlist formats:
| Format | Extension | Description |
|---|---|---|
| M3U | .m3u |
Standard playlist format (media players compatible) |
| JSON | .json |
Structured playlist with metadata |
| Text | .txt |
Simple list of file paths (one per line) |
| PLS | .pls |
Winamp-style playlist format |
Creating Playlists
M3U Format (playlist.m3u):
#EXTM3U
#EXTINF:-1,Episode 1 - Pilot
/videos/episode1.sanchez
#EXTINF:-1,Episode 2 - Ricksy Business
/videos/episode2.mp4
#EXTINF:-1,Interdimensional Cable
/videos/cable.sanchez
JSON Format (playlist.json):
{
"name": "Rick's TV Channel",
"mode": "shuffle_repeat",
"items": [
{"path": "/videos/episode1.sanchez", "name": "Pilot"},
{"path": "/videos/episode2.mp4", "name": "Ricksy Business"},
{"path": "/videos/cable.sanchez", "name": "Interdimensional Cable"}
]
}
Text Format (playlist.txt):
/videos/episode1.sanchez
/videos/episode2.mp4
/videos/cable.sanchez
Playlist Modes
| Mode | Description |
|---|---|
sequential |
Play videos in order, then stop (default) |
shuffle |
Randomize order, play once |
repeat_one |
Loop the current video forever |
repeat_all |
Loop the entire playlist forever |
shuffle_repeat |
Shuffle and repeat forever |
Command Line Channel Streaming
# Stream a playlist file
python -m sanchez channel --playlist videos.m3u
# Stream multiple video files directly
python -m sanchez channel video1.sanchez video2.mp4 video3.sanchez
# Shuffle mode
python -m sanchez channel --playlist tv.m3u --shuffle
# Repeat all videos forever
python -m sanchez channel --playlist tv.m3u --playlist-mode repeat_all
# Shuffle and repeat forever (TV station mode!)
python -m sanchez channel --playlist tv.m3u --playlist-mode shuffle_repeat
# Named channel with multicast
python -m sanchez channel --playlist tv.m3u -n "Rick's TV" -m multicast -H 239.0.0.1
# Stream all .sanchez files in a folder
python -m sanchez channel *.sanchez --playlist-mode repeat_all
# With channel text overlay
python -m sanchez channel --playlist tv.m3u --overlay "SPORTS TV" --overlay-position top-left
# Per-video text overlays (e.g., show "LIVE" for sports videos)
python -m sanchez channel *.sanchez --video-overlays "sports*.mp4:LIVE SPORTS" "news*.sanchez:BREAKING NEWS"
# Custom styling
python -m sanchez channel --playlist tv.m3u --overlay "MY CHANNEL" \
--overlay-position top-right --overlay-opacity 0.9 \
--overlay-size 32 --overlay-color "255,0,0"
# Dynamic queue - add videos while streaming
python -m sanchez channel --playlist tv.m3u --queue-file queue.txt
# Then add videos by appending paths to queue.txt
Channel Options
| Option | Description |
|---|---|
--playlist, -P |
Path to playlist file (.m3u, .json, .txt, .pls) |
-n, --name |
Channel name (displayed in console) |
--shuffle |
Shuffle playlist order |
--playlist-mode |
sequential, shuffle, repeat_one, repeat_all, shuffle_repeat |
-H, --host |
Host/IP to stream to (default: 0.0.0.0) |
-p, --port |
Port number (default: 9999) |
-m, --mode |
tcp, udp, multicast, or broadcast |
--fps |
Frames per second for .mp4 conversion (default: 24) |
-r, --resize |
Resize all videos (e.g., 1280x720) |
-o, --overlay |
Text overlay for channel branding |
--overlay-position |
Position: top-left, top-right, bottom-left, bottom-right, center, top-center, bottom-center |
--overlay-opacity |
Text opacity 0.0-1.0 (default: 0.8) |
--overlay-size |
Font size in pixels (default: 24) |
--overlay-color |
RGB color as R,G,B (default: 255,255,255) |
--video-overlays |
Per-video text overlays (pattern:text format) |
-l, --logo |
PNG logo overlay (supports transparency) |
--logo-position |
Logo position (default: top-left) |
--logo-opacity |
Logo opacity 0.0-1.0 (default: 0.8) |
--logo-scale |
Logo scale factor (default: 1.0) |
--video-logos |
Per-video PNG logos (pattern:path format) |
-q, --queue-file |
File to watch for adding videos to queue |
๐ Dynamic Text Overlays
Add dynamic text overlays to your streams - change text, position, and style while streaming!
CLI Examples:
# Simple channel branding
python -m sanchez channel --playlist tv.m3u --overlay "MY CHANNEL"
# Sports channel with custom position and color
python -m sanchez channel sports/*.mp4 --overlay "SPORTS TV" \
--overlay-position top-right --overlay-color "255,255,0" --overlay-size 28
# Per-video overlays (different text for different content)
python -m sanchez channel --playlist mixed.m3u \
--overlay "NEWS 24/7" \
--video-overlays "sports*.mp4:LIVE SPORTS" "weather*.mp4:WEATHER UPDATE"
Python API - Full Control:
from sanchez import ChannelServer, Playlist, OverlayManager
# Create a channel server with text overlays
server = ChannelServer()
# Set main channel overlay
server.set_overlay("SPORTS TV", position="top-left", font_size=28, color=(255, 255, 0))
# Add additional overlays (score, status, etc.)
server.add_overlay("score", "HOME 0 - 0 AWAY", position="top-center", font_size=24)
server.add_overlay("status", "LIVE", position="top-right", color=(255, 0, 0))
# Set per-video overlays
server.set_video_overlay("halftime*.mp4", "HALFTIME", position="center")
# Stream the playlist
playlist = Playlist.load("games.m3u")
server.stream_playlist(playlist, host="0.0.0.0", port=9999)
Dynamic Text Updates (during streaming):
import threading
import time
# Start streaming in background
def stream():
server.stream_playlist(playlist)
thread = threading.Thread(target=stream)
thread.start()
# Update overlays dynamically while streaming!
time.sleep(60)
server.set_text("score", "HOME 1 - 0 AWAY") # Update score
time.sleep(300)
server.set_text("status", "2ND HALF") # Update status
time.sleep(600)
server.set_default_text("SPORTS TV - GOAL!") # Flash message on main overlay
Advanced OverlayManager:
from sanchez import OverlayManager
# Create overlay manager for fine-grained control
manager = OverlayManager()
# Add multiple overlays
manager.add_overlay("channel", "ESPN", position="top-left", font_size=32)
manager.add_overlay("ticker", "Breaking: Big game tonight!", position="bottom-center", font_size=18)
manager.add_overlay("time", "LIVE", position="top-right", color=(255, 0, 0))
# Update text dynamically
manager.set_text("ticker", "Score update: Home leads 2-1")
manager.set_position("ticker", "bottom-left")
manager.set_color("time", (0, 255, 0)) # Change to green
# Remove an overlay
manager.remove_overlay("ticker")
# Apply to frames manually
frame = manager.apply(frame)
๏ฟฝ๏ธ PNG Logo Overlays
Add transparent PNG logos to your streams - perfect for channel branding with professional graphics!
CLI Examples:
# Simple channel logo (top-left corner)
python -m sanchez channel --playlist tv.m3u --logo "logo.png"
# Logo with custom position and opacity
python -m sanchez channel sports/*.mp4 --logo "espn_logo.png" \
--logo-position top-right --logo-opacity 0.9 --logo-scale 0.5
# Combine text overlay AND logo
python -m sanchez channel --playlist news.m3u \
--logo "news_logo.png" --logo-position top-left \
--overlay "BREAKING NEWS" --overlay-position bottom-center
# Per-video logos (different logos for different content)
python -m sanchez channel --playlist mixed.m3u \
--logo "main_logo.png" \
--video-logos "sports*.mp4:sports_logo.png" "news*.mp4:news_logo.png"
Python API - Full Control:
from sanchez import ChannelServer, Playlist, ImageOverlay
# Create a channel server with PNG logo
server = ChannelServer()
# Set main channel logo
server.add_logo("logo.png", position="top-left", opacity=0.9, scale=0.5)
# Add per-video logos (different logos for different content)
server.add_video_logo("sports*.mp4", "sports_logo.png")
server.add_video_logo("news*.mp4", "news_logo.png")
# Combine with text overlays
server.set_overlay("LIVE", position="top-right", color=(255, 0, 0))
# Stream the playlist
playlist = Playlist.load("channel.m3u")
server.stream_playlist(playlist, host="0.0.0.0", port=9999)
ImageOverlay Direct Usage:
from sanchez import ImageOverlay, OverlayManager
# Create image overlay directly
logo = ImageOverlay(
image_path="logo.png",
position="top-left",
opacity=0.8,
scale=0.5
)
# Load the image
logo.load()
# Add to overlay manager
manager = OverlayManager()
manager.add_image("channel_logo", logo)
# Apply to frames
frame = manager.apply(frame)
Supported Image Formats:
- PNG (recommended - supports transparency)
- JPEG, JPG (no transparency)
- BMP, WEBP, and other formats supported by PIL/OpenCV
Tips:
- Use PNG with transparency for professional-looking overlays
- Scale down large logos for better performance
- Combine multiple logos and text overlays for rich branding
- Use per-video logos to match content (sports logo for sports, news logo for news, etc.)
๏ฟฝ๐ฅ Dynamic Queue Management
Add, skip, and change videos while the channel is streaming - perfect for live TV stations!
Queue File Method:
# Start streaming with queue file watching
python -m sanchez channel --playlist initial.m3u --queue-file queue.txt
# In another terminal, add videos to the queue:
echo "/path/to/new_video.mp4" >> queue.txt
echo "/path/to/another.sanchez" >> queue.txt
Python Queue API:
from sanchez import Playlist, ChannelServer
import threading
# Create playlist
playlist = Playlist.load("initial.m3u")
# Watch a file for new videos
playlist.watch_queue_file("queue.txt")
# Add videos programmatically (thread-safe)
playlist.add("/path/to/new_video.mp4") # Add to end of queue
playlist.add_next("/path/to/priority.mp4") # Play next (after current video)
# Control playback
playlist.skip_current() # Skip to next video immediately
playlist.jump_to(5) # Jump to video at index 5
playlist.jump_to_title("Breaking News") # Jump to video by title (partial match)
playlist.replace_current("/path/to/replacement.mp4") # Replace currently playing
playlist.insert_and_play("/path/to/urgent.mp4") # Insert and immediately play
# Query the queue
upcoming = playlist.get_queue() # Get list of upcoming videos
playlist.clear_queue() # Clear all videos after current one
threading.Thread(target=add_video_later).start()
# Start streaming
server = ChannelServer()
server.stream_playlist(playlist)
Python Channel API
from sanchez import (
Playlist,
PlaylistItem,
PlaylistMode,
ChannelServer,
create_channel,
stream_channel,
StreamMode
)
# Create a playlist from files
playlist = create_channel([
"episode1.sanchez",
"episode2.mp4",
"episode3.sanchez"
], name="My Channel", mode=PlaylistMode.SHUFFLE_REPEAT)
# Or load from file
playlist = Playlist.from_file("tv.m3u")
playlist.mode = PlaylistMode.REPEAT_ALL
# Stream the channel
server = ChannelServer(mode=StreamMode.TCP_UNICAST)
server.stream_channel(playlist, host="0.0.0.0", port=9999)
# Multicast for satellite/IPTV
server = ChannelServer(mode=StreamMode.UDP_MULTICAST)
server.stream_channel(playlist, host="239.0.0.1", port=9999)
# Quick stream helper
stream_channel(
["video1.sanchez", "video2.mp4"],
host="0.0.0.0",
port=9999,
mode=PlaylistMode.REPEAT_ALL
)
# Access playlist items
for item in playlist.items:
print(f"{item.name}: {item.path} ({item.file_type})")
# Shuffle playlist
playlist.shuffle()
# Get next video (respects mode)
while True:
item = playlist.get_next()
if item is None:
break # End of sequential playlist
print(f"Now playing: {item.name}")
Receiving Channel Streams
Clients don't need to know about playlists - they just receive a continuous stream:
# Receive and play the channel
python -m sanchez receive 192.168.1.100 9999
# Record the stream (captures all videos as one)
python -m sanchez receive 192.168.1.100 9999 -o recording.sanchez
Example: 24/7 TV Station
Set up a continuous TV channel streaming all your .sanchez files:
# Create a playlist of all videos
ls *.sanchez > channel.txt
# Or create an M3U with nice names
cat > channel.m3u << EOF
#EXTM3U
#EXTINF:-1,Episode 1
episode1.sanchez
#EXTINF:-1,Episode 2
episode2.sanchez
#EXTINF:-1,Interdimensional Cable
cable.sanchez
EOF
# Start the 24/7 channel
python -m sanchez channel --playlist channel.m3u \
--playlist-mode shuffle_repeat \
-n "Interdimensional Cable TV" \
-m multicast -H 239.0.0.1
Example
Run the example script to see the format in action:
python example.py
This creates a test pattern video, saves it as .sanchez, reads info, extracts a frame, and decodes it back to MP4.
Get schwifty! ๐ธ
Project details
Release history Release notifications | RSS feed
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 dotsanchez_cbxnz-2.5.0.tar.gz.
File metadata
- Download URL: dotsanchez_cbxnz-2.5.0.tar.gz
- Upload date:
- Size: 81.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3017e3b8b91e898348d758e7a5ceac59ec53bf4367c7d4cdbcb189513574581a
|
|
| MD5 |
fba5bfea247f436e5409deefe61c63cf
|
|
| BLAKE2b-256 |
11b353924ddd37103f91dc666792ae99004541480a3057232784178dc94597fa
|
File details
Details for the file dotsanchez_cbxnz-2.5.0-py3-none-any.whl.
File metadata
- Download URL: dotsanchez_cbxnz-2.5.0-py3-none-any.whl
- Upload date:
- Size: 69.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bc0c80bca03a15db86edd128fdffbe8695267b7cec79f66cfe3bd64b0b9b7a0
|
|
| MD5 |
72ce5ae7b53eb7b1c037eb285f595ded
|
|
| BLAKE2b-256 |
6e4cc6194eeeb9b6a2b2c8a0cd24c7d65ea49ed46143f6347216a9741b7ecb4f
|