# O11 Streaming Panel Scripts

## Overview

These scripts have been converted from XAccel format to work with the O11 streaming panel. Each script supports:
- **Internal CDM**: License proxy mode where the panel handles Widevine challenges
- **External CDM**: Direct key extraction using pywidevine library
- **Event Scheduling**: Support for scheduled events with start/end times

## Installation

```bash
pip install -r requirements.txt
```

You also need a valid Widevine device file (`WVD.wvd`) placed in each script's directory.

## Directory Structure

```
o11/
├── o11.py                 # Core library (copy to each script folder)
├── requirements.txt       # Python dependencies
├── README.md             # This file
├── A1XploreBG/
│   ├── A1XploreBG.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd           # Required
├── Allente/
│   ├── Allente.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── BlueTV/
│   ├── BlueTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── BallySports/
│   ├── BallySports.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── FibeTV/
│   ├── FibeTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CosmoteTV/
│   ├── CosmoteTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Dazn/
│   ├── Dazn.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SaltTV/
│   ├── SaltTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd           # Not required (clear streams)
├── Magenta/
│   ├── Magenta.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RTL/
│   ├── RTL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Tring/
│   ├── Tring.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalPlus/
│   ├── CanalPlus.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DirectTV/
│   ├── DirectTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── StcTV/
│   ├── StcTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── NowTV/
│   ├── NowTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CytaVision/
│   ├── CytaVision.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TivifyTV/
│   ├── TivifyTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Televio/
│   ├── Televio.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd           # Not required (clear streams)
├── SkyGo/
│   ├── SkyGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── UFC/
│   ├── UFC.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalDigitaal/
│   ├── CanalDigitaal.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Viaplay/
│   ├── Viaplay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Videoland/
│   ├── Videoland.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Spectrum/
│   ├── Spectrum.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Amazon/
│   ├── Amazon.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── WOWTV/
│   ├── WOWTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── VectraTV/
│   ├── VectraTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── StarPlus/
│   ├── StarPlus.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TwistTV/
│   ├── TwistTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CignalPlay/
│   ├── CignalPlay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SwitchTV/
│   ├── SwitchTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Digitalb/
│   ├── Digitalb.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── A1XploreHR/
│   ├── A1XploreHR.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DaznV23/
│   ├── DaznV23.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DirecTVGo/
│   ├── DirecTVGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SFR/
│   ├── SFR.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TOD/
│   ├── TOD.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SuperNova/
│   ├── SuperNova.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Tring/
│   ├── Tring.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── trueID/
│   ├── trueID.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Allente/
│   ├── Allente.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── BallySports/
│   ├── BallySports.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SaltTV/
│   ├── SaltTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Viaplay/
│   ├── Viaplay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Videoland/
│   ├── Videoland.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Spectrum/
│   ├── Spectrum.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CytaVision/
│   ├── CytaVision.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CosmoteTV/
│   ├── CosmoteTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── OrangeTV/
│   ├── OrangeTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── IrisTV/
│   ├── IrisTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── MeoGo/
│   ├── MeoGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Pickx/
│   ├── Pickx.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RMCSport/
│   ├── RMCSport.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── VooTV/
│   ├── VooTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SunriseTV/
│   ├── SunriseTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── WaipuTV/
│   ├── WaipuTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Sling/
│   ├── Sling.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PolsatBoxGo/
│   ├── PolsatBoxGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PlayerPL/
│   ├── PlayerPL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── O2TV/
│   ├── O2TV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SaltTV/
│   ├── SaltTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CignalPlay/
│   ├── CignalPlay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Dazn/
│   ├── Dazn.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── UFC/
│   ├── UFC.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TwistTV/
│   ├── TwistTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── StcTV/
│   ├── StcTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Allente/
│   ├── Allente.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── F1TV/
│   ├── F1TV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DiscoveryPlus/
│   ├── DiscoveryPlus.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalPlus/
│   ├── CanalPlus.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DirectTV/
│   ├── DirectTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── BallySports/
│   ├── BallySports.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── FibeTV/
│   ├── FibeTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── IrisTV/
│   ├── IrisTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PlutoTV/
│   ├── PlutoTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── NHL/
│   ├── NHL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SlingTV/
│   ├── SlingTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── FuboTV/
│   ├── FuboTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── A1XploreBG/
│   ├── A1XploreBG.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalPlusPL/
│   ├── CanalPlusPL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── DirecTVGo/
│   ├── DirecTVGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalPlusAF/
│   ├── CanalPlusAF.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── ViaPlay/
│   ├── ViaPlay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── WaipuTV/
│   ├── WaipuTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Tring/
│   ├── Tring.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── VideoLand/
│   ├── VideoLand.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TivifyTV/
│   ├── TivifyTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TwistTV/
│   ├── TwistTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── VooTV/
│   ├── VooTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SwitchTV/
│   ├── SwitchTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SunriseTV/
│   ├── SunriseTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RMCSport/
│   ├── RMCSport.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RTLPlus/
│   ├── RTLPlus.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PlutoTV/
│   ├── PlutoTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── OrangeTV/
│   ├── OrangeTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Supernova/
│   ├── Supernova.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Movistar/
│   ├── Movistar.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Kayo/
│   ├── Kayo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Magenta/
│   ├── Magenta.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── MeoGo/
│   ├── MeoGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CignalPlay/
│   ├── CignalPlay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── NowPlayer/
│   ├── NowPlayer.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Fubo/
│   ├── Fubo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CanalPlusPL/
│   ├── CanalPlusPL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Dazn/
│   ├── Dazn.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── A1XploreBG/
│   ├── A1XploreBG.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Peacock/
│   ├── Peacock.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── IrisTV/
│   ├── IrisTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CytaVision/
│   ├── CytaVision.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── Spectrum/
│   ├── Spectrum.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SaltTV/
│   ├── SaltTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── UFC/
│   ├── UFC.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── NjpwWorld/
│   ├── NjpwWorld.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CosmoteTV/
│   ├── CosmoteTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PlutoTV/
│   ├── PlutoTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── CignalPlay/
│   ├── CignalPlay.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── OrangeTV/
│   ├── OrangeTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TwistTV/
│   ├── TwistTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── NowPlayer/
│   ├── NowPlayer.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── PlayerPL/
│   ├── PlayerPL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RTL/
│   ├── RTL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── SunriseTV/
│   ├── SunriseTV.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── MeoGo/
│   ├── MeoGo.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── TelevioPL/
│   ├── TelevioPL.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
├── RMCSport/
│   ├── RMCSport.py
│   ├── o11.py
│   ├── requirements.txt
│   └── WVD.wvd
└── Pickx/
    ├── Pickx.py
    ├── o11.py
    ├── requirements.txt
    └── WVD.wvd
```

## Common Parameters

All scripts accept these standard parameters:

| Parameter | Description |
|-----------|-------------|
| `user` | Username/email for authentication |
| `password` | Password for authentication |
| `action` | Action to perform (see below) |
| `id` | Channel/content ID |
| `cdm` | CDM mode: `internal` or `external` |
| `challenge` | Base64 Widevine challenge (for internal CDM) |
| `pssh` | PSSH data (optional) |
| `bind` | Network interface to bind to |
| `proxy` | HTTP/HTTPS proxy URL |
| `doh` | DNS-over-HTTPS server URL |
| `worker` | Worker server URL for request routing |

## Actions

### `login`
Authenticate and save tokens for future use.

