Как скачать часть видео с помощью команды youtube-dl?

Вопрос или проблема

Я использую Ubuntu, и команда youtube-dl работает абсолютно нормально.

Однако теперь я хочу загрузить только часть видео, которое слишком длинное. Поэтому я хочу скачать всего несколько минут этого видео, например, с 13-й по 17-ю минуту.

Есть ли способ это сделать?

Не думаю, что youtube-dl сам по себе сделает то, что вам нужно. Однако вы можете объединить его с утилитой командной строки, такой как ffmpeg.

Сначала получите фактический URL, используя youtube-dl:

youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"

Скопируйте вывод команды и вставьте его как часть параметра -i следующей команды:

ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4

Параметр -ss в этой позиции указывает отбросить весь ввод до 15 секунд видео. Опция -t указывает захватывать в течение 10 секунд. Остальная часть команды сообщает, что нужно сохранить в формате mp4.

ffmpeg – популярный инструмент и должен быть в любом из популярных репозиториев/менеджеров пакетов ОС.

Дополняя ответ Джонни:

Используйте youtube-dl --youtube-skip-dash-manifest -g "URL", чтобы получить видеопотоки и аудиопотоки.

Теперь используйте:

ffmpeg -ss 12:15 -i "1st-URL" -ss 12:15 -i "2nd-URL" -t 5:15 -map 0:v -map 1:a -c:v libx264 -c:a aac output.mkv

Вам нужно будет использовать опцию -ss для каждого потока. Я также рекомендую сделать это примерно за 30 секунд до начала и затем использовать еще один -ss 30, чтобы избежать потери ключевых кадров. Вот реальный пример, использующий одно из моих видео на youtube.

Видео

youtube-dl --youtube-skip-dash-manifest -g https://www.youtube.com/watch?v=gESHIrvIQQo

Вывод:

https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/signature/4FFB9B0B7E1703B31F5D07DAD579B55F17EF7BAA.0CB63905C89DD4D33F90CF3AAD728F1ECDFCB9B3/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/
https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/signature/4CD42047D1D5C714377350905C1CC5CBA37C0009.6EED1FC92D17A096235C32E48F4B15DEF7DD99B0/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/

Я хотел вырезать с 43:00 до 50:10, так что я собираюсь использовать -ss 42:30 (давая мне несколько секунд, чтобы поймать хороший ключевой кадр) для обоих входов и затем использовать -ss 30 после входов, чтобы начать с 43:00.

Затем я использую map, чтобы сопоставить видео 0:v и аудио 1:a (0 означает первый ввод, который является видео, а 1 означает второй ввод, который является аудио) и затем выбираю свои параметры кодирования.

# Первый URL
video_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/8CCFBF5CAB97341D0CB1F34E85AB6EE20FC7A03E.7679F39A8603CF41A95F10232E2A921EB0774101/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
# Второй URL
audio_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/4AACC8E27F9036D36D4D623A771A9F2BAC4674BA.7E4F4FB4DC023E3FE491A991F0F9F2329648DE9D/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/"
ffmpeg -ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv

Благодарность Jakub Vrána за решение --youtube-skip-dash-manifest.


ИЗМЕНЕНИЕ: Я так часто делаю это, что создал сценарий, который включу здесь. Я перешел с youtube-dl на yt-dlp по причинам, которые не столь важны для этой публикации, но вы можете заменить yt-dlp на youtube-dl, если хотите продолжать его использовать.

clip-youtube.sh

#!/bin/bash
# Аргументы: URL, временная метка -5 секунд, длина клипа, имя видеофайла

readarray -t urls <<< "$(yt-dlp --youtube-skip-dash-manifest -g "$1")"
ffmpeg -ss $2 -i "${urls[0]}" -ss $2 -i "${urls[1]}" -ss 5 -map 0:v -map 1:a -c:v libx264 -c:a aac -t $3 $4

Пример использования:

./clip-youtube.sh "https://www.youtube.com/watch?v=aqz-KE-bpKQ" 3:05 11 squashed.mp4

ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed 's/^/-ss 00:05 -i /') -t 01:00 -c copy out.mkv

Отредактируйте URL и времена -ss, -t, чтобы использовать эту команду. Она создает аргументы, используя как URL видео, так и аудио, аналогично этому ответу от @godofgrunts. Кавычки не используются для $(), потому что это создает два отдельных аргумента для ffmpeg.

