Иногда мы хотим поделиться с друзьями частью какого то видео на YouTube — время концентрации внимания в современной реальности снижено до предела, и если скидывать ссылку на ролик(даже с таймкодом начала) с комментарием «смотреть с 21:51 по 24:55» — велика вероятность, что видео просмотрено не будет.
Кроме того — куски видео могут потребоваться для монтажа своих роликов — и довольно неудобно скачивать ради нескольких секунд весь ролик и искать/вырезать нужную часть в программе для монтажа.
Как загружать часть видео YouTube при помощи ffmpeg — под катом
Получаем прямую ссылку
Часть реализации Telegram бота на Python.
Нам потребуется библиотека pytube.
Создаем объект класса YouTube, которому передаем нашу ссылку, передаем номер нужного потока и получаем прямую ссылку на видео/аудио
from pytube import YouTube
link = "ссылка на видео"
itag = номер_потока
url = YouTube(link).streams.get_by_itag(itag).url
Обратите внимание, что потоки 1080p и 480p не имеют аудиодорожки.
Далее — подаем ссылку на вход (-i) ffmpeg вместе с таймкодами начала (-ss) и конца (-to) в формате «hh:mm:ss.xx». Задаем аудио кодек, битрейт и "-avoid_negative_ts make_zero" для того чтобы избежать подвисания картинки в начале видео из за потери ключевых кадров.
ffmpeg загрузит видео с нужного момента — нам не нужно качать видео на компьютер и обрезать — мы сразу выкачиваем нужный кусок.
process_call_str = 'ffmpeg -ss {1} -to {2} -i "{0}"'
'-acodec aac -b:a 192k -avoid_negative_ts make_zero "{3}"'
.format(str(url), str(ss), str(t), download_file_path)
status = subprocess.check_call(process_call_str, shell=True)
Потоки без аудио
А что же делать с потоками без аудио? FFMPEG выручит нас и здесь — он может принимать на вход несколько потоков и объединять их.
Получаем прямую ссылку на видеопоток (например 137 — 1080p) и на поток с аудио/видео — например 18 — 360p
url = YouTube(link).streams.get_by_itag(itag).url
aurl = YouTube(link).streams.get_by_itag(18).url
Далее начинается магия — подаем на вход оба потока и при помощи "-map" берем видео дорожку из первого потока и аудио дорожку из второго потока и объединяем- теперь загрузка и объединение потоков происходит с нужного места из двух источников.
process_call_str = 'ffmpeg -ss {2} -to {3} -i "{0}" -ss {2} -to {3} -i "{1}"'
' -acodec aac -b:a 192k -avoid_negative_ts '
'make_zero -map 0:v:0 -map 1:a:0 "{4}"'
.format(str(url), str(aurl), str(ss), str(t), download_file_path)
status = subprocess.check_call(process_call_str, shell=True)
Заключение
Вообще ffmpeg довольно мощная штука, возможности которой несколько шире переконвертации видео/аудио из одного формата в другой и позволяет соптимизировать нагрузку на входящий канал, диск, процессорное время и оперативку
Для меня эти возможности стали открытием и очень помогли в реализации Telegram бота AudioTubeBot — бот для загрузки аудио с YouTube.
При помощи ffmpeg в боте реализовано ускорение/замедление звука с тонокомпенсацией, сжатие в формат opus. Теперь вот и загрузка видео/аудио с нужного момента по таймкодам — достаточно прикрепить к ссылке таймкоды и бот оперативно пришлет нужный кусок аудио/видео в нужном формате и качестве:
http://www.youtube.com/watch?v=Qgm36HHDEk0(30:29.5-30:38.5)
Автор: Вячеслав