DEV Community

yqqwe
yqqwe

Posted on

Инженерия загрузчика Bilibili: Разбор протокола DASH, сегментации M4S и мультиплексирования через FFmpeg

Введение

В мире глобального видеостриминга Bilibili занимает уникальную нишу. Эту платформу часто называют «китайским YouTube», и она является домом для огромного количества высококачественного контента: от профессиональных 4K-видео до интерактивных медиа в стиле ACG (Anime, Comics, Games). Однако для нас, разработчиков, Bilibili представляет собой серьезный технический вызов. В отличие от более простых платформ, отдающих статические MP4-файлы, Bilibili использует сложную архитектуру динамического адаптивного стриминга.
Недавно я запустил Bilibili Video Downloader — инструмент, созданный для автоматизации этих процессов. В этой статье я подробно разберу техническую архитектуру, логику парсинга потоков DASH и способы оптимизации бэкенда для высокопроизводительной сборки видео.

1. Архитектура идентификаторов: Навигация между AV и BV

Прежде чем загрузить хотя бы один байт данных, необходимо точно идентифицировать видео. Bilibili использует две системы ID, которые каждый загрузчик должен уметь сопоставлять.
Наследие (AV) и современность (BV)
Изначально платформа использовала простые инкрементные целые числа — AV-номера (например, av123456). Однако для защиты от массового парсинга в 2020 году произошел переход на BV-идентификаторы — строки в кодировке Base-58 (например, BV17x411w7KC).
Техническая задача: Для создания надежного инструмента на twittervideodownloaderx.com/bilibili_downloader_ru нам пришлось реализовать алгоритм двусторонней конвертации. Это включает в себя побитовые операции, XOR со специфическими «магическими числами» и использование кастомной таблицы символов (fZodR9...). Понимание этой логики — первый шаг к получению метаданных видео из любого URL.

2. Главный вызов: Протокол DASH и сегментация M4S

Основным препятствием при загрузке с Bilibili является использование протокола DASH (Dynamic Adaptive Streaming over HTTP).
Разделение аудио и видео
На большинстве «простых» сайтов аудио и видео объединены в один файл. На Bilibili они отдаются как отдельные потоки M4S.
• Логика платформы: Это позволяет плееру динамически переключать разрешение видео (например, с 720p на 1080p в зависимости от пропускной способности канала), не прерывая аудиодорожку.
• Задача загрузчика: Наш движок не может просто «выхватить ссылку». Он должен отправить запрос к API playurl, извлечь URL видеопотока максимального качества, найти соответствующий URL аудиопотока и загрузить их параллельно.

3. Обход ошибки 403 Forbidden: Слой защиты CDN

CDN (Content Delivery Network) Bilibili настроена крайне агрессивно. Если вы попытаетесь загрузить поток с помощью стандартного запроса curl или fetch, вы получите ошибку 403 Forbidden.
Эмуляция заголовков и сессий
Для обхода блокировок наш загрузчик реализует строгую стратегию эмуляции:

  1. Проверка Referer: Заголовок Referer должен быть строго установлен на https://www.bilibili.com/.
  2. Ротация User-Agent: Мы используем пул современных браузерных строк для предотвращения фингерпринтинга.
  3. Авторизация: Доступ к контенту 1080P (High Bitrate) или 4K часто требует валидных куки сессии (SESSDATA). Наш бэкенд управляет этими сессиями, чтобы гарантировать получение запрошенного качества, а не принудительное понижение до 360p.

4. Архитектура бэкенда: Производительность и масштабируемость

Чтобы поддерживать глобальную базу пользователей, мы построили загрузчик на стеке Python/Django, оптимизированном для задач с интенсивным вводом-выводом (I/O-bound).
Асинхронный ввод-вывод с Httpx
Стандартные синхронные запросы слишком медленны для парсинга медиа. Мы используем httpx и asyncio для параллельного выполнения задач:
• Задача А: Получение метаданных (название, превью, длительность).
• Задача Б: Переговоры с эндпоинтами потоков DASH.
• Задача В: Валидация доступности потоков на зеркалах CDN.
За счет выполнения этих операций в событийном цикле (event loop) мы сократили время до получения первого байта (TTFB) более чем на 60%.
Сборка медиа: FFmpeg без перекодирования
Когда у нас есть отдельные файлы .m4s (видео и аудио), мы должны отдать пользователю готовый .mp4. Наивный подход с перекодированием видео уничтожил бы производительность CPU. Вместо этого мы используем копирование потоков FFmpeg:
Bash
ffmpeg -i video_track.m4s -i audio_track.m4s -c copy -map 0✌️0 -map 1🅰️0 output.mp4
Технический инсайт: Флаг -c copy критически важен. Он приказывает FFmpeg просто переместить пакеты данных из контейнера M4S в контейнер MP4 без изменения самих пикселей или аудиосемплов. Этот процесс происходит на 100% без потерь качества и невероятно быстро.

5. Фронтенд и пользовательский опыт

Мы верим, что технические инструменты должны быть быстрыми и минималистичными. Наш интерфейс предлагает:
• Адаптивный дизайн: Оптимизирован для работы как на мобильных устройствах, так и на десктопах.
• Локализация: Для русскоязычного сегмента мы подготовили полностью переведенную версию на русском языке.
• Безопасность: Все процессы происходят на стороне сервера, пользователям не нужно устанавливать сомнительные расширения для браузера.

Заключение

Создание высокопроизводительного загрузчика для Bilibili — это не просто написание скрипта для скачивания, а полноценное исследование современных протоколов стриминга и оптимизации обработки медиаданных. Если вы интересуетесь медиа-инженерией или ищете надежный способ архивации контента с Bilibili, приглашаю вас протестировать наш проект.
👉 Попробовать здесь: Bilibili Video Downloader
Краткий стек технологий:
• Backend: Python / Django / Redis
• Обработка медиа: FFmpeg (Stream Copy Mode)
• Асинхронность: Asyncio / Httpx
• Frontend: Vanilla JS / CSS3
Есть вопросы по парсингу DASH или сборке M4S? Оставляйте комментарии ниже, давайте обсудим инженерию!

WebDev #Python #Bilibili #Programming #VideoProcessing #FFmpeg #OpenSource #RussianTech

Top comments (0)