youtube-dl поддерживает передачу аргументов в подлежащий постпроцессор (проверено с версией 2017.08.27.1):


youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...

Это по сути то же самое, что делать постобработку с помощью ffmpeg самостоятельно после скачивания файла.

Нативный способ (YT-DLP)

yt-dlp, духовный преемник youtube-dl, поддерживает это при установленном ffmpeg.

Он ТОЛЬКО скачает ту часть видео, которую вы укажете, что хорошо для низкой пропускной способности или длинных видео!


Самый быстрый

Он принимает временные метки или секунды:

yt-dlp.exe --download-sections "*6:02-6:22"

Он скачает только указанную часть (до ближайшего ключевого кадра).


Точный ключевой кадр

Если вам нужны точные времена начала/остановки (хоть и медленнее):

yt-dlp.exe --download-sections "*1:22:22-inf" --force-keyframes-at-cuts

inf означает до конца видео.


Секции

Скачать секцию под названием "03. Симфония № 6, Оп. 68 (Пастораль): III. Аллегро":

yt-dlp.exe --download-sections "03.*"


Несколько секций

Скачать несколько секций:

yt-dlp.exe --download-sections "03.*" --download-sections "05.*" -o "%(title)s-%(section_title)s.%(ext)s"


Заметка о скорости

Этот метод загружает и транскодирует довольно медленно.

Возможно, будет быстрее просто скачать все видео и нарезать с помощью ffmpeg.

Я определенно буду использовать этот метод для очень длинных видео или очень коротких сегментов.

Используйте параметр --postprocessor-args, чтобы передать аудиовизуальный вывод в ffmpeg для редактирования (процессор). Постпроцессор нужно устанавливать ffmpeg.

--postprocessor-args принимает 3 аргумента и значения (например, их больше, проверьте страницу руководства ffmpeg):

  • -ss HH:MM:SS : время начала для захвата
  • -to HH:MM:SS : время окончания
  • -t HH:MM:SS : длина времени для захвата

Примеры:

  • Начать кодирование через 15 секунд и остановиться на 1 минуте 20 секунд
    $ youtube-dl --postprocessor-args "-ss 0:0:15 -to 0:1:20" '[video_URL]'
    
  • Начать кодирование через 15 секунд и взять только следующие 3 минуты 5 секунд
    $ youtube-dl --postprocessor-args "-ss 0:0:15 -t 0:3:5" '[video_URL]'
    

PS: youtube-dl сначала будет скачивать весь медиафайл, прежде чем обрабатывать его, и удалит его после.

Этот запрос на функциональность еще не реализован в youtube-dl. См. вопрос #622 и многие его дубликаты на github.

Это не совсем отвечает на вопрос автора, но есть способ скачать поток с начала до определенной длительности без необходимости скачивать целиком. Поскольку YouTube поддерживает возобновление, мы можем запрашивать частичное содержимое с использованием заголовка Range.

Сначала мы получаем URL потоков:

$ youtube-dl -g https://www.youtube.com/watch?v=yysk8s2vih8
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...
https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...

Это должно вывести два URL (каждый для видео и аудиопотоков).

Теперь отправляем запрос в заголовке на первый URL (который ведет к видеопотоку), чтобы получить общую длину содержимого этого потока:

$ curl "1st-URL" -sI | grep Content-Length
Content-Length: 64380504

Теперь мы делим эту общую длину содержимого на общее количество секунд в видео (видео на YouTube имеет длительность 4 минуты и 7 секунд, что составляет 247 секунд) для получения приблизительной длины содержимого за 1 секунду:

64380504 / 247 ≈ 260650

Умножаем это значение на (число секунд, которые мы хотим загрузить с начала + 1)

(мы добавляем один, чтобы также грубо учесть дополнительное пространство, занимаемое метаданными, которые располагаются в начале потока)

Например, чтобы получить примерно первые 10 секунд, вам нужно будет получить первые 260650 * 11 = 2867150 байт, поэтому мы делаем запрос с заголовком Range:

$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4

Это должно скачать только первые 10 секунд. Загруженный файл должен воспроизводиться, но лучше дать FFmpeg исправить неправильные метаданные:

$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4

