# O11 Streaming Panel Scripts - Instruction Manual

## Overview

This collection of scripts provides integration with the O11 streaming panel for various streaming services. Each script has been converted from the Xaccel format to work with the O11 framework, supporting both internal and external CDM (Content Decryption Module) operations using the pywidevine library.

## Table of Contents

1. [Installation](#installation)
2. [Directory Structure](#directory-structure)
3. [Configuration](#configuration)
4. [Available Actions](#available-actions)
5. [Command Line Parameters](#command-line-parameters)
6. [Usage Examples](#usage-examples)
7. [Service-Specific Instructions](#service-specific-instructions)
8. [Troubleshooting](#troubleshooting)

---

## Installation

### Prerequisites

- Python 3.8 or higher
- pip (Python package manager)

### Install Dependencies

```bash
cd /path/to/o11
pip install -r requirements.txt
```

### WVD File Setup

Each script requires a Widevine Device file (`WVD.wvd`) for DRM operations. The WVD file should be placed in each service's folder. The path is hardcoded as:

```python
WVD_PATH = './WVD.wvd'
```

---

## Directory Structure

```
o11/
├── o11.py                 # Core O11 framework module
├── example.py             # Example script template
├── requirements.txt       # Python dependencies
├── MANUAL.md              # This instruction manual
├── outputexample/         # Template files for each service
│   ├── WVD.wvd
│   └── o11.py
├── ESPN/
│   ├── ESPN.py
│   ├── o11.py
│   └── WVD.wvd
├── NFL/
│   ├── NFL.py
│   ├── o11.py
│   └── WVD.wvd
├── Hulu/
│   ├── Hulu.py
│   ├── o11.py
│   └── WVD.wvd
... (and other services)
```

---

## Configuration

### Authentication Files

Each service requires authentication. The scripts will create template auth files on first run. Common auth file patterns:

| Service | Auth File | Required Data |
|---------|-----------|---------------|
| ESPN | `ESPN_tokens.json` | `refresh_token` from ESPN-ONESITE.WEB-PROD.token cookie |
| NFL | `NFL_refreshable.json` | `nfl.refreshableToken.v3` from Local Storage |
| Hulu | `Hulu_auth.json` | `_hulu_dt`, `_hulu_pid`, `_hulu_pgid` cookies |
| Paramount | `Paramount_auth.json` + `Paramount_creds.json` | Token or username/password |
| Max | `Max_token.txt` | `st` cookie from play.max.com |
| Peacock | `Peacock_auth.json` | `skyCEsidmesso01`, `idsession` cookies or credentials |
| SkyGoUK | `SkyGoUK_auth.json` | `skyCEsidismesso01` cookie |
| DSTV | `DSTV_auth.json` | Encrypted tokens from Local Storage |
| ViaPlay | `ViaPlay_persistentLogin.txt` | `persistentLogin` cookie |
| Stan | `Stan_auth.json` | `streamco_token`, `streamco_device_id` cookies |
| NBA | `NBA_auth.json` | `nbaidentity` cookie or credentials |
| BBC | No auth required | Public streams |

---

## Available Actions

Each script supports the following actions via the `action` parameter:

### `login`
Authenticates with the service and saves tokens.

```bash
python ESPN.py action=login
```

### `channels`
Returns a JSON list of available live channels.

```bash
python ESPN.py action=channels
```

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

### `events`
Returns a JSON list of scheduled events with start/end times.

```bash
python ESPN.py action=events
```

Output format:
```json
{
  "Events": [
    {
      "Name": "NFL Game",
      "Mode": "live",
      "Start": 1706140800,
      "End": 1706155200,
      "Autostart": true,
      ...
    }
  ]
}
```

### `manifest`
Returns the stream manifest URL and related information.

```bash
python ESPN.py action=manifest id=12345
```

Output format:
```json
{
  "Cdn": [{"Name": "default", "ManifestUrl": "https://..."}],
  "ManifestUrl": "https://...",
  "Headers": {...},
  "Heartbeat": {...},
  "LicenseUrl": "https://..."
}
```

### `cdm` (with `cdm=internal`)
Processes a license challenge and returns the license response.

```bash
python ESPN.py action=cdm cdm=internal id=12345 challenge=BASE64_CHALLENGE
```

### `cdm` (with `cdm=external`)
Extracts Widevine keys directly using the pywidevine library.

```bash
python ESPN.py action=cdm cdm=external id=12345 pssh=BASE64_PSSH
```

Output:
```
kid1:key1
kid2:key2
```

### `heartbeat`
Sends a heartbeat to maintain the stream session.

```bash
python ESPN.py action=heartbeat heartbeaturl=URL heartbeatparams=PARAMS
```

---

## Command Line Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `action` | Action to perform | `action=channels` |
| `id` | Content/channel identifier | `id=12345` |
| `user` | Username (if required) | `user=email@example.com` |
| `password` | Password (if required) | `password=secret` |
| `cdm` | CDM mode: `internal` or `external` | `cdm=external` |
| `pssh` | Base64 PSSH for external CDM | `pssh=AAAA...` |
| `challenge` | Base64 license challenge | `challenge=CAQ=` |
| `bind` | Network interface to bind | `bind=eth0` |
| `proxy` | Proxy server URL | `proxy=http://127.0.0.1:8080` |
| `doh` | DNS-over-HTTPS server | `doh=https://1.1.1.1/dns-query` |
| `worker` | Worker server for requests | `worker=worker.example.com` |

---

## Usage Examples

### Example 1: Get ESPN Channels

```bash
cd /path/to/o11/ESPN
python ESPN.py action=channels
```

### Example 2: Get Stream Manifest

```bash
python ESPN.py action=manifest id=abc123
```

### Example 3: Extract Widevine Keys (External CDM)

```bash
python ESPN.py action=cdm cdm=external id=abc123 pssh=AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQVmVyaWZpZWRIRCBDb250ZW50
```

### Example 4: Process License Challenge (Internal CDM)

```bash
python ESPN.py action=cdm cdm=internal id=abc123 challenge=CAQ=
```

### Example 5: Use with Proxy

```bash
python ESPN.py action=channels proxy=socks5://127.0.0.1:1080
```

### Example 6: Get Scheduled Events

```bash
python ESPN.py action=events
```

---

## Service-Specific Instructions

### ESPN

1. Login to ESPN in your browser
2. Open DevTools → Application → Cookies → espn.com
3. Copy the value of `ESPN-ONESITE.WEB-PROD.token`
4. Create `ESPN_tokens.json`:
```json
{"refresh_token": "YOUR_TOKEN_HERE"}
```

### NFL

1. Login to NFL in your browser
2. Open DevTools → Application → Local Storage → id.nfl.com
3. Copy the value of `nfl.refreshableToken.v3`
4. Create `NFL_refreshable.json` with the JSON content

### Hulu

1. Login to Hulu in your browser
2. Open DevTools → Application → Cookies → hulu.com
3. Copy `_hulu_dt`, `_hulu_pid`, `_hulu_pgid` values
4. Create `Hulu_auth.json`:
```json
{
  "hulu_dt": "VALUE",
  "hulu_pid": "VALUE",
  "hulu_pgid": "VALUE"
}
```

### Max (HBO Max)

1. Login to Max in your browser
2. Open DevTools → Application → Cookies → play.max.com
3. Copy the value of `st` cookie
4. Save to `Max_token.txt`

### Peacock

1. Login to Peacock in your browser
2. Open DevTools → Application → Cookies
3. Copy `skyCEsidmesso01` and `idsession` values
4. Create `Peacock_auth.json`:
```json
{
  "skyCEsidmesso01": "VALUE",
  "idsession": "VALUE"
}
```

Or provide credentials:
```json
{
  "username": "email@example.com",
  "password": "your_password"
}
```

### SkyGo UK

1. Login to SkyGo in your browser
2. Open DevTools → Application → Cookies
3. Copy `skyCEsidismesso01` value
4. Create `SkyGoUK_auth.json`:
```json
{"messo_token": "VALUE"}
```

### ViaPlay

1. Login to ViaPlay in your browser
2. Open DevTools → Application → Cookies → login.viaplay.com
3. Copy `persistentLogin` cookie value
4. Save to `ViaPlay_persistentLogin.txt`

### Stan

1. Login to Stan in your browser
2. Open DevTools → Application → Cookies → stan.com.au
3. Copy `streamco_token` and `streamco_device_id` values
4. Create `Stan_auth.json`:
```json
{
  "streamco_token": "VALUE",
  "streamco_device_id": "VALUE"
}
```

### DSTV

1. Login to DSTV in your browser
2. Open DevTools → Application → Local Storage
3. Copy the encrypted token values
4. Create `DSTV_auth.json` with the values

### BBC iPlayer

No authentication required for basic channels. Simply run:
```bash
python BBC.py action=channels
```

---

## Troubleshooting

### Common Issues

**"No refresh token found"**
- Ensure you've created the auth file with valid tokens
- Re-login to the service and get fresh tokens

**"Login failed"**
- Tokens may have expired
- Re-authenticate and update the auth file

**"CDM external failed"**
- Verify `WVD.wvd` file exists in the script directory
- Ensure the WVD file is valid

**"Failed getting manifest"**
- Check if the content ID is correct
- Verify authentication is valid
- Some content may be geo-restricted

### Debug Mode

Add print statements or check stderr output for detailed error messages:
```bash
python ESPN.py action=channels 2>&1
```

### Network Issues

Use proxy or DNS-over-HTTPS if experiencing connectivity issues:
```bash
python ESPN.py action=channels proxy=http://proxy:8080 doh=https://1.1.1.1/dns-query
```

---

## License

These scripts are provided for educational purposes only. Ensure you comply with the terms of service of each streaming platform.

---

## Support

For issues or questions, refer to the original Xaccel documentation or the O11 streaming panel documentation.
