【问题标题】:Is it possible to download a specific part of a file? [closed]是否可以下载文件的特定部分? [关闭]
【发布时间】:2019-07-21 07:01:19
【问题描述】:

所以我想下载一个文件,但我不需要全部。是否可以跳过文件的前 1/4 并下载其余部分?

我已经尝试过 python youtube-dl 包,有一些我认为可能有用的相关标志。但我不知道如何使用它们

所以无论如何,如果有人以前尝试过,您介意分享一下您是如何进行的吗?还是有可能?

【问题讨论】:

标签: python audio video download


【解决方案1】:

有人建议使用 ffmpeg 和 youtube-dl 的组合来做你想做的事:

https://askubuntu.com/questions/970629/how-to-download-a-portion-of-a-video-with-youtube-dl-or-something-else

这是一个建议的示例,原样来自上面的链接。如您所见,youtube-dl 仅用于获取视频 URL,ffmpeg 完成了这项工作:

ffmpeg -i $(youtube-dl -f 22 --get-url https://www.youtube.com/watch?v=ZbZSe6N_BXs) -ss 00:00:10 -t 00:00:30 -c:v copy -c:a copy happy.mp4

以类似方式启动 ffmpeg 并下载一段 3 小时视频的示例:

import youtube_dl, subprocess

URL = "https://www.youtube.com/watch?v=eyU3bRy2x44"
FROM = "00:00:15"
TO = "00:00:25"
TARGET = "demo.mp4"

with youtube_dl.YoutubeDL({'format': 'best'}) as ydl:
    result = ydl.extract_info(URL, download=False)
    video = result['entries'][0] if 'entries' in result else result

url = video['url']
subprocess.call('ffmpeg -i "%s" -ss %s -t %s -c:v copy -c:a copy "%s"' % (url, FROM, TO, TARGET))

【讨论】:

  • 嗯,但是您是否注意到,答案中的建议会下载整个视频以重新编码?这不完全是他所要求的(顺便说一句。另一个人也没有)。
  • 但确实不行,我刚试过。不能像在 Windows 环境中那样真正执行命令,但这就是我所做的。首先通过运行 youtube-dl -f best --get-url youtube.com/watch?v=ZbZSe6N_BXs > url.txt 获取 URL,然后将 ffmpeg 与该 URL 一起使用(复制粘贴形式 url.txt),它运行良好,只下载了必要的部分。
  • 我已经编辑了答案以包含一段使用 youtube_dl 并启动 ffmpeg 命令行的 python 代码。它工作得很好,只下载了 3 小时视频中的几 MB。
  • 哇,多么棒的解决方案。非常感谢
  • 我想给你点赞,但我还没有 15 个声望点。我只想再次感谢你。
【解决方案2】:

编辑:我有点错过(抱歉)的事实是您不只是试图下载一段二进制文件,而是试图获取一段 youtube 视频。我在下面的回答并不真正适用,您不能只从视频中挑选一个二进制片段并期望它能够工作,至少对于大多数开箱即用的容器类型来说不是。

原答案: 答案是“也许你可以”。这取决于服务器,它可能支持也可能不支持部分下载。 在此处阅读更多信息:https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

如果它确实受支持,您唯一要做的就是添加一个范围标题。 Python 示例,从下面的文件中提取第二个 1kb 块。

import urllib.request

url = 'http://ipv4.download.thinkbroadband.com/100MB.zip'
req = urllib.request.Request(url)
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0')
req.add_header('Range', 'bytes=1024-2047') # <=== range header
res = urllib.request.urlopen(req)
with open('test.bin', 'wb') as f:
    f.write(res.read())

【讨论】:

  • 非常有趣。 add_header('User-Agent...-line 是干什么用的?是模拟浏览器交互吗?
  • 用户代理告诉服务器它处理什么浏览器。该服务器不允许我使用默认 python 下载。
  • 谢谢。我通常使用requests,但那里似乎也有可能。当我抓取了一些足够拒绝我的请求的网站时,这可能会保护我一些时间。
【解决方案3】:

鲍里斯的观点很好。视频文件通常有一个标题,其中包括视频大小、帧速率等信息。

此外,帧通常不会完全存储,而是仅将帧中的更改存储到安全的大量空间中。如果您只是从字节 x 开始下载到字节 y,您会错过标头,并且您无法确定是否获得了帧的边界。

但如果你只想下载 Youtube 视频的某一部分直到最后,你只需要知道你感兴趣的部分开始的第二个。然后你只需要稍微更改 URL 并添加&amp;t=x 到其中 x 是起始秒数(整数)。

所以,如果您想从 02:25 开始观看此视频的其余部分

https://www.youtube.com/watch?v=LUk73pUe9i4

变成:

https://youtu.be/LUk73pUe9i4?t=125

或者,这似乎给出了相同的结果:

https://www.youtube.com/watch?v=LUk73pUe9i4&feature=youtu.be&t=125

应该可以在你使用的库中将其用作 url。

但我不知道持续时间是否还有一个变量,如果这与您相关。但我想,你只是想要视频的其余部分,对吧?

但是如果它是相关的,你仍然可以计算结束(这可能很困难,因为在以秒为单位的长度和以字节为单位的大小之间并没有真正的直线依赖关系),或者(但这会有点混乱)说如果你想下载第 100 秒到 500 秒之间的视频部分。开始下载第一个说 5MB 从第 500 秒开始的视频。丢弃足够的字节以丢弃标题和初始帧,并将其余字节用作“停止” -图案。所以你会从 100 开始下载,一旦你找到你的模式,你就知道,你已经过了第二个 500。是的,我说它会变得混乱 :-)

【讨论】:

  • 看我的第二个答案,你实际上可以使用 ffmpeg 轻松做到这一点,它决定要下载视频的哪些部分,并自行处理容器。
猜你喜欢
  • 2019-08-14
  • 2011-05-02
  • 2011-03-20
  • 1970-01-01
  • 2022-01-12
  • 2019-04-02
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
相关资源
最近更新 更多