A standalone Python video downloader toolkit for public platform media and direct streams.
Project description
Bentu Downloader
Bentu Downloader ist eine eigenstaendige Python-Bibliothek und ein Terminal-Programm zum Herunterladen von oeffentlich erreichbaren Videos, direkten Videodateien und einfachen Videostreams.
Das Paket kann auf PyPI veroeffentlicht und danach so installiert werden:
python -m pip install bentu-downloader
Im Python-Code wird es so importiert:
import bentu_downloader
Python erlaubt keine Bindestriche in import-Namen. Deshalb heisst das PyPI-Paket bentu-downloader, aber der Import heisst bentu_downloader.
Features
- Python-Bibliothek fuer eigene Programme
- Terminal-Befehl
bentu - Download von direkten
.mp4,.webm,.mov,.m4v-Links - Download von direkten Audio-Dateien wie
.mp3,.m4a,.aac,.ogg - Download von einfachen unverschluesselten
.m3u8-Streams - HTML-Seiten nach sichtbaren Media-Links durchsuchen
- Schutz gegen kaputte Downloads: HTML wird nicht als MP4 gespeichert
- SSL-Unterstuetzung mit normalem Python-SSL und optional
certifi - Keine benoetigten Drittanbieter-Bibliotheken fuer den Bentu-Kern
- Open-Source-tauglich mit MIT-Lizenz
Wichtiger Hinweis
Bentu braucht keine andere Downloader-Bibliothek fuer direkte Media-Links und einfache Streams.
Plattformseiten wie YouTube, Instagram oder TikTok sind aber oft zuerst normale HTML-Webseiten. Wenn die Webseite keinen oeffentlichen direkten Media-Link bereitstellt, speichert Bentu keine falsche .mp4, sondern bricht mit einer klaren Fehlermeldung ab.
Bentu umgeht keine Logins, Captchas, Paywalls, DRM, private APIs, geschuetzte Signaturen oder andere Zugriffsschutz-Systeme.
Installation
Von PyPI:
python -m pip install bentu-downloader
Update:
python -m pip install -U bentu-downloader
Aus diesem Repository lokal:
python -m pip install -e .
Schnellstart In Python
import bentu_downloader
result = bentu_downloader.download(
"https://example.com/video.mp4",
output="downloads/video.mp4",
)
print("Gespeichert:", result.path)
Mit automatischem Dateinamen:
import bentu_downloader
result = bentu_downloader.download(
"https://example.com/video.mp4",
output="downloads/%(title)s.%(ext)s",
)
print(result.path)
Informationen auslesen:
import bentu_downloader
info = bentu_downloader.extract_info("https://example.com/video.mp4")
print(info.title)
print(info.formats)
Terminal Nutzung
Download:
bentu "https://example.com/video.mp4"
Als MP4 speichern:
bentu "https://example.com/video.mp4" -o "downloads/video.mp4"
Mit Titel und Endung:
bentu "https://example.com/video.mp4" -o "downloads/%(title)s.%(ext)s"
Infos anzeigen:
bentu "https://example.com/video.mp4" --print-info
Formate anzeigen:
bentu "https://example.com/video.mp4" --list-formats
Alle Optionen:
bentu --help
YouTube, Instagram Und TikTok Beispiel
Im Ordner examples/social_downloader.py liegt ein aufgeraeumtes Beispielprogramm. Es ist aus dem funktionierenden Testcode entstanden und zeigt ein Menue fuer:
- YouTube Download
- Instagram Download
- TikTok Download
Dieses Beispiel nutzt optional btch-downloader, um fuer diese Plattformen direkte Media-URLs zu bekommen. Bentu selbst bleibt weiterhin eigenstaendig und hat keine Pflicht-Abhaengigkeiten.
Optionale Beispiel-Abhaengigkeiten installieren:
python -m pip install -r examples/requirements-social.txt
Beispiel starten:
python examples/social_downloader.py
Dann erscheint:
Social Downloader
=================
1 YouTube Download
2 Instagram Download
3 TikTok Download
Danach Zahl eingeben, Link einfuegen und Enter druecken. Dateien werden im Ordner downloads/ gespeichert.
Kompakter Code Fuer Eigene Social-Downloader
Dieser Code zeigt das Prinzip aus dem Beispiel: Plattform-API fragen, Media-URL finden, Datei speichern.
from __future__ import annotations
import asyncio
from pathlib import Path
from urllib.parse import unquote, urlparse
from urllib.request import Request, urlopen
DOWNLOAD_DIR = Path("downloads")
async def fetch_platform_info(platform: str, url: str):
import btch_downloader
fn_name = {
"youtube": "youtube",
"instagram": "igdl",
"tiktok": "ttdl",
}[platform]
result = getattr(btch_downloader, fn_name)(url)
if hasattr(result, "__await__"):
result = await result
return result
def extract_media_urls(platform: str, result) -> list[str]:
urls: list[str] = []
if platform == "youtube" and isinstance(result, dict):
for key in ("mp4", "mp3"):
value = result.get(key)
if isinstance(value, str) and value.startswith(("http://", "https://")):
urls.append(value)
elif platform == "tiktok" and isinstance(result, dict):
for key in ("video", "audio"):
value = result.get(key)
if isinstance(value, str) and value.startswith(("http://", "https://")):
urls.append(value)
elif platform == "instagram":
if isinstance(result, list):
for item in result:
if isinstance(item, dict):
value = item.get("url")
if isinstance(value, str) and value.startswith(("http://", "https://")):
urls.append(value)
elif isinstance(result, dict):
value = result.get("url")
if isinstance(value, str) and value.startswith(("http://", "https://")):
urls.append(value)
return list(dict.fromkeys(urls))
def sanitize_filename(value: str) -> str:
cleaned = "".join("_" if char in '\\/:*?"<>|\n\r\t' else char for char in value)
cleaned = " ".join(cleaned.split()).strip(". ")
return cleaned[:120] or "download"
def build_target_path(title: str, media_url: str, index: int) -> Path:
parsed = urlparse(media_url)
suffix = Path(unquote(parsed.path)).suffix.lower()
if not suffix or len(suffix) > 8:
suffix = ".mp4"
safe_title = sanitize_filename(title)
if index > 1:
safe_title = f"{safe_title}_{index}"
return DOWNLOAD_DIR / f"{safe_title}{suffix}"
def download_file(media_url: str, target: Path) -> int:
request = Request(media_url, headers={"User-Agent": "Mozilla/5.0"})
target.parent.mkdir(parents=True, exist_ok=True)
bytes_written = 0
with urlopen(request, timeout=60.0) as response, target.open("wb") as output:
while True:
chunk = response.read(1024 * 256)
if not chunk:
break
output.write(chunk)
bytes_written += len(chunk)
return bytes_written
def extract_title(platform: str, result) -> str:
if isinstance(result, dict):
title = result.get("title")
if isinstance(title, str) and title.strip():
return title.strip()
return f"{platform}_download"
def download_platform_video(platform: str, url: str) -> None:
DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True)
result = asyncio.run(fetch_platform_info(platform, url))
media_urls = extract_media_urls(platform, result)
if not media_urls:
raise RuntimeError("Keine direkte Media-URL gefunden.")
title = extract_title(platform, result)
for index, media_url in enumerate(media_urls, start=1):
target = build_target_path(title, media_url, index)
bytes_written = download_file(media_url, target)
print(f"Fertig: {target} ({bytes_written} Bytes)")
if __name__ == "__main__":
download_platform_video("youtube", "https://www.youtube.com/watch?v=VIDEO_ID")
Fuer das komplette Menue-Programm nutze examples/social_downloader.py.
Bentu Als Fallback Verwenden
Wenn du schon eine URL hast, kannst du Bentu direkt verwenden:
import bentu_downloader
result = bentu_downloader.download(
"https://example.com/video.mp4",
output="downloads/%(title)s.%(ext)s",
overwrite=True,
)
print(result.path)
Fehler: HTML Statt Video
Wenn diese Meldung erscheint:
The server returned HTML, not a media file.
dann hat der Server eine Webseite geliefert, keine echte Media-Datei. Bentu speichert diese Webseite nicht als MP4, weil die Datei sonst kaputt waere.
Moegliche Loesungen:
- direkten
.mp4-,.webm- oder.m3u8-Link verwenden bentu URL --print-infoausfuehren- bei Seiten mit Referer-Schutz
--add-header "Referer:https://example.com/"nutzen - fuer Plattformen mit eigener Datenstruktur einen Provider oder ein Social-Beispiel wie oben verwenden
SSL Hinweis
Bentu nutzt automatisch den normalen Python-SSL-Kontext. Wenn certifi installiert ist, nutzt Bentu automatisch dessen Zertifikate.
python -m pip install certifi
Projektstruktur
.
├── LICENSE
├── README.md
├── pyproject.toml
├── examples/
│ ├── requirements-social.txt
│ └── social_downloader.py
├── scripts/
│ └── bump_version.py
├── src/
│ ├── bentu/
│ └── bentu_downloader/
└── tests/
Tests
python -m unittest discover -s tests
Paket Bauen
Jeder PyPI-Upload braucht eine neue Versionsnummer. Eine Version, die schon bei PyPI liegt, kann nicht noch einmal hochgeladen werden.
Version erhoehen:
python scripts/bump_version.py 0.1.5
Alte Build-Dateien loeschen:
rm -rf dist build
Bauen:
python -m pip install build
python -m build
Hochladen:
python -m pip install twine
python -m twine upload dist/*
GitHub Veroeffentlichung
- Repository auf GitHub erstellen.
- Platzhalter in
pyproject.tomlersetzen:
Homepage = "https://github.com/YOUR_USERNAME/bentu-downloader"
Repository = "https://github.com/YOUR_USERNAME/bentu-downloader"
Issues = "https://github.com/YOUR_USERNAME/bentu-downloader/issues"
- Dateien committen:
git add .
git commit -m "Initial open source release"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/bentu-downloader.git
git push -u origin main
Lizenz
Dieses Projekt steht unter der MIT-Lizenz. Siehe LICENSE.
Rechtlicher Hinweis
Lade nur Inhalte herunter, fuer die du die Rechte oder eine Erlaubnis hast. Bentu ist fuer legale Downloads, eigene Inhalte, erlaubte Medien, direkte Media-Links und oeffentliche Streams gedacht.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bentu_downloader-0.1.4.tar.gz.
File metadata
- Download URL: bentu_downloader-0.1.4.tar.gz
- Upload date:
- Size: 24.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64909fda8d9e8bb4c2ff74387fa7687f3238f11e258ea4b73304ee7ab6ac091f
|
|
| MD5 |
46bdd2aa692c54e18cddc11354a29bcd
|
|
| BLAKE2b-256 |
cbe78b721f70e4d7499fe2ec796642300b9d9c9c5423f7b3028f9cfa6c99a2a2
|
File details
Details for the file bentu_downloader-0.1.4-py3-none-any.whl.
File metadata
- Download URL: bentu_downloader-0.1.4-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e9bbac95b3d9cd01e98460607bf9ae864f8183a3c704af899f20c88d75ccd56
|
|
| MD5 |
7f3d30963b5aca0f6f6ee48d710477b5
|
|
| BLAKE2b-256 |
e74623cf7320e79a9defb16601db9b90e231ce36ea4dabc62238ab56c0afbb55
|