我正在使用Ubuntu,并且youtube-dl命令可以正常运行。

但是,现在我只想下载一段过长的视频。因此,我只想下载该视频的几分钟,例如从第13分钟到第17分钟。

有什么办法吗?

#1 楼

我不相信youtube-dl会满足您的要求。不过,您可以将其与ffmpeg这样的命令行实用工具结合使用。

首先使用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是一种流行的工具,应该在任何流行的OS信息库/程序包管理器中。

评论


因此,基本上,您仍然必须下载整个视频并自己裁剪

– Antony
16年6月17日在0:08

如果要指定结束视频片段的时间,则可以使用-to选项而不是-t。 ffmpeg -i“输出首个URL” -ss 00:13:00.00 -to 00:17:00.00 -c复制out.mp4

–罗伊
17-4-7在14:41



@Antony ffmpeg实际上只会下载您指定的部分。

– akaihola
18/12/21在20:29

@Antony只要将-ss参数放在-i参数之前,它就会从使用-ss指定的时间开始下载。但是,如果将-ss放在-i参数后面,则ffmpeg将从视频的最开始下载,并从-ss指定的位置开始编码。有关更多信息,请参见我对约翰尼答案的编辑。

– Programmar
19/12/15在7:35

使用带有-g选项的youtube-dl提供的链接,对于我来说总是会返回403禁止。单独使用youtube-dl来下载视频,将始终具有魅力。

–法比安
20年8月5日19:27

#2 楼

添加到Johnnie的答案中:
使用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(请给我几秒钟的时间来捕捉一个好的关键帧),然后在43:00开始输入后再执行-ss 30
然后我将使用map映射视频0:v和音频1:a(0表示第一个输入,它是视频,1表示第二个输入,它是音频),然后选择我的编码选项。
 # The first 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/"
# The second 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
 

请给JakubVrána以获得--youtube-skip-dash-manifest解决方案。

评论


谢谢。对于@Johnnie帖子,我不确定如何获取声音。您的帖子回答了。

–Manny_Mar
19年6月27日在3:27

与直接在youtube-dl中使用--postprocessor-args有何不同?

– daGo
19年11月2日在13:15

@daGo-我相信youtube-dl --postprocessor-args将下载整个视频,然后将其编辑到选定范围,而此答案使用youtube-dl只是为了获得一些特殊的URL。然后,ffmpeg使用这些URL仅下载所需范围。因此,如果您想从2小时的讲座视频中提取2分钟,则此答案将节省大量下载。

–尼克·查玛斯(Nick Chammas)
20-2-3在7:20

这适用于大多数YT视频,但我正在尝试使用9个小时的视频进行此操作,该视频以前是实时流式传输的(现已完成),并且收到“处理输入时发现无效数据”。主要区别在于youtube-dl -g的输出不同。大多数视频都具有结构。 “ https:// r3 --- sn-mv-cvne.googlevideo.com/videoplayback/id/8 ...”,但对于此视频,它具有结构。 “ https://manifest.googlevideo.com/api/manifest/dash/expire/15956 ...”(空格被截断)。关于如何使这项工作的想法?

–剩菜沙拉
20/07/24在23:26

@LeftoverSalad找到了一个解决方案。

– ynn
20年8月18日在9:01

#3 楼

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产生两个单独的参数。

评论


您能否解释一下它的作用,原理?

–peterh-恢复莫妮卡
17年9月15日在4:49

它只是@godofgrunts答案的更简洁的版本,使用sed可以节省一些时间,以手动获取URL并在开始时间进行复制/粘贴(-ss 00:05)。 @godofgrunts还有一些额外的标志-map 0:v -map 1:a -c:v libx264 -c:a aac可能会提高质量。我还喜欢添加youtube-dl -f bestvideo + bestaudio,以确保获得最高质量的版本。

–史蒂夫·戈兰森(Steve Goranson)
17/09/16在7:13



ffmpeg.zeranoe.com/builds for Windows。

– Wolfpack'08
19年6月5日在3:29

“额外的标志”处理两个流(视频和音频),我认为您处理不当-IIUC它们与提高质量无关(嗯,有声音可能是提高质量的标志:-))下面的@godofgrunts似乎是正确的。

– NickD
20 Dec 9'在22:23

#4 楼

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进行后处理基本相同首先。

评论


但这仍然需要下载整个视频,然后剪切所需的部分

– Kasparov92
18-09-15在10:52

我无法获得带有ffprobe错误的文件音频编解码器。你能帮我吗我正在使用CentOS 7

–哈桑
18-11-22在9:40



请注意,-x标志仅下载音频。如果您同时需要音频和视频,请从命令中忽略它。 :)

– Grooveplex
19年1月9日,11:29

这将无法可靠地工作,因为在某些情况下会多次应用-postprocessor-args。见github.com/ytdl-org/youtube-dl/issues/26863

– antgiant
20-10-17在13:05



#5 楼

youtube-dl中尚未实现此功能请求。参见#622问题及其在github上的许多副本。

#6 楼

