Skip to content

GhostStream turns any PC into a GPU–powered transcoding backend for your self-hosted apps. HLS, ABR, HDR→SDR, hardware detection, zero config.

License

Notifications You must be signed in to change notification settings

BleedingXiko/GhostStream

Repository files navigation

GhostStream

Open-Source Video Transcoding Server

License: MIT Python 3.10+ Platform

GhostStream is a hardware-accelerated video transcoding server with automatic GPU detection, adaptive bitrate streaming, and minimal configuration. It serves as the transcoding backend for GhostHub but can be used standalone.

Quick Start

Pre-built Binaries

Platform Download Run
Windows GhostStream.exe Double-click
Linux GhostStream-Linux chmod +x && ./GhostStream-Linux
macOS GhostStream-macOS chmod +x && ./GhostStream-macOS

Requires FFmpeg. The application will provide installation instructions if FFmpeg is not found.

From Source

git clone https://github.com/BleedingXiko/GhostStream.git
cd GhostStream
python run.py

The launcher creates a virtual environment, installs dependencies, and starts the server.

SDK Installation

Python:

pip install ghoststream              # SDK only (lightweight)
pip install ghoststream[server]      # Full server with all dependencies

JavaScript/TypeScript:

npm install ghoststream-sdk

Usage

Python SDK (recommended):

from ghoststream import GhostStreamClient, TranscodeStatus

client = GhostStreamClient(manual_server="localhost:8765")

# Synchronous (Flask/gevent compatible)
job = client.transcode_sync(source="https://example.com/video.mp4", resolution="720p")
print(f"Stream URL: {job.stream_url}")

# Or async
async with GhostStreamClient(manual_server="localhost:8765") as client:
    job = await client.transcode(source="https://example.com/video.mp4")
    print(f"Stream URL: {job.stream_url}")

JavaScript/TypeScript:

import { GhostStreamClient } from 'ghoststream-sdk';

const client = new GhostStreamClient('localhost:8765');
const job = await client.transcode({ source: 'https://example.com/video.mp4', resolution: '720p' });
console.log(`Stream URL: ${job.streamUrl}`);

curl:

curl -X POST http://localhost:8765/api/transcode/start \
  -H "Content-Type: application/json" \
  -d '{"source": "https://example.com/video.mp4", "mode": "stream"}'

See the examples/ directory for additional usage examples.

Features

  • HLS Streaming - Real-time transcoding with immediate playback
  • Adaptive Bitrate (ABR) - Multiple quality variants for bandwidth adaptation
  • Subtitle Muxing - Native WebVTT subtitle support in HLS streams
  • HDR to SDR - Automatic tone mapping for HDR content
  • Codec Support - H.264, H.265/HEVC, VP9, AV1
  • Batch Processing - Queue multiple files with optional two-pass encoding
  • Hardware Acceleration - NVIDIA NVENC, Intel QuickSync, AMD AMF, Apple VideoToolbox
  • Automatic Fallback - Falls back to software encoding if hardware fails
  • Thermal Management - Reduces load when GPU temperature is high

Supported Hardware Encoders

Platform Encoder Detection
NVIDIA NVENC Automatic via nvidia-smi
Intel QuickSync Automatic via VA-API
AMD AMF/VCE Automatic
Apple VideoToolbox Native macOS support
CPU libx264/libx265 Always available

API Reference

Endpoints

Method Endpoint Description
POST /api/transcode/start Start a transcoding job
GET /api/transcode/{id}/status Get job status & progress
POST /api/transcode/{id}/cancel Cancel a job
DELETE /api/transcode/{id} Delete job & cleanup
GET /api/health Health check
GET /api/capabilities Hardware & codec info
WS /ws/progress Real-time progress via WebSocket

Start Transcode Request

{
  "source": "https://example.com/video.mp4",
  "mode": "stream",           // "stream", "abr", or "batch"
  "output": {
    "resolution": "720p",     // "4k", "1080p", "720p", "480p", "original"
    "video_codec": "h264",    // "h264", "h265", "vp9", "av1"
    "audio_codec": "aac",     // "aac", "opus", "copy"
    "hw_accel": "auto"        // "auto", "nvenc", "qsv", "software"
  },
  "start_time": 0,            // Seek to position (seconds)
  "subtitles": [              // Optional: Subtitle tracks to mux
    {
      "url": "https://example.com/subtitle.vtt",
      "label": "English",
      "language": "en",
      "default": true
    }
  ]
}

Response

{
  "job_id": "abc-123",
  "status": "processing",
  "stream_url": "http://localhost:8765/stream/abc-123/master.m3u8",
  "progress": 0
}

Examples

File Description
demo.py Basic demo with auto-play
demo.html Browser-based demo
minimal.py Minimal Python example
quickstart.py Interactive examples
curl_examples.md HTTP/curl commands
web_player.html Full-featured web player

Running HTML Examples

The HTML examples must be served over HTTP due to browser CORS restrictions:

# 1. Start GhostStream
python run.py

# 2. In another terminal, serve the examples
cd examples
python -m http.server 8080

# 3. Open in browser
#    http://localhost:8080/demo.html
#    http://localhost:8080/web_player.html

Configuration

Create ghoststream.yaml to customize (optional):

server:
  host: 0.0.0.0
  port: 8765

transcoding:
  max_concurrent_jobs: 2
  segment_duration: 4
  tone_map_hdr: true
  retry_count: 3

hardware:
  prefer_hw_accel: true
  fallback_to_software: true

GhostHub Integration

GhostStream serves as the transcoding backend for GhostHub.

Architecture

┌─────────────────────────────────┐      ┌─────────────────────────────────┐
│        Raspberry Pi             │      │         Your PC                 │
│  ┌───────────────────────────┐  │      │  ┌───────────────────────────┐  │
│  │       GhostHub            │  │ WiFi │  │      GhostStream          │  │
│  │    (Media Server)         │◄─┼──────┼─►│   (GPU Transcoder)        │  │
│  └───────────────────────────┘  │      │  └───────────────────────────┘  │
└─────────────────────────────────┘      └─────────────────────────────────┘
  • Auto-Discovery: GhostStream advertises via mDNS (_ghoststream._tcp.local)
  • On-Demand: Transcoding occurs only when requested
  • Local Network: No internet connection required

Python SDK

pip install ghoststream
from ghoststream import GhostStreamClient, TranscodeStatus

# Auto-discover on network
client = GhostStreamClient()
client.start_discovery()

# Or connect directly
client = GhostStreamClient(manual_server="192.168.1.100:8765")

# Synchronous API (Flask/gevent compatible)
job = client.transcode_sync(
    source="http://pi:5000/media/video.mkv",
    resolution="1080p"
)
if job.status != TranscodeStatus.ERROR:
    print(job.stream_url)

# Async API
job = await client.transcode(source="http://pi:5000/media/video.mkv")

WebSocket Progress

# Subscribe to job updates
ws.send({"type": "subscribe", "job_ids": ["job-123"]})

# Receive real-time progress
{"type": "progress", "job_id": "job-123", "data": {"progress": 45.2}}
{"type": "status_change", "job_id": "job-123", "data": {"status": "ready"}}

Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

# Development setup
git clone https://github.com/BleedingXiko/GhostStream.git
cd GhostStream
python -m venv venv && source venv/bin/activate  # or venv\Scripts\activate on Windows
pip install -r requirements.txt
python -m ghoststream --log-level DEBUG

License

MIT License - see LICENSE for details.

About

GhostStream turns any PC into a GPU–powered transcoding backend for your self-hosted apps. HLS, ABR, HDR→SDR, hardware detection, zero config.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published