```bash
python3 ScriptName.py user=email@example.com password=mypassword action=login
```

### `channels`
List available channels in JSON format for O11 panel.

```bash
python3 ScriptName.py user=email@example.com action=channels
```

### `events`
List scheduled events with start/end times.

```bash
python3 ScriptName.py user=email@example.com action=events
```

### `manifest`
Get manifest URL and metadata for a specific channel.

```bash
python3 ScriptName.py user=email@example.com action=manifest id=CHANNEL_ID
```

### `cdm` (internal)
Process Widevine license challenge through the service.

```bash
python3 ScriptName.py user=email@example.com action=cdm cdm=internal id=CHANNEL_ID challenge=BASE64_CHALLENGE
```

### `cdm` (external)
Extract Widevine keys directly using pywidevine.

```bash
python3 ScriptName.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### `heartbeat`
Keep session alive (used by panel for periodic pings).

```bash
python3 ScriptName.py user=email@example.com action=heartbeat
```

## Script-Specific Usage

### A1XploreBG (Bulgaria)

```bash
# Login
python3 A1XploreBG.py user=myuser password=mypass action=login

# List channels
python3 A1XploreBG.py user=myuser action=channels

# Get keys externally
python3 A1XploreBG.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### Allente (Nordic)

Supports regions: `cdno` (Norway), `cddk` (Denmark), `cdse` (Sweden)

```bash
# Login with region
python3 Allente.py user=myuser password=mypass region=cdse action=login

# List channels
python3 Allente.py user=myuser action=channels

# Get manifest with stream ID
python3 Allente.py user=myuser action=manifest id=CHANNEL_ID streamId=STREAM_ID
```

### BlueTV (Switzerland)

Uses token-based authentication. Get token from browser DevTools.

```bash
# Save token
python3 BlueTV.py user=myuser token=YOUR_BEARER_TOKEN action=login

# List channels
python3 BlueTV.py user=myuser action=channels

# Get keys
python3 BlueTV.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### BallySports (USA)

```bash
# Login
python3 BallySports.py user=email@example.com password=mypass action=login

# List live games
python3 BallySports.py user=email@example.com action=channels

# Get keys
python3 BallySports.py user=email@example.com action=cdm cdm=external id=VIDEO_ID
```

### FibeTV / Bell (Canada)

```bash
# Login
python3 FibeTV.py user=myuser password=mypass action=login

# List channels
python3 FibeTV.py user=myuser action=channels

# Get manifest
python3 FibeTV.py user=myuser action=manifest id=CHANNEL_NUMBER mergeId=MERGE_ID

# Get keys
python3 FibeTV.py user=myuser action=cdm cdm=external id=CHANNEL_NUMBER mergeId=MERGE_ID
```

### CosmoteTV (Greece)

```bash
# Login (may require PIN for profile selection)
python3 CosmoteTV.py user=myuser password=mypass pin=1234 action=login

# List channels
python3 CosmoteTV.py user=myuser action=channels

# Get manifest
python3 CosmoteTV.py user=myuser action=manifest id=CHANNEL_GUID

# Get keys
python3 CosmoteTV.py user=myuser action=cdm cdm=external id=CHANNEL_GUID
```

### DAZN (Global Sports)

```bash
# Login
python3 Dazn.py user=email@example.com password=mypass action=login

# List live events
python3 Dazn.py user=email@example.com action=channels

# List events with scheduling
python3 Dazn.py user=email@example.com action=events

# Get manifest (with optional age verification PIN)
python3 Dazn.py user=email@example.com action=manifest id=ASSET_ID pin=1234

# Get keys
python3 Dazn.py user=email@example.com action=cdm cdm=external id=ASSET_ID
```

### SaltTV (Switzerland)

Non-DRM streams - no Widevine required.

```bash
# Login
python3 SaltTV.py user=myuser password=mypass action=login

# List channels
python3 SaltTV.py user=myuser action=channels

# Get manifest
python3 SaltTV.py user=myuser action=manifest id=CHANNEL_CID
```

### MagentaTV (Germany/Telekom)

```bash
# Login
python3 Magenta.py user=myuser password=mypass action=login

# List channels
python3 Magenta.py user=myuser action=channels

# Get manifest
python3 Magenta.py user=myuser action=manifest id=MEDIA_PID

# Get keys
python3 Magenta.py user=myuser action=cdm cdm=external id=MEDIA_PID
```

### RTL+ (Germany)

```bash
# Login
python3 RTL.py user=email@example.com password=mypass action=login

# List channels
python3 RTL.py user=email@example.com action=channels

# List events (includes live events)
python3 RTL.py user=email@example.com action=events

# Get manifest
python3 RTL.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 RTL.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### Tring (Albania)

```bash
# Login
python3 Tring.py user=myuser password=mypass action=login

# List channels
python3 Tring.py user=myuser action=channels

# Get manifest
python3 Tring.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 Tring.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### Canal+ (France/Poland/Africa)

Uses passId from browser cookies instead of username/password.

```bash
# Save passId (get from browser DevTools -> Cookies)
python3 CanalPlus.py passId=FR_XXXXXXXX action=login

# List channels
python3 CanalPlus.py passId=FR_XXXXXXXX action=channels

# Get manifest
python3 CanalPlus.py passId=FR_XXXXXXXX action=manifest id=EPG_ID

# Get keys
python3 CanalPlus.py passId=FR_XXXXXXXX action=cdm cdm=external id=EPG_ID
```

### DirecTV Stream (USA)

Uses tToken and refreshToken from browser DevTools.

```bash
# Save tokens (get from browser DevTools -> LocalStorage)
python3 DirectTV.py tToken=XXX refreshToken=XXX action=login

# List channels
python3 DirectTV.py user=saved action=channels

# Get manifest
python3 DirectTV.py user=saved action=manifest id=CCID

# Get keys
python3 DirectTV.py user=saved action=cdm cdm=external id=CCID
```

### STC TV (Saudi Arabia)

```bash
# Login
python3 StcTV.py user=email@example.com password=mypass action=login

# List channels
python3 StcTV.py user=email@example.com action=channels

# Get manifest
python3 StcTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 StcTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### NowTV (UK/IE/IT/DE)

Uses SSO token from browser cookies or login.

```bash
# Login (or use ssoToken from browser cookies)
python3 NowTV.py user=email@example.com password=mypass action=login

# Login with SSO token directly
python3 NowTV.py ssoToken=XXX country=GB action=login

# List channels
python3 NowTV.py user=email@example.com action=channels

# Get manifest
python3 NowTV.py user=email@example.com action=manifest id=SERVICE_KEY

# Get keys
python3 NowTV.py user=email@example.com action=cdm cdm=external id=SERVICE_KEY
```

### CytaVision (Cyprus)

```bash
# Login
python3 CytaVision.py user=myuser password=mypass action=login

# List channels
python3 CytaVision.py user=myuser action=channels

# Get manifest
python3 CytaVision.py user=myuser action=manifest id=CHANNEL_ID mediaId=MEDIA_ID

# Get keys
python3 CytaVision.py user=myuser action=cdm cdm=external id=CHANNEL_ID mediaId=MEDIA_ID
```

### TivifyTV (Spain - Free)

No login required - free service.

```bash
# Generate session (optional)
python3 TivifyTV.py action=login

# List channels
python3 TivifyTV.py action=channels

# Get manifest
python3 TivifyTV.py action=manifest id=CHANNEL_NAME

# Get keys
python3 TivifyTV.py action=cdm cdm=external id=CHANNEL_NAME
```

