背景:目前主流的播放器(potplayer、vlc、mpc…)均不支持多线程播放在线视频,但有些链接单线程下载速度很低,不能流畅播放。
以往只能使用多线程下载器(aria2c、idm、迅雷…)下载到本地之后,再使用播放器播放。有可能还没下载完,我就没兴趣看了。
探索过程
好不容易才在v2ex找到这两篇帖子
“科学”的看片方式,一个多线程下载视频,支持边下边播的 Python 脚本 - V2EX
我选择了第一个帖子稍微研究了一下,发现是一个5年前的古老项目video-funnel。
光是部署花了很多时间摸索(项目太古老了,有很多依赖问题),跑起来之后还有点bug,费了一番功夫之后总算搞定了
现在我把完整方案分享出来:
先安装python 3.7的环境,其它版本也许能行,自行尝试
创建虚拟环境并激活:
py -3.7 -m venv player
player\Scripts\activate
pip install keyring==19.1.0 pycookiecheat==0.4.5
pip install video_funnel
接下来修改源码,打开player/Lib/site-packages/video_funnel/server.py文件
找到get_info函数,将整个函数替换成下面这样:
@retry
async def get_info():
nonlocal url
async with aiohttp.ClientSession() as session:
async with session.get(url, allow_redirects=True, headers={
"Range": "bytes=0-0",
}) as resp:
if not use_original_url:
url = str(resp.url)
content_range = resp.headers['Content-Range']
content_length = int(content_range.split('/')[1])
content_type = resp.headers['Content-Type']
return content_length, content_type
大功告成,接下来执行:
py -m video_funnel -b 10M -p 1M --port 9999 -u "http://example.com/video.mp4"
链接可以换成你自己的视频链接(能直接下载的那种)
接下来播放器直接播放http://127.0.0.1:9999,就能多线程播放了(支持进度拖拽)
-b表示块大小,表示每次转发给播放器的数据量
-p表示分片大小,每个块会拆分成分片,每个分片由单独的线程下载
-b 10M -p 1M 相当于10线程
其它参数可以使用py -m video_funnel -h
查看
其他说明
- 原项目是使用的head请求得到的文件大小,但有些下载服务器将head请求禁用了,我这里改成用get请求拿文件大小更通用一些(除非压根不让下载)
- 如果某些下载地址需要加自定义头,同样可以改源码实现
- 如果是网盘的视频直链或者文件是用webdav挂载的,还可以使用CD2来挂载,可以修改挂载的下载线程数量
- 关于多线程播放这一点,还有很多思路,如果服务端限制了多线程,可以做多源地址下载、代理池等,顺着这个思路,我把目光投向了aria2c,如果有go语言大佬能二开一下aria2c,加个边下边播(在下载的同时启动一个http服务用于多线程在线播放)的功能,就完美了。