Мы также можем скачать только начальную часть аудио (2-й URL) аналогичным образом (длина содержания будет различаться, но общее количество секунд останется тем же).

Скачивание любой средней части из видео также должно быть возможным таким образом, но это, вероятно, будет гораздо сложнее, потому что YouTube помещает метаданные в начало потока (в первые несколько байт), и без них в загруженном медиафайле поток вообще не воспроизведется.

ИЗМЕНЕНИЕ: Это будет работать только на сайтах с поддержкой возобновления, таких как YouTube. Это не сработает для других сайтов.

Для всех ленивых, кто не хочет использовать больше одной команды, сделайте следующее:

youtube-dl https://www.youtube.com/watch?v=MJD39Aja1Is --external-downloader ffmpeg --external-downloader-args "-ss 00:00:10.00 -t 00:01:00.00"

Теперь вы можете комбинировать опции youtube-dl.exe и ffmpeg, такие как выбор формата, удаление видео и обрезка аудиофайла и т. д. (возможно, сначала обрезка видеофайла, а затем конвертация в аудиофайл, в зависимости от того, что выполнится первым)

youtube-dl -f 251 https://www.youtube.com/watch?v=MJD39Aja1Is -x --external-downloader ffmpeg --external-downloader-args "-ss 00:00:10.00 -t 00:01:00.00"

Примечание: на видео HLS, таких как на Twitch, вам также нужно будет добавить --hls-prefer-ffmpeg, чтобы это сработало.

Вы можете скачать с начала до определенной точки без загрузки всего и редактирования. Это половина того, о чем спрашивается в этом вопросе:

прерываем загрузку с помощью ^C

  • Я пробовал это только с mp4
  • не работает с отдельным видео и аудио, вам нужен формат с обоими. По умолчанию ytdl часто получает отдельное видео и аудио, а затем объединяет их. Используйте -F, чтобы увидеть доступные форматы, и выберите mp4, который имеет оба. Например, -f18 или -f22 обычно там есть.
  • вам придется оценивать по проценту загруженного (что не линейно; скорость сжатия варьируется со временем).

Да. Это хак.

Дополнительный вопрос: если вы действительно хотите отдельные видео и аудиоформаты, не могли бы вы скачать часть каждого отдельно (используя ^c, как здесь), а затем объединить их вручную? Я не думаю, что это сработает для некоторых форматов.

yt-dlp – форк youtube-dl имеет флаг --download-sections:

    --download-sections REGEX                         Загружать только главы, название которых соответствует данному регулярному
                                                      выражению. Также можно использовать временные диапазоны, предваряемые "*", вместо
                                                      глав, чтобы загрузить указанный диапазон. Требует ffmpeg.
                                                      Этот параметр можно использовать несколько раз для загрузки нескольких
                                                      секций, например, --download-sections "*10:15-inf" --download-
                                                      sections "intro"

Например, скачайте 10 секунд с 07:35 до 07:45:

yt-dlp --download-sections "*07:35-07:45" https://www.youtube.com/watch?v=vidid

Судя по скорости, это похоже, что это не делается постфактум.

Это чтобы добавить к всем ответам, связанным с --postprocessor-args.

У меня есть обходной путь к проблеме, на которую указал @antgiant, что --postprocessor-args применяется к каждому постпроцессору, о чем упомянуто здесь (https://github.com/ytdl-org/youtube-dl/issues/26863). Это может привести к тому, что ваши аргументы будут применяться более одного раза, в результате чего поведение будет неожиданным, например, вырезая ваше видео короче, чем нужно.

Я бы оставил комментарий к оригинальным ответам, но у меня недостаточно репутации для этого. Чтобы обойти это, вы должны настроить youtube-dl на использование файла конфигурации по умолчанию и указать все постпроцессы, которые вы хотите применить к видео/аудио, кроме одного другого постпроцесса, который вы хотите использовать в командной строке с --postprocessor-args. Цель в том, чтобы в командной строке было только одно постобработчик для --postprocessor-args, чтобы оно применялось только один раз.

Например, мой файл конфигурации указывает --ffmpeg-location, --audio-format и --audio-quality. Таким образом, в командной строке я бы использовал только -x.

youtube-dl -x --postprocessor-args "-ss 00:57.50" "URL"

Конечно, это будет работать с любым постобработчиком в командной строке, если их только один, а весь остальной код скрыт в файле конфигурации. Чтобы сделать файл конфигурации, просто создайте папку в вашем %appdata%, назовите ее youtube-dl и создайте там файл config.txt со всеми вашими параметрами.

Это мой первый пост на Unix & Linux Stack Exchange, пожалуйста, не стесняйтесь указывать на любые ошибки.

Я сделал сценарий, реализующий ответ @godofgrunts здесь

#!/bin/bash
# взято из https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Использование: $0 <URL youtube> <HH:mm:ss с времени> <HH:mm:ss до времени> <имя выходного файла>"
        echo "например:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "обработка..."

from=$(date "+%s" -d "UTC 01/01/1970 $2")
to=$(date "+%s" -d "UTC 01/01/1970 $3")

from_pre=$(($from - 30))

if [ $from_pre -lt 0 ]
then
        from_pre=0
fi

from_pre_command_print=$(date -u "+%T" -d @$from_pre)
from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2)
to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3)