### Televio (Croatia/Poland)

Non-DRM streams - no Widevine required.

```bash
# Login
python3 Televio.py user=email@example.com password=mypass action=login

# List channels
python3 Televio.py user=email@example.com action=channels

# Get manifest
python3 Televio.py user=email@example.com action=manifest id=CHANNEL_NAME
```

### SkyGo (UK/IT/DE)

Uses skyCEsidismesso01 cookie from browser.

```bash
# Save token (get skyCEsidismesso01 cookie from browser)
python3 SkyGo.py user=myuser ssoToken=01-XXXXXXX country=GB action=login

# List channels
python3 SkyGo.py user=myuser action=channels

# Get manifest
python3 SkyGo.py user=myuser action=manifest id=SERVICE_KEY

# Get keys
python3 SkyGo.py user=myuser action=cdm cdm=external id=SERVICE_KEY
```

### UFC Fight Pass

```bash
# Login
python3 UFC.py user=email@example.com password=mypass action=login

# List live events
python3 UFC.py user=email@example.com action=channels

# Get manifest
python3 UFC.py user=email@example.com action=manifest id=EVENT_ID

# Get keys
python3 UFC.py user=email@example.com action=cdm cdm=external id=EVENT_ID
```

### Canal Digitaal (Netherlands)

Uses token from browser DevTools -> Local Storage.

```bash
# Save token
python3 CanalDigitaal.py user=myuser token=BEARER_TOKEN action=login

# List channels
python3 CanalDigitaal.py user=myuser action=channels

# Get manifest
python3 CanalDigitaal.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 CanalDigitaal.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### Viaplay (SE/NO/DK/PL/NL)

Uses persistentLogin cookie from browser.

```bash
# Save token (get persistentLogin cookie from login.viaplay.*)
python3 Viaplay.py user=myuser persistentLogin=COOKIE_VALUE action=login

# List channels
python3 Viaplay.py user=myuser action=channels

# Get manifest
python3 Viaplay.py user=myuser action=manifest id=CHANNEL_NAME

# Get keys
python3 Viaplay.py user=myuser action=cdm cdm=external id=CHANNEL_NAME
```

### Videoland (Netherlands)

```bash
# Login
python3 Videoland.py user=email@example.com password=mypass action=login

# List channels
python3 Videoland.py user=email@example.com action=channels

# Get manifest
python3 Videoland.py user=email@example.com action=manifest id=CHANNEL_CODE

# Get keys
python3 Videoland.py user=email@example.com action=cdm cdm=external id=CHANNEL_CODE
```

### Spectrum (USA)

Uses token from browser DevTools -> Local Storage.

```bash
# Save token
python3 Spectrum.py user=myuser token=BEARER_TOKEN action=login

# List channels
python3 Spectrum.py user=myuser action=channels

# Get manifest
python3 Spectrum.py user=myuser action=manifest id=ENTITLEMENT_ID

# Get keys
python3 Spectrum.py user=myuser action=cdm cdm=external id=ENTITLEMENT_ID
```

### Amazon Prime Video

Requires cookies from browser and ASIN + PSSH for content.

```bash
# Save cookies (get from browser DevTools)
python3 Amazon.py user=myuser sessionId=XXX atMain=XXX sessAtMain=XXX sessionToken=XXX region=EU action=login

# Get keys (requires ASIN and PSSH from browser DevTools)
python3 Amazon.py user=myuser action=cdm cdm=external asin=B0XXXXXX pssh=AAAA...
```

### WOWTV / NowTV (IE/UK/DE/IT)

Uses skyCEsidismesso01 cookie from browser.

```bash
# Save token (get skyCEsidismesso01 cookie from browser)
python3 WOWTV.py user=myuser ssoToken=01-XXXXXXX country=IE action=login

# List channels
python3 WOWTV.py user=myuser action=channels

# Get manifest
python3 WOWTV.py user=myuser action=manifest id=SERVICE_KEY

# Get keys
python3 WOWTV.py user=myuser action=cdm cdm=external id=SERVICE_KEY
```

### VectraTV Smart (Poland)

Uses token from browser DevTools -> Local Storage.

```bash
# Save token
python3 VectraTV.py user=myuser token=BEARER_TOKEN action=login

# List channels
python3 VectraTV.py user=myuser action=channels

# Get manifest
python3 VectraTV.py user=myuser action=manifest id=CHANNEL_UUID

# Get keys
python3 VectraTV.py user=myuser action=cdm cdm=external id=CHANNEL_UUID
```

### Star+ (Latin America)

```bash
# Login
python3 StarPlus.py user=email@example.com password=mypass action=login

# List live events
python3 StarPlus.py user=email@example.com action=channels

# Get manifest
python3 StarPlus.py user=email@example.com action=manifest eventId=XXX mediaId=XXX

# Get keys
python3 StarPlus.py user=email@example.com action=cdm cdm=external eventId=XXX mediaId=XXX
```

### TwistTV

```bash
# Login
python3 TwistTV.py user=email@example.com password=mypass action=login

# List channels
python3 TwistTV.py user=email@example.com action=channels

# Get manifest
python3 TwistTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 TwistTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### CignalPlay (Philippines)

```bash
# Login
python3 CignalPlay.py user=email@example.com password=mypass action=login

# List channels
python3 CignalPlay.py user=email@example.com action=channels

# Get manifest
python3 CignalPlay.py user=email@example.com action=manifest id=CONTENT_ID

# Get keys
python3 CignalPlay.py user=email@example.com action=cdm cdm=external id=CONTENT_ID
```

### SwitchTV (UAE - Etisalat)

```bash
# Login
python3 SwitchTV.py user=email@example.com password=mypass action=login

# List channels
python3 SwitchTV.py user=email@example.com action=channels

# Get manifest
python3 SwitchTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 SwitchTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### Digitalb (Albania)

Requires sessionId and accessToken from browser DevTools.

```bash
# Save tokens
python3 Digitalb.py user=myuser sessionId=XXX accessToken=XXX action=login

# List channels
python3 Digitalb.py user=myuser action=channels

# Get keys
python3 Digitalb.py user=myuser action=cdm cdm=external id=CHANNEL_ID&url=MPD_URL
```

### A1XploreHR (Croatia)

```bash
# Login
python3 A1XploreHR.py user=email@example.com password=mypass action=login

# List channels
python3 A1XploreHR.py user=email@example.com action=channels

# Get manifest
python3 A1XploreHR.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 A1XploreHR.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### DAZN V23

```bash
# Login
python3 DaznV23.py user=email@example.com password=mypass action=login

# List live events
python3 DaznV23.py user=email@example.com action=channels

# Get manifest
python3 DaznV23.py user=email@example.com action=manifest id=ASSET_ID

# Get keys (with optional pin for age-restricted content)
python3 DaznV23.py user=email@example.com action=cdm cdm=external id=ASSET_ID pin=1234
```

### DirecTVGo (Latin America)

Requires refreshToken, businessUnit, and deviceId from browser DevTools -> Local Storage.

```bash
# Save tokens
python3 DirecTVGo.py user=myuser refreshToken=XXX businessUnit=AR-DGO deviceId=XXX action=login

# List channels
python3 DirecTVGo.py user=myuser action=channels

# Get manifest
python3 DirecTVGo.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 DirecTVGo.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### SFR (France)

```bash
# Login
python3 SFR.py user=username password=mypass action=login

