mirror of
https://github.com/NohamR/OqeeRewind.git
synced 2026-01-10 16:19:11 +00:00
Update CLI docs and remove unused DRM key logic
Expanded README with detailed CLI usage instructions and examples. Removed unused DRM key fetching logic and the get_missing_keys function from main.py and utilities.py to clean up the codebase.
This commit is contained in:
46
README.md
46
README.md
@@ -46,7 +46,9 @@ API_URL=https://example.com/get-cached-keys
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
### Via Command Line
|
|
||||||
|
### Interactive Mode
|
||||||
|
If you run the script without arguments, it will guide you through channel selection and date picking.
|
||||||
|
|
||||||
**Using uv:**
|
**Using uv:**
|
||||||
```bash
|
```bash
|
||||||
@@ -58,9 +60,43 @@ uv run main.py
|
|||||||
python main.py
|
python main.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via CLI Arguments
|
### CLI Mode
|
||||||
|
You can automate the download by providing arguments.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uv run main.py --output-dir ./downloads -id channel_id --start DATE --end DATA -sv best -sa best
|
usage: main.py [-h] [--start-date START_DATE] [--end-date END_DATE] [--duration DURATION] [--channel-id CHANNEL_ID] [--video VIDEO] [--audio AUDIO]
|
||||||
|
[--title TITLE] [--username USERNAME] [--password PASSWORD] [--key KEY] [--output-dir OUTPUT_DIR] [--widevine-device WIDEVINE_DEVICE]
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
--start-date START_DATE
|
||||||
|
Start date and time in YYYY-MM-DD HH:MM:SS format
|
||||||
|
--end-date END_DATE End date and time in YYYY-MM-DD HH:MM:SS format
|
||||||
|
--duration DURATION Duration in HH:MM:SS format (alternative to --end-date)
|
||||||
|
--channel-id CHANNEL_ID
|
||||||
|
Channel ID to download from
|
||||||
|
--video VIDEO Video quality selection (e.g., 'best', '1080p', '720p', '1080p+best', '720p+worst')
|
||||||
|
--audio AUDIO Audio track selection (e.g., 'best', 'fra_main')
|
||||||
|
--title TITLE Title for the download (default: channel_id_start_date)
|
||||||
|
--username USERNAME Oqee username for authentication
|
||||||
|
--password PASSWORD Oqee password for authentication
|
||||||
|
--key KEY DRM key for decryption (can be specified multiple times)
|
||||||
|
--output-dir OUTPUT_DIR
|
||||||
|
Output directory for downloaded files (default: ./download)
|
||||||
|
--widevine-device WIDEVINE_DEVICE
|
||||||
|
Path to Widevine device file (default: ./widevine/device.wvd)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Examples
|
||||||
|
|
||||||
|
**Download a specific program with duration:**
|
||||||
|
```bash
|
||||||
|
uv run main.py --channel-id 536 --start-date "2025-12-19 12:00:00" --duration "01:30:00" --video "1080p+best" --audio "best" --title "MyMovie"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Download with manual DRM keys:**
|
||||||
|
```bash
|
||||||
|
uv run main.py --channel-id 536 --start-date "2025-12-19 12:00:00" --duration "00:05:00" --key "KID:KEY" --key "KID2:KEY2"
|
||||||
```
|
```
|
||||||
|
|
||||||
## DRM Decryption
|
## DRM Decryption
|
||||||
@@ -79,9 +115,9 @@ In order to decrypt DRM content, you will need to have a dumped CDM, after that
|
|||||||
- [ ] Demo GIF
|
- [ ] Demo GIF
|
||||||
- [ ] Lint code
|
- [ ] Lint code
|
||||||
- [ ] Oqee widevine license implementation (.wvd) + mention README
|
- [ ] Oqee widevine license implementation (.wvd) + mention README
|
||||||
- [ ] Full implementation
|
- [x] Full implementation
|
||||||
- [ ] Verify mp4ff installation
|
- [ ] Verify mp4ff installation
|
||||||
- [ ] CLI arguments implementation + documentation
|
- [x] CLI arguments implementation + documentation
|
||||||
- [ ] French/English full translation
|
- [ ] French/English full translation
|
||||||
- [ ] Better output system
|
- [ ] Better output system
|
||||||
- [ ] Add more comments in the code
|
- [ ] Add more comments in the code
|
||||||
|
|||||||
34
main.py
34
main.py
@@ -13,7 +13,7 @@ from utils.input import (
|
|||||||
)
|
)
|
||||||
from utils.oqee import OqeeClient
|
from utils.oqee import OqeeClient
|
||||||
from utils.downloader import get_keys
|
from utils.downloader import get_keys
|
||||||
from utils.utilities import verify_cmd, get_missing_keys, merge_segments, decrypt
|
from utils.utilities import verify_cmd, merge_segments, decrypt
|
||||||
from utils.times import (
|
from utils.times import (
|
||||||
convert_date_to_sec,
|
convert_date_to_sec,
|
||||||
convert_sec_to_ticks,
|
convert_sec_to_ticks,
|
||||||
@@ -197,38 +197,6 @@ if __name__ == "__main__":
|
|||||||
keys = []
|
keys = []
|
||||||
|
|
||||||
output_dir = args.output_dir if cli_mode else "./download"
|
output_dir = args.output_dir if cli_mode else "./download"
|
||||||
# pprint(selections)
|
|
||||||
# missing_keys = get_missing_keys(keys, selections)
|
|
||||||
|
|
||||||
# if missing_keys:
|
|
||||||
# print(f"Getting missing DRM keys {missing_keys}...")
|
|
||||||
|
|
||||||
# method = {}
|
|
||||||
# # api_url = os.getenv("API_URL")
|
|
||||||
# # api_key = os.getenv("API_KEY")
|
|
||||||
# api_url = None
|
|
||||||
# api_key = None
|
|
||||||
# if api_url and api_key:
|
|
||||||
# method = {"method": "api", "api_url": api_url, "api_key": api_key}
|
|
||||||
# else:
|
|
||||||
# username = args.username or os.getenv("OQEE_USERNAME")
|
|
||||||
# password = args.password or os.getenv("OQEE_PASSWORD")
|
|
||||||
# client = OqeeClient(username, password)
|
|
||||||
# verify_cmd(args.widevine_device)
|
|
||||||
# method = {
|
|
||||||
# "method": "device",
|
|
||||||
# "device_file": args.widevine_device,
|
|
||||||
# "client_class": client,
|
|
||||||
# }
|
|
||||||
|
|
||||||
# fetched_keys = get_keys(kids=missing_keys, method=method)
|
|
||||||
# keys = keys + fetched_keys
|
|
||||||
# print(f"DRM Keys: {keys}")
|
|
||||||
|
|
||||||
# missing_keys = get_missing_keys(keys, selections)
|
|
||||||
# if len(missing_keys) > 0:
|
|
||||||
# print(f"Some DRM keys are still missing: {missing_keys}, exiting.")
|
|
||||||
# exit(1)
|
|
||||||
|
|
||||||
start_tick_user = int(convert_sec_to_ticks(convert_date_to_sec(start_date), TIMESCALE))
|
start_tick_user = int(convert_sec_to_ticks(convert_date_to_sec(start_date), TIMESCALE))
|
||||||
|
|
||||||
|
|||||||
@@ -15,21 +15,6 @@ def verify_cmd(path: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_missing_keys(keys, selection):
|
|
||||||
"""Determine which DRM keys are missing based on user selection."""
|
|
||||||
missing_keys = []
|
|
||||||
for drm_info in [
|
|
||||||
selection["video"]["drm_info"],
|
|
||||||
selection["audio"]["drm_info"],
|
|
||||||
]:
|
|
||||||
for drm in drm_info:
|
|
||||||
if "default_KID" in drm:
|
|
||||||
kid = drm["default_KID"].replace("-", "").lower()
|
|
||||||
if kid not in [k.split(":")[0] for k in keys]:
|
|
||||||
missing_keys.append(kid)
|
|
||||||
return missing_keys
|
|
||||||
|
|
||||||
|
|
||||||
def merge_segments(input_folder: str, track_id: str, output_file: str):
|
def merge_segments(input_folder: str, track_id: str, output_file: str):
|
||||||
"""Merge downloaded segments into a single file using ffmpeg."""
|
"""Merge downloaded segments into a single file using ffmpeg."""
|
||||||
segment_folder = os.path.join(input_folder, f"segments_{track_id}")
|
segment_folder = os.path.join(input_folder, f"segments_{track_id}")
|
||||||
|
|||||||
Reference in New Issue
Block a user