mirror of
https://github.com/NohamR/OqeeRewind.git
synced 2026-01-09 23:58:17 +00:00
Compare commits
2 Commits
a01b199475
...
3079169b60
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3079169b60 | ||
|
|
c23263364a |
14
README.fr.md
14
README.fr.md
@@ -69,8 +69,12 @@ https://github.com/user-attachments/assets/54a50828-c0e9-4a29-81c7-e188c238a998
|
|||||||
Vous pouvez automatiser le téléchargement en fournissant des arguments.
|
Vous pouvez automatiser le téléchargement en fournissant des arguments.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
usage: main.py [-h] [--start-date START_DATE] [--end-date END_DATE] [--duration DURATION] [--channel-id CHANNEL_ID] [--video VIDEO] [--audio AUDIO] [--title TITLE]
|
usage: main.py [-h] [--start-date START_DATE] [--end-date END_DATE] [--duration DURATION]
|
||||||
[--username USERNAME] [--password PASSWORD] [--key KEY] [--output-dir OUTPUT_DIR] [--widevine-device WIDEVINE_DEVICE]
|
[--channel-id CHANNEL_ID] [--video VIDEO] [--audio AUDIO] [--title TITLE]
|
||||||
|
[--username USERNAME] [--password PASSWORD] [--key KEY]
|
||||||
|
[--output-dir OUTPUT_DIR] [--widevine-device WIDEVINE_DEVICE]
|
||||||
|
[--bruteforce-batch-size BRUTEFORCE_BATCH_SIZE]
|
||||||
|
[--segment-batch-size SEGMENT_BATCH_SIZE]
|
||||||
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
||||||
|
|
||||||
options:
|
options:
|
||||||
@@ -91,8 +95,10 @@ options:
|
|||||||
Répertoire de sortie pour les fichiers téléchargés (par défaut: ./downloads)
|
Répertoire de sortie pour les fichiers téléchargés (par défaut: ./downloads)
|
||||||
--widevine-device WIDEVINE_DEVICE
|
--widevine-device WIDEVINE_DEVICE
|
||||||
Chemin vers le CDM Widevine (par défaut: ./widevine/device.wvd)
|
Chemin vers le CDM Widevine (par défaut: ./widevine/device.wvd)
|
||||||
--batch-size BATCH_SIZE
|
--bruteforce-batch-size BRUTEFORCE_BATCH_SIZE
|
||||||
Nombre de requêtes pour le bruteforce (par défaut: 20000)
|
Taille de lot pour le bruteforce (par défaut: 20000)
|
||||||
|
--segment-batch-size SEGMENT_BATCH_SIZE
|
||||||
|
Taille de lot pour les téléchargements de segments (par défaut: 64)
|
||||||
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
||||||
Définir le niveau de logging (par défaut: INFO)
|
Définir le niveau de logging (par défaut: INFO)
|
||||||
```
|
```
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -69,8 +69,12 @@ https://github.com/user-attachments/assets/54a50828-c0e9-4a29-81c7-e188c238a998
|
|||||||
You can automate the download by providing arguments.
|
You can automate the download by providing arguments.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
usage: main.py [-h] [--start-date START_DATE] [--end-date END_DATE] [--duration DURATION] [--channel-id CHANNEL_ID] [--video VIDEO] [--audio AUDIO] [--title TITLE]
|
usage: main.py [-h] [--start-date START_DATE] [--end-date END_DATE] [--duration DURATION]
|
||||||
[--username USERNAME] [--password PASSWORD] [--key KEY] [--output-dir OUTPUT_DIR] [--widevine-device WIDEVINE_DEVICE]
|
[--channel-id CHANNEL_ID] [--video VIDEO] [--audio AUDIO] [--title TITLE]
|
||||||
|
[--username USERNAME] [--password PASSWORD] [--key KEY]
|
||||||
|
[--output-dir OUTPUT_DIR] [--widevine-device WIDEVINE_DEVICE]
|
||||||
|
[--bruteforce-batch-size BRUTEFORCE_BATCH_SIZE]
|
||||||
|
[--segment-batch-size SEGMENT_BATCH_SIZE]
|
||||||
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
[--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
|
||||||
|
|
||||||
options:
|
options:
|
||||||
@@ -91,8 +95,10 @@ options:
|
|||||||
Output directory for downloaded files (default: ./downloads)
|
Output directory for downloaded files (default: ./downloads)
|
||||||
--widevine-device WIDEVINE_DEVICE
|
--widevine-device WIDEVINE_DEVICE
|
||||||
Path to Widevine device file (default: ./widevine/device.wvd)
|
Path to Widevine device file (default: ./widevine/device.wvd)
|
||||||
--batch-size BATCH_SIZE
|
--bruteforce-batch-size BRUTEFORCE_BATCH_SIZE
|
||||||
Batch size for bruteforce (default: 20000)
|
Batch size for bruteforce (default: 20000)
|
||||||
|
--segment-batch-size SEGMENT_BATCH_SIZE
|
||||||
|
Batch size for segment downloads (default: 64)
|
||||||
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
|
||||||
Set the logging level (default: INFO)
|
Set the logging level (default: INFO)
|
||||||
```
|
```
|
||||||
|
|||||||
17
main.py
17
main.py
@@ -86,11 +86,17 @@ def parse_arguments():
|
|||||||
help="Path to Widevine device file (default: ./widevine/device.wvd)",
|
help="Path to Widevine device file (default: ./widevine/device.wvd)",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--batch-size",
|
"--bruteforce-batch-size",
|
||||||
type=int,
|
type=int,
|
||||||
default=20000,
|
default=20000,
|
||||||
help="Batch size for bruteforce (default: 20000)",
|
help="Batch size for bruteforce (default: 20000)",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--segment-batch-size",
|
||||||
|
type=int,
|
||||||
|
default=64,
|
||||||
|
help="Batch size for segment downloads (default: 64)",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--log-level",
|
"--log-level",
|
||||||
type=str,
|
type=str,
|
||||||
@@ -188,7 +194,7 @@ if __name__ == "__main__":
|
|||||||
logger.debug("DRM keys: %s", keys)
|
logger.debug("DRM keys: %s", keys)
|
||||||
logger.debug("Output dir: %s", args.output_dir)
|
logger.debug("Output dir: %s", args.output_dir)
|
||||||
logger.debug("Widevine device: %s", args.widevine_device)
|
logger.debug("Widevine device: %s", args.widevine_device)
|
||||||
logger.debug("Batch size: %d", args.batch_size)
|
logger.debug("Batch size: %d", args.bruteforce_batch_size)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Interactive mode
|
# Interactive mode
|
||||||
@@ -213,7 +219,8 @@ if __name__ == "__main__":
|
|||||||
title = title or f"{freebox_id}_{start_date.strftime('%Y%m%d_%H%M%S')}"
|
title = title or f"{freebox_id}_{start_date.strftime('%Y%m%d_%H%M%S')}"
|
||||||
keys = []
|
keys = []
|
||||||
|
|
||||||
batch_size = args.batch_size if cli_mode else 20000
|
batch_size = args.bruteforce_batch_size if cli_mode else 20000
|
||||||
|
segment_batch_size = args.segment_batch_size if cli_mode else 64
|
||||||
output_dir = os.getenv("OUTPUT_DIR") or (
|
output_dir = os.getenv("OUTPUT_DIR") or (
|
||||||
args.output_dir if cli_mode else "./downloads"
|
args.output_dir if cli_mode else "./downloads"
|
||||||
)
|
)
|
||||||
@@ -249,7 +256,7 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
"Date mismatch between requested start date and manifest data, bruteforce method is needed."
|
"Date mismatch between requested start date and manifest data for %s, bruteforce method is needed.", content_type
|
||||||
)
|
)
|
||||||
|
|
||||||
valid_ticks = asyncio.run(bruteforce(track_id, start_tick_user, batch_size))
|
valid_ticks = asyncio.run(bruteforce(track_id, start_tick_user, batch_size))
|
||||||
@@ -285,7 +292,7 @@ if __name__ == "__main__":
|
|||||||
start_tick = data["start_tick"]
|
start_tick = data["start_tick"]
|
||||||
rep_nb = data["rep_nb"]
|
rep_nb = data["rep_nb"]
|
||||||
asyncio.run(
|
asyncio.run(
|
||||||
save_segments(output_dir, track_id, start_tick, rep_nb, DURATION)
|
save_segments(output_dir, track_id, start_tick, rep_nb, DURATION, batch_size=segment_batch_size)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Merge video and audio
|
# Merge video and audio
|
||||||
|
|||||||
65
utils/trimmer.py
Normal file
65
utils/trimmer.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def hhmmss_to_seconds(time_str):
|
||||||
|
"""Convert hh:mm:ss to total seconds."""
|
||||||
|
parts = list(map(int, time_str.split(':')))
|
||||||
|
if len(parts) == 3:
|
||||||
|
h, m, s = parts
|
||||||
|
elif len(parts) == 2:
|
||||||
|
h = 0
|
||||||
|
m, s = parts
|
||||||
|
elif len(parts) == 1:
|
||||||
|
h = 0
|
||||||
|
m = 0
|
||||||
|
s = parts[0]
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid time format")
|
||||||
|
return h * 3600 + m * 60 + s
|
||||||
|
|
||||||
|
def get_video_duration(filename):
|
||||||
|
"""Return video duration in seconds using ffprobe."""
|
||||||
|
cmd = [
|
||||||
|
"ffprobe", "-v", "error", "-show_entries",
|
||||||
|
"format=duration", "-of",
|
||||||
|
"default=noprint_wrappers=1:nokey=1", filename
|
||||||
|
]
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||||
|
return float(result.stdout.strip())
|
||||||
|
|
||||||
|
def trim_video(input_file, output_file, remove_start=None, remove_end=None):
|
||||||
|
# Convert times to seconds
|
||||||
|
start_sec = hhmmss_to_seconds(remove_start) if remove_start else 0
|
||||||
|
duration = None
|
||||||
|
if remove_end:
|
||||||
|
total_duration = get_video_duration(input_file)
|
||||||
|
end_sec = hhmmss_to_seconds(remove_end)
|
||||||
|
duration = total_duration - start_sec - end_sec
|
||||||
|
if duration <= 0:
|
||||||
|
raise ValueError("Trim times are too long; resulting duration is <= 0")
|
||||||
|
|
||||||
|
cmd = ["ffmpeg", "-y"]
|
||||||
|
if start_sec > 0:
|
||||||
|
cmd += ["-ss", str(start_sec)]
|
||||||
|
cmd += ["-i", input_file]
|
||||||
|
if duration:
|
||||||
|
cmd += ["-t", str(duration)]
|
||||||
|
cmd += ["-c", "copy", output_file]
|
||||||
|
|
||||||
|
print("Running command:", " ".join(cmd))
|
||||||
|
subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Trim video start/end times")
|
||||||
|
parser.add_argument("input_file", help="Input video file")
|
||||||
|
parser.add_argument("output_file", help="Output trimmed video file")
|
||||||
|
parser.add_argument("--remove-start", help="Time to remove from start (hh:mm:ss)")
|
||||||
|
parser.add_argument("--remove-end", help="Time to remove from end (hh:mm:ss)")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
trim_video(args.input_file, args.output_file, args.remove_start, args.remove_end)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user