# List channels
python3 SFR.py user=username action=channels

# Get manifest
python3 SFR.py user=username action=manifest id=CHANNEL_ID&url=STREAM_URL

# Get keys
python3 SFR.py user=username action=cdm cdm=external id=CHANNEL_ID&url=STREAM_URL
```

### TOD (beIN MENA)

Requires account token from browser. Get it from browser DevTools.

```bash
# Save token
python3 TOD.py user=myuser token=ACCOUNT_TOKEN action=login

# List channels
python3 TOD.py user=myuser action=channels

# Get manifest
python3 TOD.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 TOD.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### SuperNova (Serbia)

```bash
# Login
python3 SuperNova.py user=username password=mypass action=login

# List channels
python3 SuperNova.py user=username action=channels

# Get manifest
python3 SuperNova.py user=username action=manifest id=CHANNEL_ID&url=STREAM_URL

# Get keys
python3 SuperNova.py user=username action=cdm cdm=external id=CHANNEL_ID&url=STREAM_URL
```

### Tring (Albania)

```bash
# Login
python3 Tring.py user=username password=mypass action=login

# List channels
python3 Tring.py user=username action=channels

# Get manifest
python3 Tring.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 Tring.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### trueID (Thailand)

Requires cookies from browser DevTools.

```bash
# Save cookies
python3 trueID.py user=myuser cookies='{"session":"xxx"}' action=login

# List channels
python3 trueID.py user=myuser action=channels

# Get manifest
python3 trueID.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 trueID.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### Allente (Scandinavia)

Supports Norway (cdno), Denmark (cddk), Sweden (cdse).

```bash
# Login (region: cdno, cddk, or cdse)
python3 Allente.py user=email@example.com password=mypass region=cdse action=login

# List channels
python3 Allente.py user=email@example.com action=channels

# Get manifest
python3 Allente.py user=email@example.com action=manifest id=CHANNEL_ID&streamId=STREAM_ID

# Get keys
python3 Allente.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID&streamId=STREAM_ID
```

### BallySports (USA)

```bash
# Login
python3 BallySports.py user=email@example.com password=mypass action=login

# List channels
python3 BallySports.py user=email@example.com action=channels

# Get manifest
python3 BallySports.py user=email@example.com action=manifest id=VIDEO_ID

# Get keys
python3 BallySports.py user=email@example.com action=cdm cdm=external id=VIDEO_ID
```

### SaltTV (Switzerland)

Clear streams (no DRM).

```bash
# Login
python3 SaltTV.py user=username password=mypass action=login

# List channels
python3 SaltTV.py user=username action=channels

# Get manifest
python3 SaltTV.py user=username action=manifest id=CHANNEL_ID
```

### Viaplay (Scandinavia/Europe)

Requires persistentLogin cookie from browser DevTools.

```bash
# Save token
python3 Viaplay.py user=myuser persistentLogin=COOKIE_VALUE action=login

# List channels
python3 Viaplay.py user=myuser action=channels

# Get manifest
python3 Viaplay.py user=myuser action=manifest id=streamUrl=STREAM_URL

# Get keys
python3 Viaplay.py user=myuser action=cdm cdm=external id=streamUrl=STREAM_URL
```

### Videoland (Netherlands)

```bash
# Login
python3 Videoland.py user=email@example.com password=mypass action=login

# List channels
python3 Videoland.py user=email@example.com action=channels

# Get manifest
python3 Videoland.py user=email@example.com action=manifest id=CHANNEL_CODE

# Get keys
python3 Videoland.py user=email@example.com action=cdm cdm=external id=CHANNEL_CODE
```

### Spectrum (USA)

Requires Bearer token from browser DevTools.

```bash
# Save token
python3 Spectrum.py user=myuser token=BEARER_TOKEN action=login

# List channels
python3 Spectrum.py user=myuser action=channels

# Get manifest
python3 Spectrum.py user=myuser action=manifest id=ENTITLEMENT_ID

# Get keys
python3 Spectrum.py user=myuser action=cdm cdm=external id=ENTITLEMENT_ID
```

### CytaVision (Cyprus)

```bash
# Login
python3 CytaVision.py user=username password=mypass action=login

# List channels
python3 CytaVision.py user=username action=channels

# Get manifest
python3 CytaVision.py user=username action=manifest id=channelId=123&mediaId=456

# Get keys
python3 CytaVision.py user=username action=cdm cdm=external id=channelId=123&mediaId=456
```

### CosmoteTV (Greece)

```bash
# Login
python3 CosmoteTV.py user=username password=mypass action=login

# List channels
python3 CosmoteTV.py user=username action=channels

# Get manifest
python3 CosmoteTV.py user=username action=manifest id=guid=CHANNEL_GUID

# Get keys
python3 CosmoteTV.py user=username action=cdm cdm=external id=guid=CHANNEL_GUID
```

### OrangeTV (Spain)

```bash
# Login
python3 OrangeTV.py user=username password=mypass action=login

# List channels
python3 OrangeTV.py user=username action=channels

# Get manifest
python3 OrangeTV.py user=username action=manifest id=EXTERNAL_CHANNEL_ID

# Get keys
python3 OrangeTV.py user=username action=cdm cdm=external id=EXTERNAL_CHANNEL_ID
```

### IrisTV (Serbia)

```bash
# Login
python3 IrisTV.py user=username password=mypass action=login

# List channels
python3 IrisTV.py user=username action=channels

# Get manifest
python3 IrisTV.py user=username action=manifest id=channelId=123&mediaId=456

# Get keys
python3 IrisTV.py user=username action=cdm cdm=external id=channelId=123&mediaId=456
```

### MeoGo (Portugal)

```bash
# Login
python3 MeoGo.py user=email@example.com password=mypass action=login

# List channels
python3 MeoGo.py user=email@example.com action=channels

# Get manifest
python3 MeoGo.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 MeoGo.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### Pickx (Belgium - Proximus)

```bash
# Login
python3 Pickx.py user=email@example.com password=mypass action=login

# List channels
python3 Pickx.py user=email@example.com action=channels

# Get manifest
python3 Pickx.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 Pickx.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### RMCSport (France)

```bash
# Login
python3 RMCSport.py user=email@example.com password=mypass action=login

# List channels
python3 RMCSport.py user=email@example.com action=channels

# Get manifest
python3 RMCSport.py user=email@example.com action=manifest id=url=STREAM_URL

# Get keys
python3 RMCSport.py user=email@example.com action=cdm cdm=external id=url=STREAM_URL
```

### VooTV (Belgium)

```bash
# Login
python3 VooTV.py user=email@example.com password=mypass action=login

# List channels
python3 VooTV.py user=email@example.com action=channels

# Get manifest
python3 VooTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 VooTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### SunriseTV (Switzerland)

```bash
# Login
python3 SunriseTV.py user=username password=mypass action=login

# List channels
python3 SunriseTV.py user=username action=channels

# Get manifest
python3 SunriseTV.py user=username action=manifest id=CHANNEL_ID&locator=LOCATOR_URL

# Get keys
python3 SunriseTV.py user=username action=cdm cdm=external id=CHANNEL_ID&locator=LOCATOR_URL
```

### WaipuTV (Germany)

```bash
# Note: Requires refresh_token in token file (no password login)
# Create token file: WaipuTV_username.tokens with {"refreshToken": "YOUR_REFRESH_TOKEN"}

