Developer Guide
Technical architecture, API reference, Huawei Cloud VOD/OBS integration, and server installer documentation for the OneSignal Broadcast & Ad Insertion Platform.
Architecture Overview
The OneSignal platform follows a modular, low-latency broadcast and dynamic ad-insertion architecture:
- Multi-Protocol Ingest: Nginx with
ngx_rtmp_modulehandles RTMP push ingest (:1935/live/<stream_key>), whileMediaMTX(onesignal-srt-gateway.serviceonUDP :5000) accepts SRT feeds and relays them into local RTMP. - Unified Transcoder & Midstream Ad Compositor:
scripts/transcoder_manager.py(onesignal-transcoder.service) manages per-stream FFmpeg pipelines, burns in dynamic station watermarks, and composites Fullscreen Commercials, L-Bar Squeezebacks, and Lower-Third Overlays directly onto the output stream without dropping viewer sessions. - Station Ident dHash Detector: OpenCV frame analysis monitors each stream against its configured Station Ident reference video to trigger automatic midstream commercial breaks.
- HLS Delivery & 24-Hour DVR Proxy: Nginx serves live HLS segments from
/opt/onesignal/hls_branded/while the Flask internal HLS proxy (app/api/routes.py&app/services/routing_service.py) rewrites manifests with wall-clock program timestamps and seamlessly falls back to Huawei Cloud OBS for historical DVR segments. - Backend API & Workers: Flask + Gunicorn (
onesignal.serviceon127.0.0.1:5001) handles stream lifecycle, per-stream YouTube channel mapping, Snipping & Huawei VOD processing, Ad Manager campaigns/schedules, Proxy rotation, and RBAC authentication (admin,ad_admin,user). - Database & Telemetry Store: MySQL/MariaDB stores all 15 relational tables (Users, Streams, Destinations, Campaigns, Commercials, 24-Hour Slots, Schedules, Proofs, Audit Logs, and System Settings), while Redis caches real-time stream health and compositor state.
Core Subsystems
1. HLS Proxy, Per-Stream YouTube Mapping & DVR Rewriting
Located in backend/app/api/routes.py, backend/app/api/ads_routes.py, and backend/app/services/routing_service.py.
- Each
Streammodel (backend/app/domain/models.py) includes a dedicatedyoutube_urlcolumn configurable from both Stream Details → Source Setup and Ad Manager → Settings (linked to the Direct Stream URL dropdown). - Rewrites
#EXTINFtags with wall-clock timestamps for frame-accurate DVR scrubbing and snipping. - Redirects segment requests to Huawei Cloud OBS when older DVR segments have aged out of local disk cache.
2. Snipping Engine & Huawei Cloud VOD Processing
- Frontend Workspace:
frontend/clipping.htmlprovides the 24-hour continuous DVR timeline, keyboard Mark-In/Mark-Out controls, Snipping & Huawei VOD engine mode selector, and compact Social Share modal. - Clip & VOD Service:
backend/app/services/clip_service.pyextracts MP4 clips via FFmpeg, uploads completed clips to Huawei Cloud OBS (obs_service.py), and triggers asynchronous cloud transcoding viaVodService.trigger_transcoding_async()inbackend/app/services/vod_service.py. - Commercial Asset VOD Processing: Uploaded commercial videos in
backend/app/api/ads_routes.pyare normalized for broadcast playout and automatically registered/transcoded on Huawei Cloud VOD whenHUAWEI_VOD_PROJECT_IDis configured.
3. Integrated Ad Manager & 24-Hour Scheduler
- Frontend:
frontend/advertising.htmlandfrontend/js/advertising.jsprovide the Live Playout Studio, Campaigns manager (with direct Upload Material actions per campaign), Ads Library, 24-Hour Scheduler grid, Proof-of-Play reports, and real-time compositor logs. - Backend API:
backend/app/api/ads_routes.pyenforces campaign activation checks (preventing disabled or paused campaigns from being scheduled), manages per-stream Station Idents (ads_stream_idents), and generates PDF/CSV proof-of-play certificates.
4. Proxy Management & Role-Based Access Control (RBAC)
- User Roles: Supports
admin(Full System Administrator),ad_admin(Advertisement Admin), anduser(Standard Operator with per-stream access). Managed infrontend/admin.html(#tab-users) andfrontend/js/users.jswith instant search and role filtering. - Proxy Pool Service:
backend/app/services/proxy_service.pyand/api/admin/proxiesinbackend/app/api/routes.pymanage/opt/onesignal/backend/proxies.json, supporting Webshare API synchronization, custom proxy entries, and one-click active proxy rotation inAdministration → Proxies(#tab-proxies).
Codebase Structure
/opt/onesignal/
├── backend/ # Flask Application & SQLAlchemy ORM
│ ├── app/
│ │ ├── api/ # REST Blueprints (routes.py, ads_routes.py, studio_api.py)
│ │ ├── domain/ # SQLAlchemy Models (models.py - 15 tables)
│ │ ├── services/ # Core Logic (clip_service, vod_service, obs_service, proxy_service)
│ │ └── repositories/ # Data Access Layer
│ ├── venv/ # Isolated Python 3 Virtual Environment
│ ├── .env # Runtime Environment & Huawei Cloud / DB Config
│ └── proxies.json # Outbound Proxy Pool Configuration
├── frontend/ # Static Web Portal (index, details, clipping, advertising, admin, guide)
├── scripts/ # Unified Transcoder & Compositor (transcoder_manager.py)
├── deploy/ # Guided Server Installer & Package Builder
│ ├── build_package.sh # Builds clean onesignal-installer-package.tar.gz
│ ├── install_onesignal.sh # 8-Step Guided Server Installer (Ubuntu/Debian)
│ ├── seed_starter_data.py # Provisions DB tables, starter streams, sample MP4s & campaign
│ └── INSTALL.md # Server Installation Reference
└── logs/ # Gunicorn, FFmpeg, and Transcoder logs
Environment & Runtime Configuration
Configuration is stored in /opt/onesignal/backend/.env and synchronized with the system_settings table via Administration → Huawei Cloud & OBS:
DATABASE_URL: MySQL SQLAlchemy connection URI (mysql+pymysql://onesignal:...@127.0.0.1/onesignal).OBS_ACCESS_KEY&OBS_SECRET_KEY: Huawei Cloud AK/SK credentials.OBS_BUCKET,OBS_BUCKET_REGION,OBS_ENDPOINT: Huawei OBS bucket for DVR recordings, clips, and ad assets.HUAWEI_LIVE_INGEST_URL&HUAWEI_LIVE_OUTPUT_URL: Huawei Cloud Live RTMP ingest and HLS playback endpoints.HUAWEI_VOD_PROJECT_ID: Huawei Cloud project ID used byVodServicefor cloud video transcoding.
Building & Running the Guided Server Installer
To package the entire application (excluding test-server credentials or recordings) into a self-contained installer archive:
./deploy/build_package.sh
# Outputs: deploy/onesignal-installer-package.tar.gz
To install on a fresh Ubuntu 22.04 / 24.04 LTS or Debian 12 server with live step-by-step progress:
tar -xzf onesignal-installer-package.tar.gz
cd onesignal-installer
sudo ./install.sh --domain live.yourdomain.com
- Systemd Services:
onesignal.service(Gunicorn API),onesignal-srt-gateway.service(MediaMTX SRT),onesignal-transcoder.service(Unified Transcoder & Compositor),nginx.service,mysql.service, andredis-server.service. - Starter Seed Data:
deploy/seed_starter_data.pyautomatically creates all 15 MySQL tables, 8 hourly ad segments, 3 FFmpeg sample videos, 2 demo streams, and a starter campaign.