command="ffmpeg "

for uri in $(youtube-dl -g $1)
do
        command+="-ss $from_pre_command_print -i $uri "
done

command+="-ss $from_command_print -to $to_command_print $4"
echo "скачиваю с помощью следующей команды:"
echo "$command" 
$command

Я также загрузил его в сниппеты Gitlab

Я сделал приложение flask, которое может сделать то, что вам нужно. Я знаю, что пост устарел, но проблема сохраняется.

Вы можете найти его здесь

Он также может анализировать текст на наличие ссылок на YouTube. Вы просто должны предоставить, например:

YouTube.com/blahblah start-1:20

Это скачает видео с 0-1:22 (могут возникнуть небольшие различия из-за ключевых кадров). Он также может загружать целые видео, просто опустите временной интервал в этом случае.

Дополняя ответ @hyperpallium: автор не упоминал, что видео, которое он загружает, должно быть с YouTube.

YouTube абсолютно ограничителен в отношении своих видео, они разделяют аудио и видео потоки на разные файлы и отслеживают вас/продают ваши данные; поэтому у вас могут возникнуть трудности с методом частичной загрузки, а затем нажатия Ctrl+C.

С версией youtube-dl 2020.11.17 в Microsoft Windows версии 10.0.17134.1304 я загрузил часть видео с archive.org:

E:\cs>youtube-dl --abort-on-unavailable-fragment https://archive.org/download/beastars-season-1-1080p/%5BHCS%5D%20Beastars%20-%2003%20%5B1080p%5D.mkv
[generic] [HCS] Beastars - 03 [1080p]: Запрашиваем заголовок
[redirect] Следующий редирект к https://ia601504.us.archive.org/14/items/beastars-season-1-1080p/%5BHCS%5D%20Beastars%20-%2003%20%5B1080p%5D.mkv
[generic] [HCS] Beastars - 03 [1080p]: Запрашиваем заголовок
WARNING: Переход на общий экстрактор информации.
[generic] [HCS] Beastars - 03 [1080p]: Загружается веб-страница
WARNING: URL может быть прямой ссылкой на видео, возвращаем его как таковой.
[download] Цель: [HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv
[download]   2.3% из 513.77MiB на 839.68KiB/s ETA 10:12
ERROR: Прервано пользователем

E:\cs>ren "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv.part" "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv"

E:\cs>ffmpeg -i "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv" "[HCS] Beastars - 03 [1080p].mp4"
ffmpeg version N-91990-g49c67e79ca Copyright (c) 2000-2018 разработчики FFmpeg
  built with gcc 8.2.1 (GCC) 20180813
[stdout text]
    Поток #0:1(jpn): Аудио: aac (LC) (mp4a / 0x6134706D), 48000 Hz, стерео, fltp, 128 kb/s (по умолчанию)
    Метаданные:
      кодировщик         : Lavc58.30.100 aac
[matroska,webm @ 0000020c8f28a2c0] Ошибка чтения=00:00:33.96 скорость=2099.5kbits/s скорость=0.0185x
frame=  823 fps=0.3 q=-1.0 Lsize=    9677kB time=00:00:34.56 bitrate=2293.8kbits/s скорость=0.0147x
видео:9134kB аудио:519kB субтитры:0kB другие потоки:0kB глобальные заголовки:0kB замедление мультиплексирования: 0.248960%
[libx264 @ 0000020c8f3423c0] кадр I:25    Ср. QP:14.71  размер: 56865
[stdout]

E:\cs>youtube-dl -v
[debug] Системная конфигурация: []
[debug] Конфигурация пользователя: []
[debug] Пользовательская конфигурация: []
[debug] Аргументы командной строки: ['-v']
[debug] Кодировки: локаль cp1252, fs mbcs, out cp437, pref cp1252
[debug] версия youtube-dl: 2020.11.17
[debug] версия Python: 3.4.4 (CPython) - Windows-10-10.0.17134
[debug] версии exe: ffmpeg 3.4, ffprobe N-91990-g49c67e79ca
[debug] Прокси карта: {}
Использование: youtube-dl [ОПЦИИ] URL [URL...]

MKV-файл, который я получил, был “00:22:57” в “общей длительности”, но завершился через 34 секунды. MPEG4-видео, которое я получил, было 00:00:34 в общей длительности, завершилось через 34 секунды, и видео и аудио воспроизводились совершенно нормально, как задумано.

Полный cmd.exe лог доступен здесь

Итак, в summary, запустите

youtube-dl --abort-on-unavailable-fragment [URL для видеофайла]

(опция --abort-on-unavailable-fragment может быть важной, так как вы в конечном итоге прерываете загрузку с помощью Ctrl+C), позвольте ей загружаться немного, затем нажмите Ctrl+C.

Опционально: переименуйте файл [file].mkv.part в [file].mkv. Конвертация MKV в MP4 также, вероятно, является опциональной.

-o - отправляет видео YouTube в stdout, которое передается в ffmpeg с помощью |. -i - вводит видео из stdin, передаваемого от команды youtube-dl. -ss – это время начала клипа, а -to – это время окончания клипа. `

youtube-dl -o - "https://youtu.be/dQw4w9WgXcQ" | ffmpeg -i - -ss 00:00:15 -to 00:01:30 -c copy FileNameOfYouTubeVideoDownload.mp4

Надеюсь, это поможет!

Для zsh просто скопируйте и вставьте эту функцию в ваш .zshrc и радуйтесь 🙂

Для получения дополнительной информации проверьте мои dotfiles

# функция, которая использует youtube-dl вместе с ffmpeg, чтобы захватить часть видео
# $1 - URL YouTube
# $2 - начальная позиция в формате hh:mm:ss.msms (ms=милисекунды)
# $3 - конечная позиция в формате hh:mm:ss.msms (ms=милисекунды)
# $4 - имя выходного файла (опционально)
# $5 - тип кодека видео вывода (опционально, например: libx264)
# $6 - тип кодека аудио вывода (опционально, например: aac)
function youtubedl_snippet()(
  local url_streams=$(youtube-dl -f best --get-url $1)
  local output_name=$(youtube-dl --get-title $1)

  ffmpeg -ss $2 -to $3 -i $url_streams -c:v copy -c:a copy ${4:-"$output_name.mp4"}
)

PS: Если получите запрещенный доступ. В этом случае попробуйте снова.

Многие люди перешли с youtube-dl на yt-dlp, так как youtube-dl не обновлялся уже много лет, у них были проблемы с их релизами, поэтому я сдался и выбрал yt-dlp, это легко:

yt-dlp --download-sections "*0:00-3:59" [URL]

Кто-то сделал пакетный скрипт (для Windows), который загружает файл и извлекает нужную часть:

@ECHO off

:Input
ECHO.
SET url=
ECHO Введите URL YouTube:
SET /P url=
IF "%url%" EQU "" GOTO End
IF "%url: =%" NEQ "%url%" GOTO Input
ECHO Введите время начала (в секундах или в формате hh:mm:ss[.xxx]):
SET /P start=
ECHO Введите продолжительность (в секундах или в формате hh:mm:ss[.xxx]):
SET /P dur=
ECHO.
FOR /F "delims==" %%A IN ('youtube-dl.exe --no-warnings --get-filename "%url%"') DO SET filename=%%A
FOR /F %%B IN ('youtube-dl.exe -g "%url%"') DO (
ffmpeg.exe -hide_banner -ss "%start%" -i "%%B" -c copy -t "%dur%" "%filename%"
)
GOTO Input

:End

Вот чистый пакетный скрипт, который выполнит работу аккуратно,
его должно быть легко перенести на linux тоже.
ffmpeg.exe и youtube-dl.exe должны быть где-то в %PATH%,
или просто добавьте полный путь к обеим командам в скрипте.

@echo off
rem
rem Скачайте часть видео youtube
rem
rem Параметры :
rem 
rem "%1" = качество, "-f18", "-f22", ...
rem "%2" = youtube video "url"
rem "%3" = starttime "HH:MM:SS"
rem "%4" = duration "HH:MM:SS" (чтобы захватить 1 минуту 00:01:00)
rem "%5" = outputfile "my-part.mp4"

youtube-dl "%1" -g "%2" > urls.tmp
rem прочитайте первую строку файла "urls.tmp" в переменной "url"
set /p url=< urls.tmp
ffmpeg -ss "%3" -i "%url%" -t "%4" -c copy "%5"
del urls.tmp

В linux вы можете использовать эту команду:

ffmpeg -ss "starttime" -i $(youtube-dl "url" "quality" -g) -t "duration" -c copy "output-file.mp4"

Ура

Итак, рабочее решение:

ffmpeg -ss 00:01:00 -to 00:02:00 -i "$(youtube-dl -f best --get-url 'https://www.youtube.com/watch?v=dc7I-i7sPrg')" -c:v copy -c:a copy kiosk.mp4

но -f best возвращает 720p (один файл: видео + аудио), и это не путь Джедая, поэтому есть альтернативное решение для максимального (умолчательного) качества:

ffmpeg `youtube-dl --get-url "$url" | xargs printf -- "-ss $start -to $finish"' -i %s\n'` -map 0:v -map 1:a -c copy $outname

Кроме того, вы можете поставить -f видео + аудио перед передачей в xargs (проверьте возможные варианты с youtube-dl -F) в данной команде. Например:

  • -f 137+140 – то же самое, что и по умолчанию
  • -f 397+249 – 480p с самым низким качеством аудио.

Легкая функция-обертка в zsh:

function youtube-dl-part {                                          
   readonly start=${1:?"Начало должно быть указано"}
   readonly finish=${2:?"Конец должен быть указан"}
   readonly url=${3:?"URL должен быть указан"}
   readonly outname=${4:?"Имя вывода должно быть указано"}
   ffmpeg `youtube-dl --get-url "$url" | xargs printf -- "-ss $start -to $finish"' -i %s\n'` -map 0:v -map 1:a -c copy $outname
}

Вот простое решение командной строки.

Вставьте функцию ниже в свой .bashrc файл и вызывайте ее с командой clip следующим образом
clip {youtube_video_url} {start_hh:mm:ss} {end_hh:mm:ss} {out_clip.mp4}

Функция также имеет базовый файл справки, который показывает, как ее использовать. Просто введите clip в командной строке.

Использовать просто, и это сэкономит много времени на следующий раз, когда вам нужно будет вырезать что-то из видео YouTube.

Надеюсь, это поможет!

function clip () {

# скачать секцию видео youtube без скачивания всего видео
#   ссылка
#        https://unix.stackexchange.com/a/392350/46470

# echo help statement if 4 parameters are not entered
# or $1 or $2 are not entered in the correct format 
if [ -z "$1 " ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then

   #                   $1            $2         $3         $4
   echo
   echo "     Создайте клип с youtube, используя"   
   echo
   echo "         1 URL клипа"
   echo "         2          время начала, hh:mm:ss"
   echo "         3                        время окончания,   hh:mm:ss"
   echo "         4                                               имя файла вывода.mp4" 
   echo "      "    
   echo " Например: "    
   echo
   echo "    clip   https://www.youtube.com/watch?v=6mPxcljRRzE    00:01:56    00:02:15    out_clip.mp4"
   echo "      "
   echo
   echo

else

# смените на вашу директорию загрузки или это будет работать в директории, в которой вы находитесь
cd /home/$USER/videos

url_z="$1"
start_time_z="$2"
end_time_z="$3"
out_file_name="$4"

# например
# $1  url_z="https://www.youtube.com/watch?v=6mPxcljRRzE"
# $2  start_time_z=00:01:56
# $3    end_time_z=00:02:15
#       duration_z=00:00:19
# $4  out_file_name=out_clip.mp4

# соберите длительность в секундах между двумя временем, чтобы 
#   вычислить нашу "-to" длительность ffmpeg от $start_time до $end_time
#       ссылка
#           https://unix.stackexchange.com/a/167156/46470
# start_time_z=00:01:56
#   end_time_z=00:02:15
beginning_seconds=$(date --date="$start_time_z" +%s);
ending_seconds=$(date --date="$end_time_z" +%s);
duration_z=$((ending_seconds-beginning_seconds))
# echo the culculated duration in seconds
#echo $duration_z
# duration_z=19

# get the necessary information from youtube. See the reference link above
video_url_z="youtube-dl -g $url_z"

# command
ffmpeg $($video_url_z | sed "s/^/-ss $start_time_z -i /") -to $duration_z -c copy $out_file_name

fi

}

Ответ или решение

Для того чтобы загрузить часть видео с YouTube с помощью команды youtube-dl в Ubuntu, вам потребуется использовать сочетание с утилитой ffmpeg. Настоящая инструкция покажет, как это сделать пошагово.

Шаг 1: Установка необходимых инструментов

Если у вас еще не установлены youtube-dl и ffmpeg, выполните следующие команды в терминале:

sudo apt update
sudo apt install youtube-dl ffmpeg

Шаг 2: Получение URL видео и аудио потоков

Сначала получите прямые URL потоков видео и аудио с помощью youtube-dl. Используйте следующую команду, заменив VIDEO_URL на ссылку на нужное видео:

youtube-dl -g "VIDEO_URL" --youtube-skip-dash-manifest

Это вернет URL-адреса для видео и аудио потоков, например:

https://r1---sn-npoeenee.googlevideo.com/videoplayback?id=...
https://r1---sn-npoeenee.googlevideo.com/videoplayback?id=...

Скопируйте эти URL-адреса в текстовый редактор, так как они понадобятся на следующем шаге.

Шаг 3: Загрузка части видео

Теперь вы можете использовать ffmpeg для загрузки конкретной части видео. Предположим, вы хотите загрузить часть видео с 13-й минуты до 17-й. Сначала преобразуйте время в формат HH:MM:SS, то есть 00:13:00 для начала и 00:17:00 для конца.

Выполните следующую команду, заменив VIDEO_URL на первый URL (видео) и AUDIO_URL на второй URL (аудио):

ffmpeg -ss 00:12:30 -i "VIDEO_URL" -ss 00:12:30 -i "AUDIO_URL" -map 0:v -map 1:a -t 00:04:00 -c:v copy -c:a aac output.mp4

Пояснения к команде:

  • -ss 00:12:30: Указывает ffmpeg начать с 12 минут 30 секунд. Это нужно для того, чтобы "поймать" ближайший ключевой кадр.
  • -i "VIDEO_URL": Указывает URL видео.
  • -ss 00:12:30: Указывает, когда начинать для аудиотрека. Этот параметр тоже нужно устанавливать для аудио, если оно загружается отдельно.
  • -map 0:v -map 1:a: Указывает ffmpeg выбрать видео из первого потока и аудио из второго потока.
  • -t 00:04:00: Указывает длительность, которую вы хотите загрузить (в данном случае 4 минуты).
  • -c:v copy -c:a aac: Указывает коды для видео и аудио.

Шаг 4: Использование команды в одну строку (опционально)

Если вы хотите сократить процесс, вы можете использовать конструкцию, которая можно вставить в одну строку:

ffmpeg -ss 00:12:30 -i "$(youtube-dl -g "VIDEO_URL" | sed -n '1p')" -ss 00:12:30 -i "$(youtube-dl -g "VIDEO_URL" | sed -n '2p')" -map 0:v -map 1:a -t 00:04:00 -c:v copy -c:a aac output.mp4

Заключение

Используя данные шаги, вы сможете легко загружать определенные части видео с YouTube. Использование ffmpeg в комбинации с youtube-dl предоставляет гибкость и высокую степень контроля над вашими загрузками. Если у вас остались вопросы или возникли трудности, не стесняйтесь задать их, и я постараюсь помочь.

Оцените материал
Добавить комментарий

Капча загружается...