# List channels
python3 WaipuTV.py user=username action=channels

# Get manifest
python3 WaipuTV.py user=username action=manifest id=station=STATION_ID

# Get keys
python3 WaipuTV.py user=username action=cdm cdm=external id=station=STATION_ID
```

### Sling (USA)

```bash
# Note: Requires persist:root data from browser localStorage
# Create token file: Sling_username.tokens with {"user": "..."}

# List channels
python3 Sling.py user=username action=channels

# Get manifest
python3 Sling.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 Sling.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### PolsatBoxGo (Poland)

```bash
# Login
python3 PolsatBoxGo.py user=email@example.com password=mypass action=login

# List channels
python3 PolsatBoxGo.py user=email@example.com action=channels

# Get manifest
python3 PolsatBoxGo.py user=email@example.com action=manifest id=MEDIA_ID

# Get keys
python3 PolsatBoxGo.py user=email@example.com action=cdm cdm=external id=MEDIA_ID
```

### PlayerPL (Poland - TVN)

```bash
# Note: Requires sso and konto cookies from browser
# Create token file: PlayerPL_username.tokens with {"sso": "...", "konto": "..."}

# List channels
python3 PlayerPL.py user=username action=channels

# Get manifest
python3 PlayerPL.py user=username action=manifest id=CHANNEL_ID&payable=False

# Get keys
python3 PlayerPL.py user=username action=cdm cdm=external id=CHANNEL_ID&payable=False
```

### O2TV (Czech Republic)

```bash
# Login
python3 O2TV.py user=username password=mypass action=login

# List channels
python3 O2TV.py user=username action=channels

# Get manifest
python3 O2TV.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 O2TV.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### SaltTV (Switzerland)

```bash
# Login
python3 SaltTV.py user=username password=mypass action=login

# List channels (clear streams, no DRM)
python3 SaltTV.py user=username action=channels

# Get manifest
python3 SaltTV.py user=username action=manifest id=cid=CHANNEL_CID
```

### CignalPlay (Philippines)

```bash
# Login
python3 CignalPlay.py user=email@example.com password=mypass action=login

# List channels
python3 CignalPlay.py user=email@example.com action=channels

# Get manifest
python3 CignalPlay.py user=email@example.com action=manifest id=CONTENT_ID

# Get keys
python3 CignalPlay.py user=email@example.com action=cdm cdm=external id=CONTENT_ID
```

### Dazn (Global Sports)

```bash
# Login
python3 Dazn.py user=email@example.com password=mypass action=login

# List channels
python3 Dazn.py user=email@example.com action=channels

# Get manifest (with optional pin for age-restricted content)
python3 Dazn.py user=email@example.com action=manifest id=asset=ASSET_ID pin=1234

# Get keys
python3 Dazn.py user=email@example.com action=cdm cdm=external id=asset=ASSET_ID
```

### UFC Fight Pass

```bash
# Login
python3 UFC.py user=email@example.com password=mypass action=login

# List live events
python3 UFC.py user=email@example.com action=channels

# Get manifest
python3 UFC.py user=email@example.com action=manifest id=event=EVENT_ID

# Get keys
python3 UFC.py user=email@example.com action=cdm cdm=external id=event=EVENT_ID
```

### TwistTV

```bash
# Login
python3 TwistTV.py user=email@example.com password=mypass action=login

# List channels
python3 TwistTV.py user=email@example.com action=channels

# Get manifest
python3 TwistTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 TwistTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### StcTV (Saudi Arabia)

```bash
# Login
python3 StcTV.py user=email@example.com password=mypass action=login

# List channels
python3 StcTV.py user=email@example.com action=channels

# Get manifest
python3 StcTV.py user=email@example.com action=manifest id=url=CHANNEL_URL

# Get keys
python3 StcTV.py user=email@example.com action=cdm cdm=external id=url=CHANNEL_URL
```

### Allente (Scandinavia)

```bash
# Login (region: cdno=Norway, cddk=Denmark, cdse=Sweden)
python3 Allente.py user=email@example.com password=mypass region=cdse action=login

# List channels
python3 Allente.py user=email@example.com action=channels

# Get manifest
python3 Allente.py user=email@example.com action=manifest id=CHANNEL_ID&streamId=STREAM_ID

# Get keys
python3 Allente.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID&streamId=STREAM_ID
```

### F1TV (Formula 1)

```bash
# Note: Requires ascendonToken from browser cookies
# Create token file: F1TV_username.tokens with {"ascendonToken": "..."}

# List live events
python3 F1TV.py user=username action=channels

# Get manifest
python3 F1TV.py user=username action=manifest id=CONTENT_ID

# Get keys
python3 F1TV.py user=username action=cdm cdm=external id=CONTENT_ID
```

### DiscoveryPlus

```bash
# Note: Requires token from browser cookies (st cookie)
# Create token file: DiscoveryPlus_username.tokens with {"token": "..."}

# List channels
python3 DiscoveryPlus.py user=username action=channels

# Get manifest
python3 DiscoveryPlus.py user=username action=manifest id=CHANNEL_ID&type=channel

# Get keys
python3 DiscoveryPlus.py user=username action=cdm cdm=external id=CHANNEL_ID&type=channel
```

### CanalPlus (France/Poland/Africa)

```bash
# Note: Requires passId from browser cookies
# Create token file: CanalPlus_username.tokens with {"passId": "..."}

# List channels
python3 CanalPlus.py user=username action=channels

# Get manifest
python3 CanalPlus.py user=username action=manifest id=epgId=EPG_ID&wsxUrl=WSX_URL

# Get keys
python3 CanalPlus.py user=username action=cdm cdm=external id=epgId=EPG_ID&wsxUrl=WSX_URL
```

### DirectTV (USA)

```bash
# Note: Requires tToken and refreshToken from browser LocalStorage
# Create token file: DirectTV_username.tokens with {"tToken": "...", "refreshToken": "..."}

# List channels
python3 DirectTV.py user=username action=channels

# Get manifest
python3 DirectTV.py user=username action=manifest id=ccid=CHANNEL_CCID

# Get keys
python3 DirectTV.py user=username action=cdm cdm=external id=ccid=CHANNEL_CCID
```

### BallySports (USA)

```bash
# Login
python3 BallySports.py user=email@example.com password=mypass action=login

# List channels
python3 BallySports.py user=email@example.com action=channels

# Get manifest
python3 BallySports.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 BallySports.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### FibeTV (Canada - Bell)

```bash
# Login
python3 FibeTV.py user=email@example.com password=mypass action=login

# List channels
python3 FibeTV.py user=email@example.com action=channels

# Get manifest
python3 FibeTV.py user=email@example.com action=manifest id=number=CHANNEL_NUM&mergeId=MERGE_ID

# Get keys
python3 FibeTV.py user=email@example.com action=cdm cdm=external id=number=CHANNEL_NUM&mergeId=MERGE_ID
```

### IrisTV (Serbia - MTS)

```bash
# Login
python3 IrisTV.py user=username password=mypass action=login

# List channels
python3 IrisTV.py user=username action=channels

# Get manifest
python3 IrisTV.py user=username action=manifest id=channelId=CHANNEL_ID&mediaId=MEDIA_ID

# Get keys
python3 IrisTV.py user=username action=cdm cdm=external id=channelId=CHANNEL_ID&mediaId=MEDIA_ID
```

### PlutoTV (Free Streaming)

```bash
# No login required - free service

