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

64

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

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

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

user3181614
источник

Ответы:

46

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

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

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

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

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

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

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

Johnnie
источник
8
По сути, вам все равно нужно скачать все видео и обрезать его самостоятельно
Antony
12
Вы можете использовать опцию -to вместо -t, если хотите указать время окончания фрагмента видео. ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:13:00.00 -to 00:17:00.00 -c copy out.mp4
5
@Antony ffmpegфактически загрузит только ту часть, которую вы укажете.
akaihola
В моем случае он не сохранил аудио для видео, в отличие от ответа @godofgrunts.
ДаГо
19
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Стив Горансон
источник
5
Не могли бы вы объяснить, что это делает, как это работает?
user259412
3
Это просто более краткая версия ответа @godofgrunts, использующая sed для экономии времени, ручного захвата URL-адресов и копирования / вставки во время запуска (-ss 00:05). У @godofgrunts есть несколько дополнительных флагов, -map 0:v -map 1:a -c:v libx264 -c:a aacкоторые могут улучшить качество. Я также хотел бы добавить, youtube-dl -f bestvideo+bestaudioчтобы быть уверенным, что я получаю версию самого высокого качества.
Стив Горансон
ffmpeg.zeranoe.com/builds для Windows.
Wolfpack'08
18

Добавляем к ответу Джонни:

Используйте youtube-dl -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 -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 означает второй вход, который является аудио), а затем выберу мои параметры кодирования.

ffmpeg -ss 42:30 -i "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/" -ss 42:30 -i "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/" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv
godofgrunts
источник
1
Благодарю. Я не был уверен, как получить звук, для сообщения @Johnnie. Ваш пост ответил на это.
Manny_Mar
Вау, я не знал, что -iфлаг ffmpeg может принимать URL. аккуратный
Геремия
Чем он отличается от использования --postprocessor-argsнепосредственно в youtube-dl?
ДаГо
13

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

ks1322
источник
10

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самим собой после первой загрузки файла.

Kevin
источник
4
но для этого все равно потребуется скачать все видео, а затем вырезать нужную часть
Kasparov92
Я получаю unable to obtain file audio codec with ffprobeошибку. Можете ли вы помочь мне с этим. Я использую CentOS 7
Hassaan
3
Обратите внимание, что -xфлаг загружает только аудио. Опустите его из команды, если вы хотите аудио и видео. :)
grooveplex
2

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

прервать загрузку с ^C

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

Да. Это хак .

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

hyperpallium
источник
2

Это не полностью отвечает на вопрос OP, но есть способ загрузить поток с начала до определенной продолжительности, не загружая весь поток. Поскольку 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 (каждый для видео и аудио потоков).

Теперь отправьте запрос head на первый 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

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

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

РЕДАКТИРОВАТЬ: Это будет работать только на веб-сайтах с поддержкой резюме, скажем YouTube. Это не будет работать для других сайтов.

ritiek
источник
1

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

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

  • -сс ЧЧ: ММ: СС: время начала
  • -в ЧЧ: ММ: СС: время окончания
  • -t ЧЧ: ММ: СС: время, необходимое для

Примеры:

  • Начните кодирование с 15 секунд и остановитесь на 1 минуте 20 секунд

$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -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 загрузит весь носитель до его обработки и удалит его после.

niainaLens
источник
1

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

#!/bin/bash
#taken from https://unix.stackexchange.com/a/388148/48971

if [ $# -lt 4 ]; then
        echo "Usage: $0 <youtube's URL> <HH:mm:ss from time> <HH:mm:ss to time> <output_file_name>"
        echo "e.g.:"
        echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4"
        exit 1
fi

echo "processing..."

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 "downloading with the following command:"
echo "$command" 
$command

Я также загрузил его Gitlab фрагментов «s

Нико Родсевич
источник