使用--postprocessor-args参数将音频/视频输出传递到要编辑的ffmpeg(处理器)。需要安装后处理器ffmpeg
--postprocessor-args需要3个参数和值(例如,还有更多的参数和值,请查看ffmpeg的手册页):


-ss HH:MM:SS:开始时间为take

-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将在处理之前下载整个媒体,然后将其删除。

评论


是!很干净,容易记住。

– Aristos Georgiou
20 Mar 4 '20 at 6:18

这将无法可靠地工作,因为在某些情况下会多次应用-postprocessor-args。见github.com/ytdl-org/youtube-dl/issues/26863

– antgiant
20-10-17在13:07



#7 楼

这不能完全回答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(每个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


我们还可以仅下载音频的初始部分(第二URL)以类似的方式(内容长度会有所不同,但总秒数将保持不变)。

也可以通过这种方式从视频中下载任何中间部分,但由于YouTube的存在,它可能会更加棘手流的开头(前几个字节)中的元数据,并且如果它不存在于下载的媒体中,则该流将根本无法播放。

编辑:仅在网站上有效YouTube说,有了简历支持。它不适用于其他网站。

#8 楼

您可以从头开始下载,而无需下载整个内容并进行编辑。这是问题的一半:


^C中断下载



我只用mp4尝试了此操作

不能使用单独的视频和音频,您需要同时使用两者的格式。默认情况下,ytdl通常会获取单独的视频和音频,然后将它们合并。使用-F查看可用的格式,然后选择同时具有这两种格式的mp4。例如通常会在其中。
您必须从下载的百分比进行估算(不是线性的;压缩率会随时间变化)。

是的。

进一步的问题:如果您确实想要单独的视频和音频格式,是否可以分别下载每种格式的一部分(使用此处的-f18),然后手动合并它们?我认为这不适用于某些格式。

#9 楼

我制作了一个脚本,在这里实现@godofgrunts答案

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

if [ $# -lt 4 ]; then
        echo "Usage: q4312079q <youtube's URL> <HH:mm:ss from time> <HH:mm:ss to time> <output_file_name>"
        echo "e.g.:"
        echo "q4312079q 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 ")
to=$(date "+%s" -d "UTC 01/01/1970 ")

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 "\..*" <<< )
to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< )

command="ffmpeg "

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

command+="-ss $from_command_print -to $to_command_print "
echo "downloading with the following command:"
echo "$command" 
$command

 


我也将其上传到了Gitlab的代码段中

#10 楼

我制作了一个烧瓶应用程序,可以满足您的需求。我知道该帖子很旧,但是问题仍然存在。

您可以在这里找到它

它也可以解析YouTube链接的文本。您只需提供例如:

YouTube.com/blahblah start-1:20


这将从0-1:22下载视频(由于关键帧而可能会略有差异)。它也可以下载整个视频,只是在这种情况下省略了时间间隔。

#11 楼

对于所有不想使用多个命令的懒家伙,请执行以下操作:
youtube-dl.exe 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.exeffmpeg的选项,例如选择格式,删除视频和剪切音频文件等。(可能是剪切视频文件,然后转换为音频文件,无论先发生什么事情)。
youtube-dl.exe -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"


评论


您的命令在GNU / Linux上不起作用:我们使用youtube-dl而不是youtube-dl.exe。 ffmpeg告诉我ss的无效持续时间规范:00.00.10.00,它应该是-ss 00:00:30.00,带有冒号而不是句点(最后一个除外)。

– ewen-goisot
20/09/08在21:33

@ ewin-goisot对不起,这是因为我在测试它后没有复制粘贴整个命令。现在应该可以了。问题是时间定义。它必须是00:00:00.00 2点的两倍,而不是1点。像hh:mm:ss.ms

–结城
20 Sep 9 '13:56



00:00:00.0,效果更好,我可以下载一部分视频。我仍然遇到一个问题(与您的命令以及大多数其他命令一样):下载时间过长5或10秒。解决方案在@godofgrunts的答案上给出:-ss 42:30 -i“ $ video_url” -ss 42:30 -i“ $ audio_url” -map 0:v -map 1:a -ss 30之前30秒开始该部分开始,并在末尾添加-ss 30。因此,我需要在同一命令上多次使用-ss选项。有没有办法用--external-downloader-args做同样的事情?

– ewen-goisot
20-09-9的16:21

抱歉,我对混合不同的流媒体并不熟悉。但是如果您只想拍摄同一视频的最佳音频和视频材料,则可以使用youtube-dl代替

–结城
20/09/10在18:29



#12 楼

有人制作了一个批处理脚本(对于Windows),该脚本下载文件并提取所需部分:

@ECHO off

:Input
ECHO.
SET url=
ECHO Enter Youtube-url:
SET /P url=
IF "%url%" EQU "" GOTO End
IF "%url: =%" NEQ "%url%" GOTO Input
ECHO Enter start time (in seconds, or in hh:mm:ss[.xxx] form):
SET /P start=
ECHO Enter duration (in seconds, or in hh:mm:ss[.xxx] form):
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