# List channels
python3 PlutoTV.py action=channels

# Get manifest (clear streams, no DRM)
python3 PlutoTV.py action=manifest id=CHANNEL_ID
```

### NHL (Hockey)

```bash
# Note: Requires token from browser cookies
# Create token file: NHL_username.tokens with {"token": "..."}

# List live events
python3 NHL.py user=username action=channels

# Get manifest (HLS streams, no DRM)
python3 NHL.py user=username action=manifest id=CONTENT_ID
```

### SlingTV (USA)

```bash
# Note: Requires persist:root from browser LocalStorage
# Create token file: SlingTV_username.tokens with persist:root JSON content

# List channels
python3 SlingTV.py user=username action=channels

# Get manifest
python3 SlingTV.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 SlingTV.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### FuboTV (USA)

```bash
# Login
python3 FuboTV.py user=email@example.com password=mypass action=login

# List channels
python3 FuboTV.py user=email@example.com action=channels

# Get manifest
python3 FuboTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 FuboTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### A1XploreBG (Bulgaria)

```bash
# Login
python3 A1XploreBG.py user=email@example.com password=mypass action=login

# List channels
python3 A1XploreBG.py user=email@example.com action=channels

# Get manifest
python3 A1XploreBG.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 A1XploreBG.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### CanalPlusPL (Poland)

```bash
# Note: Requires passId from browser cookies (p_pass_token)
# Create token file: CanalPlusPL_username.tokens with {"passId": "..."}

# List channels
python3 CanalPlusPL.py user=username action=channels

# Get manifest
python3 CanalPlusPL.py user=username action=manifest id=epgId=EPG_ID&wsxUrl=WSX_URL

# Get keys
python3 CanalPlusPL.py user=username action=cdm cdm=external id=epgId=EPG_ID&wsxUrl=WSX_URL
```

### DirecTVGo (Latin America)

```bash
# Note: Requires renewEntitlements, user, and deviceId from browser LocalStorage
# Create token file: DirecTVGo_username.tokens with {"renewEntitlements": {...}, "user": {...}, "deviceId": "..."}

# List channels
python3 DirecTVGo.py user=username action=channels

# Get manifest
python3 DirecTVGo.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 DirecTVGo.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### CanalPlusAF (Africa)

```bash
# Note: Requires passId from browser cookies
# Create token file: CanalPlusAF_username.tokens with {"passId": "..."}

# List channels
python3 CanalPlusAF.py user=username action=channels

# Get manifest
python3 CanalPlusAF.py user=username action=manifest id=epgId=EPG_ID&wsxUrl=WSX_URL

# Get keys
python3 CanalPlusAF.py user=username action=cdm cdm=external id=epgId=EPG_ID&wsxUrl=WSX_URL
```

### ViaPlay (Nordic/Europe)

```bash
# Note: Requires persistentLogin cookie from browser
# Create token file: ViaPlay_username.tokens with {"persistentLogin": "..."}

# List channels
python3 ViaPlay.py user=username action=channels

# Get manifest
python3 ViaPlay.py user=username action=manifest id=url=STREAM_URL

# Get keys
python3 ViaPlay.py user=username action=cdm cdm=external id=url=STREAM_URL
```

### WaipuTV (Germany)

```bash
# Note: Requires refresh_token from browser network requests
# Create token file: WaipuTV_username.tokens with {"refresh_token": "..."}

# List channels
python3 WaipuTV.py user=username action=channels

# Get manifest
python3 WaipuTV.py user=username action=manifest id=STATION_ID

# Get keys
python3 WaipuTV.py user=username action=cdm cdm=external id=STATION_ID
```

### Tring (Albania)

```bash
# Login
python3 Tring.py user=username password=mypass action=login

# List channels
python3 Tring.py user=username action=channels

# Get manifest
python3 Tring.py user=username action=manifest id=CHANNEL_ID

# Get keys
python3 Tring.py user=username action=cdm cdm=external id=CHANNEL_ID
```

### VideoLand (Netherlands)

```bash
# Login
python3 VideoLand.py user=email@example.com password=mypass action=login

# List channels
python3 VideoLand.py user=email@example.com action=channels

# Get manifest
python3 VideoLand.py user=email@example.com action=manifest id=CHANNEL_CODE

# Get keys
python3 VideoLand.py user=email@example.com action=cdm cdm=external id=CHANNEL_CODE
```

### TivifyTV (Spain - Free)

```bash
# No login required - free service

# List channels
python3 TivifyTV.py action=channels

# Get manifest
python3 TivifyTV.py action=manifest id=url=DASH_URL

# Get keys
python3 TivifyTV.py action=cdm cdm=external id=url=DASH_URL
```

### TwistTV

```bash
# Login
python3 TwistTV.py user=email@example.com password=mypass action=login

# List channels
python3 TwistTV.py user=email@example.com action=channels

# Get manifest
python3 TwistTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 TwistTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### VooTV (Belgium)

```bash
# Login
python3 VooTV.py user=email@example.com password=mypass action=login

# List channels
python3 VooTV.py user=email@example.com action=channels

# Get manifest
python3 VooTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 VooTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### SwitchTV (UAE)

```bash
# Login
python3 SwitchTV.py user=email@example.com password=mypass action=login

# List channels
python3 SwitchTV.py user=email@example.com action=channels

# Get manifest
python3 SwitchTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 SwitchTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### SunriseTV (Switzerland)

```bash
# Login
python3 SunriseTV.py user=username password=mypass action=login

# List channels
python3 SunriseTV.py user=username action=channels

# Get manifest
python3 SunriseTV.py user=username action=manifest id=CHANNEL_ID&locator=LOCATOR_URL

# Get keys
python3 SunriseTV.py user=username action=cdm cdm=external id=CHANNEL_ID&locator=LOCATOR_URL
```

### RMCSport (France)

```bash
# Login
python3 RMCSport.py user=email@example.com password=mypass action=login

# List channels
python3 RMCSport.py user=email@example.com action=channels

# Get manifest
python3 RMCSport.py user=email@example.com action=manifest id=url=MANIFEST_URL

# Get keys
python3 RMCSport.py user=email@example.com action=cdm cdm=external id=url=MANIFEST_URL
```

### RTLPlus (Germany)

```bash
# Login
python3 RTLPlus.py user=email@example.com password=mypass action=login

# List channels
python3 RTLPlus.py user=email@example.com action=channels

# List live events
python3 RTLPlus.py user=email@example.com action=liveevents

# Get manifest
python3 RTLPlus.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 RTLPlus.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### PlutoTV (Free - Multiple Regions)

```bash
# No login required - free service

# List channels
python3 PlutoTV.py action=channels

# Get manifest (clear stream, no DRM)
python3 PlutoTV.py action=manifest id=url=STREAM_URL
```

### OrangeTV (Spain)

```bash
# Login
python3 OrangeTV.py user=email@example.com password=mypass action=login

# List channels
python3 OrangeTV.py user=email@example.com action=channels

# Get manifest
python3 OrangeTV.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 OrangeTV.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### Supernova (Serbia)

```bash
# Login
python3 Supernova.py user=username password=mypass action=login

# List channels
python3 Supernova.py user=username action=channels

# Get manifest
python3 Supernova.py user=username action=manifest id=url=STREAM_URL&drm=True

# Get keys
python3 Supernova.py user=username action=cdm cdm=external id=url=STREAM_URL&drm=True
```

### Movistar (Spain)

