Как я написал загрузчик видео на Rust

Когда снизил расходы на содержание облака<br />
Когда снизил расходы на содержание облака

Привет! Более года я занимаюсь инди-разработкой и поддержкой самого популярного приложения в RuStore для загрузки видео с YouTube, TikTok, RuTube и других популярных видеоплатформ. Сначала все шло замечательно — более 30 тысяч установок, рейтинг пользователей на уровне 4.2. Но в какой-то момент мы достигли потолка, рост замедлился:(

Экран выбора формата видео для скачивания в загрузчике
Экран выбора формата видео для скачивания в загрузчике

Без существенных улучшений дальнейший прогресс был бы невозможен.
Проблема заключалась в том, что скачивание и обработка видео происходили на устройстве пользователя, что увеличивало размер APK файла до 90 мегабайт. Больше размер приложения = меньше пользователей хотят его установить.Плюс сторонние библиотеки влияли на производительность. Время ожидания при конвертации какого-нибудь стрима в MP3 могло занять часы, что также негативно сказывается на пользовательском опыте.

Кроме того, возникли проблемы с работой приложения в фоновом режиме на некоторых китайских устройствах.
Многие вендоры самостоятельно переписывают логику.
Существует даже специальный ресурс, https://dontkillmyapp.com, который помогает разработчикам разобраться в тонкостях работы приложений в фоне на различных устройствах.

Переход на Rust

В итоге я принял решение разработать бэкенд на Rust с использованием веб-фреймворка Axum. Выбор этого стека обусловили впечатляющие результаты бенчмарков, где Axum обгоняет по производительности практически все фреймворки. Rust меня покорил сразу. Удобная система сборки и менеджера пакетов Cargo делают процесс удобным.Зависимости подключаются в специальный конфигурационный файл Cargo.toml, а с помощью команды Cargo build --release можно легко собрать бинарник и запускать его где угодно без виртуальной машины.

Одним из ключевых преимуществ такого подхода стало низкое потребление ресурсов. В состоянии покоя мой сервис на Axum потребляет всего 10 мегабайт.А в пиковые часы весь инстанс с запущенным сервисом использует скромные 400 мегабайт оперативной памяти, а загруженность CPU не превышает 3%И это всё при обработке видео, что само по себе является довольно ресурсоемким процессом!

Потребление ресурсов сервиса на Rust
Потребление ресурсов сервиса на Rust

В сравнении с другим моим простым CRUD сервисом на Kotlin\Ktor, который в состоянии покоя потребляет целых 200 мегабайт, Rust с Axum представляется более эффективным и масштабируемым решением, что может сэкономить деньги разработчику.А размер Android приложения удалось снизить в 10 раз!

К сожалению, нативной реализации библиотек yt-dlp и FFmpeg для Rust нет, но можно легко вызывать их как отдельные процессы благодаря библиотеке от Tokio. Это может быть даже более предпочтительным, чем использование обёрток.

Привожу простой пример того, как легко запустить процесс yt-dlp с аргументами:

let process = Command::new("yt-dlp") .arg("-f") .arg(video_format) .arg(&query.video_url) .arg("-o") .arg(&video_output) .kill_on_drop(true) .spawn() .expect("Failed spawn") .wait() .await .expect("Failed wait"); if process.success() { // Скачивание завершилось успешно } else { // Неудача, удаляем исходники если таковые имеются }

В общем, я полностью удовлетворен опытом разработки на Rust и планирую продолжать его изучение. Код пишется довольно медленно, однако компилятор предостерегает от потенциальных проблем, что делает его прекрасным выбором для создания производительного и надежного кода на века.Не случайно в настоящее время Rust решили использовать в коде ядра Linux, а Google внедряют Rust в платформу Android.
Спасибо за внимание! Надеюсь, что эта небольшая статья была для вас полезна.

6 комментариев

А засчет чего снизился размер apk файла, он по идее не зависит деталей реализации сервера.

Ответить

Точно. АПК снизился, потому что до этого сервера и не было.
То, что сейчас выполняется на бэке ранее выполнялось прям на устройстве. Я тянул библиотеки FFmpeg и yt-dlp на клиентскую сторону. Теперь апка весит не 90 мегабайт, а 9)

Ответить

В итоге на расте написан только простейший сервер, а само скачивание реализовано на питоне

Ответить

Ну почти. До этого я пытался писать бэкенд на Python.
Очень много памяти кушало в итоге и слабая производительность.

Ответить