Video Funnel - 让你在线看视频也能达到多线程下载的速度
$ pip(3) install --user video_funnel
# or
$ sudo pip(3) install video_funnel
video_funnel
的服务器:$ vf http://tulip.ink/test.mp4
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
mpv
播放:$ mpv http://localhost:8080
众所周知,百度网盘之类产品的视频在线播放非常模糊,下载吧又限速,于是我写了 aiodl 这个下载器,通过 EX-百度云盘 获取的直链来“多线程”下载。可是每次都要下载完才能看又十分不爽,直接用 mpv 之类的播放器播放直链又因为限速的原因根本没法看,遂有了本项目。
--block-size/-b
来指定,默认为 8MB。--piece-size/-p
来指定,默认为 1MB。该如何把数据传给播放器呢?我最初的设想是通过标准输出,这样简单好写。但 stdio 是无法 seek 的,这就意味着你只能从视频的开头看起,无法快进 :P 如你所见,现在的解决方案是用 HTTP 协议与播放器传输数据。需要快进的时候播放器发送 HTTP Range 请求,video_funnel 将请求中的范围经过分块、切片后“多线程”下载。但这样就又带来了两个问题:
由于下载的部分是用异步 IO 写的,与播放器交互的服务器部分就不能使用 Flask 之类阻塞的框架了,幸好 aiohttp 居然同时支持客户端和服务端。
说起来简单,实际写起来处处是坑啊 :(
刚刚把输出调整了以下,用上了进度条,大家快来更新啊 ;-D
$ pip install video_funnel --upgrade
$ vf https://tulip.ink/test.mp4 &
* Listening at port 8080 ...
$ mpv http://localhost:8080 --no-ytdl --quiet
Playing: http://localhost:8080
Block #0: 15%|████▏ | 600k/4.00M [00:02<03:30, 17.0kB/s]
1
nazor 2018-01-05 23:40:45 +08:00 via iPhone 2
挺好的,要是能用 js 实现就更好了。
|
2
davy1995 2018-01-05 23:47:01 +08:00 via Android 1
可以可以,很实用啊感觉
|
3
mingyun 2018-01-06 00:08:17 +08:00 1
$ pip install video_funnel
Collecting video_funnel Could not find a version that satisfies the requirement video_funnel (from ver sions: ) No matching distribution found for video_funnel |
4
CSM OP |
5
zingl 2018-01-06 00:24:10 +08:00 1
youtube 就是这个套路
|
7
diggerdu 2018-01-06 00:46:31 +08:00 via iPad 1
mo 一波 dalao 的 aiodl 真不错
|
8
madfloyd 2018-01-06 01:10:00 +08:00 via Android 1
大有用处。。。搞个视频网站
|
9
netsail 2018-01-06 01:37:27 +08:00 via iPad 1
前排围观支持!!!
|
10
ryd994 2018-01-06 01:52:38 +08:00 via Android 6
aria2c -x10 --stream-piece-selector=inorder
|
12
CSM OP 不过 aira2 貌似不能快进?容我加上”边看边下“的功能 :)
|
13
linap 2018-01-06 07:59:56 +08:00 via Android
mark.摩拜大佬
|
14
wzhndd2 2018-01-06 09:36:21 +08:00
mark.摩拜大佬
|
15
chen2016 2018-01-06 10:22:44 +08:00 via Android
收藏多,回复少,一群大佬准备大干
|
16
honkew 2018-01-06 10:33:43 +08:00 1
这个叫做 串流播放
|
17
gabrielsong 2018-01-06 10:58:01 +08:00 via Android
膜拜大佬…
|
19
zqqian 2018-01-06 12:22:56 +08:00
mark.摩拜大佬
|
20
wcsjtu 2018-01-07 12:05:11 +08:00 via Android
TS 流怎么搞……
|
22
cnaol 2018-01-07 21:56:07 +08:00
Command "python setup.py egg_info" failed with error code 1 in C:\Users\UrAir\AppData\Local\Temp\pip-build-4koh515g\video-funnel\
怎么破 |
24
cnaol 2018-01-07 22:55:57 +08:00
@CSM
> PS F:\myproject> pip install --user video_funnel Collecting video_funnel Using cached video_funnel-0.0.3.tar.gz Complete output from command python setup.py egg_info: Traceback (most recent call last): File "<string>", line 1, in <module> File "C:\Users\UrAir\AppData\Local\Temp\pip-build-v519sou0\video-funnel\setup.py", line 29, in <module> 'vf = video_funnel.__main__:main' File "c:\users\urair\appdata\local\programs\python\python36\lib\distutils\core.py", line 108, in setup _setup_distribution = dist = klass(attrs) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\dist.py", line 315, in __init__ self.fetch_build_eggs(attrs['setup_requires']) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\dist.py", line 361, in fetch_build_eggs replace_conflicting=True, File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\pkg_resources\__init__.py", line 850, in resolve dist = best[req.key] = env.best_match(req, ws, installer) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\pkg_resources\__init__.py", line 1122, in best_match return self.obtain(req, installer) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\pkg_resources\__init__.py", line 1134, in obtain return installer(requirement) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\dist.py", line 429, in fetch_build_egg return cmd.easy_install(req) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\command\easy_install.py", line 653, in easy_install not self.always_copy, self.local_index File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 636, in fetch_distribution dist = find(requirement) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 617, in find dist.download_location = self.download(dist.location, tmpdir) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 566, in download found = self._download_url(scheme.group(1), spec, tmpdir) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 805, in _download_url return self._attempt_download(url, filename) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 811, in _attempt_download headers = self._download_to(url, filename) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 710, in _download_to fp = self.open_url(strip_fragment(url)) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 747, in open_url return open_with_auth(url, self.opener) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 948, in _socket_timeout return func(*args, **kwargs) File "c:\users\urair\appdata\local\programs\python\python36\lib\site-packages\setuptools\package_index.py", line 1067, in open_with_auth fp = opener(request) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 223, in urlopen return opener.open(url, data, timeout) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 526, in open response = self._open(req, data) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 544, in _open '_open', req) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 504, in _call_chain result = func(*args) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 1361, in https_open context=self._context, check_hostname=self._check_hostname) File "c:\users\urair\appdata\local\programs\python\python36\lib\urllib\request.py", line 1321, in do_open r = h.getresponse() File "c:\users\urair\appdata\local\programs\python\python36\lib\http\client.py", line 1331, in getresponse response.begin() File "c:\users\urair\appdata\local\programs\python\python36\lib\http\client.py", line 297, in begin version, status, reason = self._read_status() File "c:\users\urair\appdata\local\programs\python\python36\lib\http\client.py", line 258, in _read_status line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") File "c:\users\urair\appdata\local\programs\python\python36\lib\socket.py", line 586, in readinto return self._sock.recv_into(b) File "c:\users\urair\appdata\local\programs\python\python36\lib\ssl.py", line 1009, in recv_into return self.read(nbytes, buffer) File "c:\users\urair\appdata\local\programs\python\python36\lib\ssl.py", line 871, in read return self._sslobj.read(len, buffer) File "c:\users\urair\appdata\local\programs\python\python36\lib\ssl.py", line 631, in read v = self._sslobj.read(len, buffer) socket.timeout: The read operation timed out ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in C:\Users\UrAir\AppData\Local\Temp\pip-build-v519sou0\video-funnel\ |
25
CSM OP @cnaol 看最后一行,socket.timeout: The read operation timed out 应该是网络原因,换个 pip 源或挂代理试试
|
26
learningman 2019-02-25 19:11:12 +08:00 via iPad
* Listening at port 8080 ...
Error handling request Traceback (most recent call last): File "/root/.local/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 418, in start resp = await task File "/root/.local/lib/python3.6/site-packages/aiohttp/web_app.py", line 458, in _handle resp = await handler(request) File "/root/.local/lib/python3.6/site-packages/video_funnel/__init__.py", line 85, in handler del request.headers['Host'] TypeError: 'multidict._multidict.CIMultiDictProxy' object does not support item deletion 貌似库改了 |
27
vcheckzen 2019-03-01 17:53:44 +08:00 via Android
windows 下安装了找不到 vf 命令
|