```bash
# Login
python3 Movistar.py user=email@example.com password=mypass action=login

# List channels
python3 Movistar.py user=email@example.com action=channels

# Get manifest
python3 Movistar.py user=email@example.com action=manifest id=url=MANIFEST_URL

# Get keys
python3 Movistar.py user=email@example.com action=cdm cdm=external id=url=MANIFEST_URL
```

### Kayo (Australia)

```bash
# Login (requires refresh token in token file)
python3 Kayo.py user=myuser action=login

# List channels
python3 Kayo.py user=myuser action=channels

# Get manifest
python3 Kayo.py user=myuser action=manifest id=asset=ASSET_ID

# Get keys
python3 Kayo.py user=myuser action=cdm cdm=external id=asset=ASSET_ID
```

### Magenta (Germany)

```bash
# Login
python3 Magenta.py user=email@example.com password=mypass action=login

# List channels
python3 Magenta.py user=email@example.com action=channels

# Get manifest
python3 Magenta.py user=email@example.com action=manifest id=media=MEDIA_ID

# Get keys
python3 Magenta.py user=email@example.com action=cdm cdm=external id=media=MEDIA_ID
```

### MeoGo (Portugal)

```bash
# Login
python3 MeoGo.py user=email@example.com password=mypass action=login

# List channels
python3 MeoGo.py user=email@example.com action=channels

# Get manifest
python3 MeoGo.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 MeoGo.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### CignalPlay (Philippines)

```bash
# Login
python3 CignalPlay.py user=email@example.com password=mypass action=login

# List channels
python3 CignalPlay.py user=email@example.com action=channels

# Get manifest
python3 CignalPlay.py user=email@example.com action=manifest id=CONTENT_ID

# Get keys
python3 CignalPlay.py user=email@example.com action=cdm cdm=external id=CONTENT_ID
```

### NowPlayer (Hong Kong)

```bash
# Login (requires NOWSESSIONID cookie in token file)
python3 NowPlayer.py user=myuser action=login

# List channels
python3 NowPlayer.py user=myuser action=channels

# Get manifest
python3 NowPlayer.py user=myuser action=manifest id=CHANNEL_ID

# Get keys
python3 NowPlayer.py user=myuser action=cdm cdm=external id=CHANNEL_ID
```

### Fubo (USA)

```bash
# Login
python3 Fubo.py user=email@example.com password=mypass action=login

# List channels
python3 Fubo.py user=email@example.com action=channels

# Get manifest
python3 Fubo.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 Fubo.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### CanalPlusPL (Poland)

```bash
# Login (requires passId in token file)
python3 CanalPlusPL.py user=myuser action=login

# List channels
python3 CanalPlusPL.py user=myuser action=channels

# Get manifest
python3 CanalPlusPL.py user=myuser action=manifest id=epg=EPG_ID&wsx=WSX_URL

# Get keys
python3 CanalPlusPL.py user=myuser action=cdm cdm=external id=epg=EPG_ID&wsx=WSX_URL
```

### Dazn (Multiple Regions)

```bash
# Login
python3 Dazn.py user=email@example.com password=mypass action=login

# List channels
python3 Dazn.py user=email@example.com action=channels

# Get manifest
python3 Dazn.py user=email@example.com action=manifest id=asset=ASSET_ID

# Get keys (with optional pin for age-restricted content)
python3 Dazn.py user=email@example.com action=cdm cdm=external id=asset=ASSET_ID pin=1234
```

### A1XploreBG (Bulgaria)

```bash
# Login
python3 A1XploreBG.py user=email@example.com password=mypass action=login

# List channels
python3 A1XploreBG.py user=email@example.com action=channels

# Get manifest
python3 A1XploreBG.py user=email@example.com action=manifest id=CHANNEL_ID

# Get keys
python3 A1XploreBG.py user=email@example.com action=cdm cdm=external id=CHANNEL_ID
```

### Peacock (USA)

```bash
# Login
python3 Peacock.py user=email@example.com password=mypass action=login

# List channels
python3 Peacock.py user=email@example.com action=channels

# Get manifest
python3 Peacock.py user=email@example.com action=manifest id=key=SERVICE_KEY

# Get keys
python3 Peacock.py user=email@example.com action=cdm cdm=external id=key=SERVICE_KEY
```

### IrisTV (Serbia)

```bash
# Login
python3 IrisTV.py user=username password=mypass action=login

# List channels
python3 IrisTV.py user=username action=channels

# Get manifest
python3 IrisTV.py user=username action=manifest id=ch=CHANNEL_ID&media=MEDIA_ID

# Get keys
python3 IrisTV.py user=username action=cdm cdm=external id=ch=CHANNEL_ID&media=MEDIA_ID
```

### CytaVision (Cyprus)

```bash
# Login
python3 CytaVision.py user=username password=mypass action=login

# List channels
python3 CytaVision.py user=username action=channels

# Get manifest
python3 CytaVision.py user=username action=manifest id=ch=CHANNEL_ID&media=MEDIA_ID

# Get keys
python3 CytaVision.py user=username action=cdm cdm=external id=ch=CHANNEL_ID&media=MEDIA_ID
```

### Spectrum (USA)

```bash
# Login (requires bearer token in token file)
python3 Spectrum.py user=myuser action=login

# List channels
python3 Spectrum.py user=myuser action=channels

# Get manifest
python3 Spectrum.py user=myuser action=manifest id=eid=ENTITLEMENT_ID

# Get keys
python3 Spectrum.py user=myuser action=cdm cdm=external id=eid=ENTITLEMENT_ID
```

### SaltTV (Switzerland)

```bash
# Login
python3 SaltTV.py user=email@example.com password=mypass action=login

# List channels (clear streams, no DRM)
python3 SaltTV.py user=email@example.com action=channels

# Get manifest
python3 SaltTV.py user=email@example.com action=manifest id=cid=CHANNEL_ID
```

### UFC Fight Pass

```bash
# Login
python3 UFC.py user=email@example.com password=mypass action=login

# List live events
python3 UFC.py user=email@example.com action=channels

# Get manifest
python3 UFC.py user=email@example.com action=manifest id=eid=EVENT_ID

# Get keys
python3 UFC.py user=email@example.com action=cdm cdm=external id=eid=EVENT_ID
```

### NjpwWorld (Japan Wrestling)

```bash
# Login (requires refresh_token in token file)
python3 NjpwWorld.py user=myuser action=login

# List live events
python3 NjpwWorld.py user=myuser action=channels

# Get manifest
python3 NjpwWorld.py user=myuser action=manifest id=aid=ASSET_ID

# Get keys
python3 NjpwWorld.py user=myuser action=cdm cdm=external id=aid=ASSET_ID
```

### CosmoteTV (Greece)

```bash
# Login
python3 CosmoteTV.py user=username password=mypass action=login

# List channels
python3 CosmoteTV.py user=username action=channels

# Get manifest
python3 CosmoteTV.py user=username action=manifest id=guid=CHANNEL_GUID

# Get keys
python3 CosmoteTV.py user=username action=cdm cdm=external id=guid=CHANNEL_GUID
```

### PlutoTV (Free)

```bash
# Initialize (no login required - free service)
python3 PlutoTV.py user=free action=login

# List channels (clear streams, no DRM)
python3 PlutoTV.py user=free action=channels

# Get manifest
python3 PlutoTV.py user=free action=manifest id=slug=CHANNEL_SLUG
```

