Skip to main content

discord-video-stream-py Logo

discord-video-stream-py

Stream video and audio directly into Discord voice channels (Go Live / webcam) using Python. No Node.js required.

Inspired by the TypeScript @dank074/discord-video-stream, built from the ground up for Python developers.

PyPI Python License: MIT


Features

  • 🎬 H264 & VP8 video streaming via Discord Go Live
  • 🎙️ Opus audio (48 kHz stereo, 20 ms frames)
  • 🔐 Full SRTP encryption — XSalsa20-Poly1305, XChaCha20-Poly1305, and AES-256-GCM
  • 📺 Webcam mode (non-Go Live) and Go Live streaming
  • 🌐 Online sources via yt-dlp (YouTube, Twitch, 1000+ sites)
  • ⏯️ Full playback controls: pause, resume, seek, stop
  • 🔁 Auto-reconnect with exponential backoff on voice gateway drops
  • 🎛️ Events system — on_start, on_finish, on_error, on_progress
  • 📐 Resolution presets — 480p, 720p, 1080p, or source quality
  • 🔌 Familiar discord.py-style async API

System Requirements

  • Python 3.10+
  • (Optional) ffmpeg and yt-dlp installed in your system PATH.

[!NOTE] Zero Setup Required: The library automatically downloads and bundles cross-platform static binaries for ffmpeg and yt-dlp (supporting Windows x64, Linux x64/arm64, and macOS Intel/Apple Silicon). The library will fall back to your system's ffmpeg or yt-dlp if the bundled binaries are not found.


Installation

pip install discord-video-stream-py

Quick Start

Stream a local file

import discord
from discord_video_stream import Streamer, VideoPlayer

client = discord.Client()
streamer = Streamer(client)

@client.event
async def on_ready():
    print(f"Logged in as {client.user}")
    await streamer.join_voice(guild_id=123456789, channel_id=987654321)
    udp = await streamer.create_stream(resolution="720p", fps=30, codec="h264")
    player = VideoPlayer("movie.mp4", udp)
    await player.play()

client.run("YOUR_USER_TOKEN")

Stream from YouTube

player = VideoPlayer("https://www.youtube.com/watch?v=dQw4w9WgXcQ", udp)
await player.play()

VP8 & Webcam mode

udp = await streamer.create_stream(
    resolution="480p", fps=30,
    codec="vp8", stream_type="webcam"
)
player = VideoPlayer("video.mp4", udp, codec="vp8")
await player.play()

Playback Controls

player.pause()
await player.seek(120)  # seek to 2:00
player.resume()
player.stop()

Events

@player.on("start")
async def on_start():
    print("Streaming started!")

@player.on("finish")
async def on_finish():
    await streamer.stop_stream()

@player.on("error")
async def on_error(exc):
    print(f"Stream error: {exc}")

API Reference

Streamer(client)

Wraps a discord.py-self Client and manages the stream lifecycle.

Method Description
await join_voice(guild_id, channel_id) Join a voice channel
await create_stream(resolution, fps, codec, stream_type) Start streaming, returns MediaUdp
await stop_stream() Stop the stream and clean up
await leave_voice(guild_id) Leave the voice channel

VideoPlayer(source, udp, **kwargs)

High-level media player with events.

Method Description
await play() Start playback
pause() Pause (FFmpeg keeps running)
resume() Resume playback
await seek(seconds) Seek to position (restarts FFmpeg)
stop() Stop playback
on(event)(callback) Register event callback

Enums

Enum Values
Codec "h264", "vp8"
StreamType "go_live", "webcam"
Resolution "480p", "720p", "1080p", "source"

Development Status

Phase Status Description
1 — Foundation ✅ Complete Voice Gateway + Audio streaming
2 — Video (H264) ✅ Complete H264 Go Live streaming + FU-A fragmentation
3 — VP8 + Webcam ✅ Complete VP8 codec + webcam mode
4 — yt-dlp + DX ✅ Complete Online sources + player events + seek
5 — Release 🚧 In Progress PyPI publish + docs + tests

Architecture

discord_video_stream/
├── __init__.py          # Public API: Streamer, VideoPlayer, enums
├── streamer.py          # Main entry point — wraps discord.py-self client
├── bin/                 # Bundled cross-platform binaries (FFmpeg & yt-dlp)
│   ├── windows-x64/
│   ├── linux-x64/
│   ├── linux-arm64/
│   ├── macos-x64/
│   └── macos-arm64/
├── voice/
│   ├── gateway.py       # Voice WebSocket (all OPs, heartbeat, resume)
│   ├── udp.py           # MediaUdp — UDP socket, RTP dispatch, keepalive
│   ├── rtp.py           # RTP packet builder (audio + video + extension)
│   └── encryption.py    # XSalsa20 / XChaCha20 / AES-256-GCM encryption
├── codecs/
│   ├── h264.py          # NAL unit packetizer (FU-A fragmentation, SPS/PPS)
│   ├── vp8.py           # VP8 RTP packetizer (RFC 7741)
│   └── opus.py          # Opus audio framer (48kHz, 20ms)
├── media/
│   ├── player.py        # MediaPlayer + VideoPlayer — FFmpeg → RTP pipeline
│   ├── ffmpeg.py        # FFmpeg subprocess builder (H264/VP8/Opus)
│   └── ytdlp.py         # yt-dlp URL resolver
└── utils/
    ├── ssrc.py          # SSRC generation + video/RTX offsets
    └── binaries.py      # Cross-platform binary helper/resolver

Contributing

PRs welcome! See docs/getting-started.md for a development setup guide.

git clone https://github.com/subhobhai943/discord-video-stream-py.git
cd discord-video-stream-py
python -m venv venv && source venv/bin/activate
pip install -e ".[dev]"
pytest

License

MIT — see LICENSE.

Metadata

Release files for discord-video-stream-py 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for discord-video-stream-py 0.1.1
File Size Uploaded
discord_video_stream_py-0.1.1.tar.gz 729.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for discord-video-stream-py 0.1.1
File Interpreter ABI Platform
discord_video_stream_py-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 770.2 kB

Release files / discord_video_stream_py-0.1.1.tar.gz

Download URL discord_video_stream_py-0.1.1.tar.gz
Size 729.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f1de3a2b0cb151df80aecd5b71f5b5b8690938885b1dd69847af2e318f368b5c
BLAKE2b-256 checksum
How to use checksums
7ea6f4ffac58fcea425155858cdd4abef8340b302534b832c74379ef74ece3e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release files / discord_video_stream_py-0.1.1-py3-none-any.whl

Download URL discord_video_stream_py-0.1.1-py3-none-any.whl
Size 41.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef81685b8d1d00e738bcb6f62929af720b1e5924a9d34222c5334c5e0bb8d6f9
BLAKE2b-256 checksum
How to use checksums
ef0b79623965e6840a3d4822e1eb033b22b1b51190c7816db6ffa26bd5ec7d18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page