|
English Download multi-part Kinescope videos from course platforms (GetCourse and similar) where standard HLS/DASH rippers produce files in which the audio is longer than the video stream. If you ran a stream recorder or |
Русский Загрузчик многочастных видео Kinescope для платформ онлайн-курсов (GetCourse и аналоги), когда стандартные стрим-рипперы выдают файл, в котором аудио длиннее видеоряда — картинка замирает через несколько минут, а звук продолжает играть. Если ты запускал |
|
Kinescope serves long videos as byte-range chunks of a single encrypted fragmented MP4. The URLs are named after the byte range itself: |
Kinescope режет один зашифрованный fragmented MP4 на байтовые куски. Имя URL'а буквально содержит диапазон байт: |
edge-msk-1.kinescopecdn.net/.../assets/<uuid>/0/78848150/720p.mp4
edge-msk-1.kinescopecdn.net/.../assets/<uuid>/78848150/157659039/720p.mp4
edge-msk-1.kinescopecdn.net/.../assets/<uuid>/157659039/235941954/720p.mp4
...
|
A 60-minute lesson is usually split into 4–5 chunks of ~75 MB each. The player requests the next chunk only when playback reaches that part of the timeline. Common tools watch network traffic for 10–30 seconds and capture only the first chunk — exactly the long-audio / short-video result you may have seen.
|
60-минутный урок — это обычно 4–5 кусков по ~75 МБ. Плеер запрашивает следующий кусок только когда воспроизведение туда доходит. Стандартные риппери ловят первый кусок за 10–30 секунд и решают, что это весь файл — отсюда тот самый файл с короткой картинкой и длинным звуком.
|
|
✅ Use it when all of the following are true:
❌ Do not use it for:
You are solely responsible for compliance with the course's Terms of Service, copyright law, and any other applicable rules in your jurisdiction. The authors of |
✅ Только если все пункты ниже верны:
❌ Нельзя для:
Ответственность за соблюдение лицензии курса и применимого законодательства лежит только на тебе. Авторы |
|
When you run the tool, you supply:
That's the entire input surface. No API keys, no DRM tokens, no special configuration. |
При запуске ты задаёшь:
Это весь ввод. Никаких API-ключей, токенов, конфигов. |
See INSTALL.md for per-OS instructions (macOS, Linux, Windows). / Подробные инструкции по ОС — в INSTALL.md.
Quick version / Кратко:
# 1. system dependencies — ffmpeg and Bento4 (provides mp4decrypt)
# системные зависимости: ffmpeg + Bento4 (даёт mp4decrypt) — см. INSTALL.md
# 2. Python dependencies / Python-зависимости
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
playwright install chromiumPython 3.10 or newer is required. / Нужен Python ≥ 3.10.
python save_session.py https://learn.example.com|
A visible Chromium window opens at the URL you supplied. Inside the browser:
The cookies are saved to If your session ever expires (typically after a few weeks of inactivity), repeat this step. |
Откроется видимое окно Chromium на указанном URL. В браузере:
Cookies сохранятся в Если сессия со временем протухнет (обычно через несколько недель неактивности), повтори этот шаг. |
Single lesson / Один урок:
python kineripper.py --url "https://learn.example.com/lesson/123" --out ./downloadsBatch from a file / Пачкой из файла:
cat > lessons.txt <<'EOF'
https://learn.example.com/lesson/123
https://learn.example.com/lesson/124
https://learn.example.com/lesson/125
EOF
python kineripper.py --list lessons.txt --out ./downloads|
Each finished file is named after the URL's last path segment by default. Use The tool resumes automatically — if a destination file already exists and is longer than 60 seconds, that lesson is skipped. |
По умолчанию имя файла — последний сегмент URL'а. Флаг Скрипт сам пропускает уже скачанные уроки: если в папке вывода уже лежит |
python kineripper.py [options]
--url URL Download one lesson at URL
--list FILE Download every URL in FILE (one per line)
--out DIR Output directory (default: ./downloads)
--session FILE Session JSON path (default: ~/.kineripper/session.json)
--quality Q Preferred quality: 1080p, 720p, 480p, 360p, or auto (default: auto)
--seek-step SECONDS Scrubbing step in seconds (default: 60)
--headless Run Chromium headless. Some pages will not autoplay headless.
--name-from-title Use the lesson page <title> for the output filename
--keep-temp Do not delete intermediate encrypted/decrypted chunks
--tmp DIR Temporary working directory (default: ~/.kineripper/tmp)
-v, --verbose More log output
-h, --help Show this message and exit
|
The Kinescope embed protects videos with W3C Common Encryption (CENC) with ClearKey key delivery — not DRM in the Widevine/PlayReady sense. The key is fetched from: That endpoint returns a real 16-byte AES key only to a logged-in browser session. Anonymous requests get a dummy/random key. The encrypted video itself is one fragmented MP4 split into byte ranges on the CDN. The URL path encodes the start and end bytes of each chunk: Each chunk is served with the correct The audio track is delivered as a single MP4 file (e.g. The discovery of the chunk URLs is the actual problem. The player loads only what it needs as the user watches, so a passive network sniff catches only the first chunk. |
Шифрование — W3C Common Encryption (CENC) с доставкой ключа через ClearKey, не Widevine/PlayReady. Endpoint: Возвращает 16-байтный AES-ключ только залогиненной сессии. Анонимный запрос получает dummy. Видео — один fragmented MP4, разрезанный на байтовые куски. Имя URL = диапазон: Каждый кусок отдаётся с правильным Аудиодорожка — один файл ( Главная задача — обнаружить URL'ы кусков. Плеер подгружает только то, что нужно зрителю, поэтому пассивный сниф ловит только первый. |
|
|
|
"No iframe found" — the lesson is text-only or uses a different player. Skip it. "Playback did not start within 45 seconds" — your session may have expired. Re-run "Part N size mismatch" — the CDN dropped the connection mid-download. The script retries up to 5 times automatically; if it still fails, your connection is unstable or the CDN is rate-limiting. Wait and retry. "Decryption produced shorter video than expected" — the scrubber missed one or more chunks. Try a smaller "trun track id unknown, no tfhd was found" (ffprobe on intermediate file) — this is expected and benign. The intermediate concatenated encrypted file is not parseable by ffprobe; the final decrypted file is. |
«No iframe found» — у урока нет видео (текстовый) или плеер не Kinescope. Пропусти. «Playback did not start within 45 seconds» — сессия могла протухнуть. Перезапусти «Part N size mismatch» — CDN оборвал соединение. Скрипт автоматически делает до 5 ретраев; если падает дальше — соединение нестабильно или CDN рейт-лимитит. Подожди и перезапусти. «Decryption produced shorter video than expected» — скраббер пропустил один или несколько кусков. Попробуй «trun track id unknown, no tfhd was found» (ffprobe на промежуточном файле) — ожидаемо и безвредно. Промежуточный склеенный зашифрованный файл ffprobe не парсит; финальный расшифрованный — парсит. |
|
Issues and PRs welcome. If you find another course platform where this technique works (or a different chunking pattern that needs new logic), please open an issue with a small example. |
Issues и PR'ы приветствуются. Если ты нашёл другую платформу, где эта техника тоже работает (или новый паттерн нарезки, требующий другой логики), — открой issue с небольшим примером. |