### CignalPlay (Philippines)

```bash
# Login
python3 CignalPlay.py user=email@example.com password=mypass action=login

# List channels
python3 CignalPlay.py user=email@example.com action=channels

# Get manifest
python3 CignalPlay.py user=email@example.com action=manifest id=cid=CONTENT_ID

# Get keys
python3 CignalPlay.py user=email@example.com action=cdm cdm=external id=cid=CONTENT_ID
```

### OrangeTV (Spain)

```bash
# Login
python3 OrangeTV.py user=username password=mypass action=login

# List channels
python3 OrangeTV.py user=username action=channels

# Get manifest
python3 OrangeTV.py user=username action=manifest id=eid=EXTERNAL_CHANNEL_ID

# Get keys
python3 OrangeTV.py user=username action=cdm cdm=external id=eid=EXTERNAL_CHANNEL_ID
```

### TwistTV

```bash
# Login
python3 TwistTV.py user=email@example.com password=mypass action=login

# List channels
python3 TwistTV.py user=email@example.com action=channels

# Get manifest
python3 TwistTV.py user=email@example.com action=manifest id=cid=CHANNEL_ID

# Get keys
python3 TwistTV.py user=email@example.com action=cdm cdm=external id=cid=CHANNEL_ID
```

### NowPlayer (Hong Kong)

```bash
# Login (requires NOWSESSIONID cookie in token file)
python3 NowPlayer.py user=myuser action=login

# List channels
python3 NowPlayer.py user=myuser action=channels

# Get manifest
python3 NowPlayer.py user=myuser action=manifest id=cid=CHANNEL_ID

# Get keys
python3 NowPlayer.py user=myuser action=cdm cdm=external id=cid=CHANNEL_ID
```

### PlayerPL (Poland)

```bash
# Login (requires sso and konto cookies in token file)
python3 PlayerPL.py user=myuser action=login

# List channels
python3 PlayerPL.py user=myuser action=channels

# Get manifest
python3 PlayerPL.py user=myuser action=manifest id=cid=CHANNEL_ID&payable=true

# Get keys
python3 PlayerPL.py user=myuser action=cdm cdm=external id=cid=CHANNEL_ID&payable=true
```

### RTL (Germany)

```bash
# Login
python3 RTL.py user=email@example.com password=mypass action=login

# List channels
python3 RTL.py user=email@example.com action=channels

# Get manifest
python3 RTL.py user=email@example.com action=manifest id=cid=CHANNEL_ID

# Get keys
python3 RTL.py user=email@example.com action=cdm cdm=external id=cid=CHANNEL_ID
```

### SunriseTV (Switzerland)

```bash
# Login
python3 SunriseTV.py user=username password=mypass action=login

# List channels
python3 SunriseTV.py user=username action=channels

# Get manifest
python3 SunriseTV.py user=username action=manifest id=cid=CHANNEL_ID&loc=LOCATOR_URL

# Get keys
python3 SunriseTV.py user=username action=cdm cdm=external id=cid=CHANNEL_ID&loc=LOCATOR_URL
```

### MeoGo (Portugal)

```bash
# Login
python3 MeoGo.py user=email@example.com password=mypass action=login

# List channels
python3 MeoGo.py user=email@example.com action=channels

# Get manifest
python3 MeoGo.py user=email@example.com action=manifest id=cid=CHANNEL_ID

# Get keys
python3 MeoGo.py user=email@example.com action=cdm cdm=external id=cid=CHANNEL_ID
```

### TelevioPL (Croatia - Clear streams)

```bash
# Login
python3 TelevioPL.py user=email@example.com password=mypass action=login

# List channels (clear streams, no DRM)
python3 TelevioPL.py user=email@example.com action=channels

# Get manifest
python3 TelevioPL.py user=email@example.com action=manifest id=url=STREAM_URL
```

### RMCSport (France)

```bash
# Login
python3 RMCSport.py user=email@example.com password=mypass action=login

# List channels
python3 RMCSport.py user=email@example.com action=channels

# Get manifest
python3 RMCSport.py user=email@example.com action=manifest id=url=STREAM_URL

# Get keys
python3 RMCSport.py user=email@example.com action=cdm cdm=external id=url=STREAM_URL
```

### Pickx (Belgium - Proximus)

```bash
# Login
python3 Pickx.py user=email@example.com password=mypass action=login

# List channels
python3 Pickx.py user=email@example.com action=channels

# Get manifest
python3 Pickx.py user=email@example.com action=manifest id=cid=CHANNEL_ID

# Get keys
python3 Pickx.py user=email@example.com action=cdm cdm=external id=cid=CHANNEL_ID
```

## Network Options

### Using a Proxy

```bash
python3 ScriptName.py user=myuser action=channels proxy=http://127.0.0.1:8080
```

### Using DNS-over-HTTPS

```bash
python3 ScriptName.py user=myuser action=channels doh=https://cloudflare-dns.com/dns-query
```

### Binding to Network Interface

```bash
# Bind to IP
python3 ScriptName.py user=myuser action=channels bind=192.168.1.100

# Bind to interface
python3 ScriptName.py user=myuser action=channels bind=eth0
```

### Using Worker Server

```bash
python3 ScriptName.py user=myuser action=channels worker=worker.example.com
```

## Output Formats

### Channels Output

```json
{
  "Channels": [
    {
      "Name": "Channel Name",
      "Mode": "live",
      "SessionManifest": true,
      "ManifestScript": "id=123",
      "CdmType": "widevine",
      "UseCdm": true,
      "Cdm": "id=123",
      "Video": "best",
      "OnDemand": true,
      "SpeedUp": true
    }
  ]
}
```

### Events Output

```json
{
  "Events": [
    {
      "Name": "Event Name",
      "Mode": "live",
      "SessionManifest": true,
      "ManifestScript": "id=123",
      "CdmType": "widevine",
      "UseCdm": true,
      "Cdm": "id=123",
      "Video": "best",
      "Autostart": true,
      "Start": 1706601600,
      "End": 1706615200
    }
  ]
}
```

### Manifest Output

```json
{
  "Cdn": [],
  "ManifestUrl": "https://...",
  "Headers": {
    "Manifest": {"User-Agent": "..."},
    "Media": {"User-Agent": "..."}
  },
  "Heartbeat": {
    "Url": "",
    "Params": "",
    "PeriodMs": 300000
  },
  "Pssh": "AAAA..."
}
```

### CDM External Output

Keys are printed one per line in `KID:KEY` format:

```
abcdef1234567890:fedcba0987654321
```

## Troubleshooting

### Authentication Errors
- Delete the `.tokens` file and re-login
- Check credentials are correct
- Some services require VPN/proxy from specific regions

### No PSSH Found
- The manifest may not contain DRM protection
- Try a different channel/content

### License Request Failed
- Token may have expired - re-login
- Check if the content is available in your subscription

### Network Errors
- Try using a proxy or VPN
- Check DNS resolution with `doh` parameter

## Adding New Scripts

To convert a new XAccel script to O11 format:

1. Copy the template structure from an existing script
2. Replace `xaccel` imports with `o11` imports
3. Use `o11.parse_params()` for CLI argument parsing
4. Use `o11.session()` for HTTP requests
5. Implement all standard actions: `login`, `channels`, `events`, `manifest`, `cdm`
6. Add `do_cdm_external()` function using pywidevine
7. Copy `o11.py` to the script directory
8. Place `WVD.wvd` in the script directory
