sodaling / FastestBilibiliDownloader

B站视频极速批量下载器|The fastest Bilibili video downloader
682 stars 109 forks source link

下载单个视频,但会启动8个线程下载 #9

Closed justin201802 closed 4 years ago

justin201802 commented 4 years ago

aid:28899117 运行程序后, 会有8个线程下载, 但磁盘上只有1个文件, 而且大小也不正确, 不能正常播放视频。

A:\FastestBilibiliDownloader-master\cmd>go run start-concurrent-engine.go
Please enter your id type(`aid` or `upid`)
aid
Please enter your id
28899117
2020/03/27 23:58:22 Start working.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/27 23:58:22 28899117:1.flv is downloading.
2020/03/28 00:00:02 28899117:1.flv has finished.
2020/03/28 00:00:02 28899117  download completed.Start merging videos now.
2020/03/28 00:00:03 Video  28899117  merge is complete.
2020/03/28 00:00:13 28899117:1.flv has finished.
2020/03/28 00:00:25 28899117:1.flv has finished.
2020/03/28 00:00:33 28899117:1.flv has finished.
2020/03/28 00:00:34 28899117:1.flv has finished.
2020/03/28 00:00:46 28899117:1.flv has finished.
2020/03/28 00:00:54 28899117:1.flv has finished.
2020/03/28 00:01:29 28899117:1.flv has finished.
2020/03/28 00:01:29 All work has done
sodaling commented 4 years ago

哥们哈,这边虽然你的是1个视频,但是这个视频比较长,b长上面一共分了8段的,所以这边是同时开了8线程并发下载的. 不过你说的对,我没想到会出现一共cid分多个part的情况,这边我更新了代码,修复了一下,应该可以了,你再更新代码后试试?

justin201802 commented 4 years ago

下载模块应该是正常工作了, 但是。。。。。。 下载完毕后, 下载的文件都消失了

A:\FastestBilibiliDownloader\cmd>go run start-concurrent-engine.go
Please enter your id type(`aid` or `upid`)
aid
Please enter your id
28899117
2020/03/28 19:14:10 Start working.
2020/03/28 19:14:11 28899117:1_8.flv is downloading.
2020/03/28 19:14:11 28899117:1_4.flv is downloading.
2020/03/28 19:14:11 28899117:1_1.flv is downloading.
2020/03/28 19:14:11 28899117:1_3.flv is downloading.
2020/03/28 19:14:11 28899117:1_5.flv is downloading.
2020/03/28 19:14:11 28899117:1_7.flv is downloading.
2020/03/28 19:14:11 28899117:1_2.flv is downloading.
2020/03/28 19:14:11 28899117:1_6.flv is downloading.
2020/03/28 19:15:50 28899117:1_4.flv has finished.
2020/03/28 19:16:00 28899117:1_5.flv has finished.
2020/03/28 19:16:14 28899117:1_2.flv has finished.
2020/03/28 19:16:21 28899117:1_3.flv has finished.
2020/03/28 19:16:23 28899117:1_6.flv has finished.
2020/03/28 19:16:35 28899117:1_7.flv has finished.
2020/03/28 19:16:43 28899117:1_1.flv has finished.
2020/03/28 19:17:18 28899117:1_8.flv has finished.
2020/03/28 19:17:18 28899117  download completed.Start merging videos now.
2020/03/28 19:17:18 Video  28899117  merge is complete.
2020/03/28 19:17:18 All work has done

原本能看见那些flv文件, 但work has done之后就全部没有了。

sodaling commented 4 years ago

不对啊,下载完成后,文件夹下面会有个最后合并成的outpu.mp4啊.文件下什么都没有么?

justin201802 commented 4 years ago

没有任何文件, 下载的8个flv也消失了。

justin201802 commented 4 years ago

你那里可以成功输出output.mp4?如果确定可以的话, 我就去看看代码,是什么原因造成的。

sodaling commented 4 years ago

我用正常go run 或者docker方式跑都可以的呢,要不这样,你把这行注释掉,看看可以不. https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/persist/videomerge.go#L85 这个是下载完一个aid后,然后清楚之前合并之前的文件的代码,你看看不清除的话会保留哪些文件

justin201802 commented 4 years ago

注释掉85行, 下载的临时文件还在, 我觉得可能的问题是, 没有找到FFMPEG程序, 但你的程序没有报merge出错, 导致未输出output, 又把临时文件删除了。

justin201802 commented 4 years ago

把ffmpeg放在cmd目录下, 最终还是没有生成output.mp4

sodaling commented 4 years ago

程序会在启动时候,先判断有没有ffmpeg环境。 https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/tool/path.go#L28 这个函数的作用就是判断有没有FFmpeg的,基本来说就是判断系统的有没有可执行的FFmpeg命令,简单的把FFmpeg放到cmd的文件夹下是没用的。必须是在系统的PATH变量下的路径,能找到FFmpeg才行。 如果这么说的话,这个函数在你的系统通过了FFmpeg的检测,你直接在命令行输入ffmpeg可以启动的了这个程序。 不过在调用ffmpeg这个程序合并时候出错了。这边问一句,你的系统是Windows是吧?你在命令行能通过简单输入ffmpeg启动程序么?方便给一下你在命令行输入ffmpeg后的输出么?

justin201802 commented 4 years ago
C:\Users\home>ffmpeg
ffmpeg version git-2020-03-12-675bb1f Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.2.1 (GCC) 20200122
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
  libavutil      56. 42.100 / 56. 42.100
  libavcodec     58. 75.100 / 58. 75.100
  libavformat    58. 41.100 / 58. 41.100
  libavdevice    58.  9.103 / 58.  9.103
  libavfilter     7. 77.100 /  7. 77.100
  libswscale      5.  6.101 /  5.  6.101
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

直接命令行输入ffmpeg是可以运行的

C:\Users\home>where ffmpeg.exe
F:\VideoTools\ffmpeg-20200312-675bb1f-win64-static\bin\ffmpeg.exe

最终运行的ffmpeg代码如下

A:\FastestBilibiliDownloader-master\cmd> ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt -c copy A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv
ffmpeg version git-2020-03-12-675bb1f Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.2.1 (GCC) 20200122
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
  libavutil      56. 42.100 / 56. 42.100
  libavcodec     58. 75.100 / 58. 75.100
  libavformat    58. 41.100 / 58. 41.100
  libavdevice    58.  9.103 / 58.  9.103
  libavfilter     7. 77.100 /  7. 77.100
  libswscale      5.  6.101 /  5.  6.101
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
[concat @ 000001d8f56f9d80] Impossible to open 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv'
A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt: Invalid argument
sodaling commented 4 years ago

哥们,首先说声非常感谢,真的非常感谢你不厌其烦的反馈意见。 而且你的反馈都非常详细且明确,我大概知道问题的所在了。不过最近事有点多,这边我下个周末花点时间好好折腾一下呢。 再次非常感谢,说实话,这个项目除了花费了我一些心血以外,也是陪伴了我一段比较难熬的岁月,里面也有对我比较重要的人的回忆。所以,你对这个项目的详细反馈其实真的让我非常感动。我答应你我会好好解决这个问题的。

justin201802 commented 4 years ago

在V2EX上看到这个项目, 正好有需求, 就顺手用了。 其实对目录结构的调整上, 我自己修改过了部分代码, 不过这次你的改动有点大, 准备等你把问题解决后, 我再提交一个PR。 我增加了bvid转av的功能, 文件夹名称改为视频的标题之类的。 主要是对GOLANG不熟悉, 只能按照你的代码修修改改。 这个分段下载视频的功能, 我自己搞不定~

sodaling commented 4 years ago

哦我的老伙计!!!! 我的天啊!!! 感动cry!!!!! 我这代码当初写的时候输入法出问题了,中文输入不了,就基本没写注释,没想到还有人愿意阅读我的代码!! 狂respect!!! 成,我记住了,我速度搞定他!

sodaling commented 4 years ago

顺便说一声,如果正常方式启动有问题?要不试试docker方式来启动? 当然,这个问题我肯定会搞定他的,这几天下班晚and just break up。。。所以稍微等几天才能折腾,所以万分见谅。

顺便,你那个av28899117。。。。这视频那么长,后面半段都是空的。。。导致视频白分了好多段,我测试时候的视频一个cid只有1个视频,所以以为cid就代表视频了。遇到你这个视频我才发现,一个cid下面还可以继续分好几个视频,真的长知识了,所以大幅度改了不少代码。 再次感谢,这个项目见证了我许多,你的在意,真的万分让我感动。

sodaling commented 4 years ago

我才发现之前反馈文件路径问题也是兄弟你!我的天!https://github.com/sodaling/FastestBilibiliDownloader/issues/8 这边真的非常抱歉了,那段时间答应了速度搞定,but i broke up that week。。。 这周收拾心情时候才把路径问题修复了。真是惭愧,因为这边手头没有Windows平台,所以没法测然后还有新的问题产生,我这真丢人了。兄弟再次见谅一个哈!

sodaling commented 4 years ago

顺便,如果兄弟真的打算下载整个up的视频的话,https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/cmd/start-concurrent-engine.go#L42 这一行,30是最多开多少个worker下载(注意不是线程,因为golang强调的是groutine而不是线程,所以未必30个就会开30个线程)。你按照自己需要调大就好,我这边写死注意是不想用的人无脑开大。

sodaling commented 4 years ago
[concat @ 000001d8f56f9d80] Impossible to open 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv'
A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt: Invalid argument

同时我看到你测的自己输入的合并命令,我发现这个命令里面的文件路径应该是错误的,所以你手动输入命令才会报错。

那么方便在https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/persist/videomerge.go#L71 和 https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/persist/videomerge.go#L81 下面加入下面的打印命令,输出一下到底程序里面运行的命令是什么样的,然后自己手动输出一遍看看报什么错么?

fmt.Println(command)
justin201802 commented 4 years ago
[ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt -c copy A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv]
[ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt -c copy A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/output.mp4]

contact.txt这个文件里面只有1.flv, 是不是应该有8个文件?

justin201802 commented 4 years ago
PS A:\FastestBilibiliDownloader-master\cmd> ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt -c copy A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv
ffmpeg version git-2020-03-12-675bb1f Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.2.1 (GCC) 20200122
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
  libavutil      56. 42.100 / 56. 42.100
  libavcodec     58. 75.100 / 58. 75.100
  libavformat    58. 41.100 / 58. 41.100
  libavdevice    58.  9.103 / 58.  9.103
  libavfilter     7. 77.100 /  7. 77.100
  libswscale      5.  6.101 /  5.  6.101
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
[concat @ 0000024ec2689d80] Impossible to open 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv'
A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt: Invalid argument
PS A:\FastestBilibiliDownloader-master\cmd> 

contact.txt文件内容

file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv'
sodaling commented 4 years ago

首先先解释一下,b站的视频是这样的(按照老版本的aid): 1个aid代表一个av123456,但是不一定是一个视频就是了,因为视频上传上去,作者有可能分多个p,比如p1,p2这种。然而每个p1,p2都有一个cid代表。就像之前说的,我以为cid就是最小颗粒了,但是你的视频才让我发现,原来一个cid里面,还可能因为时长分成多个部分。比如你的就分成了8份。

那么你的视频,只有1个p,里面有8份。我的程序下载下来的时候就会是这样的视频 1_1.flv 1_2.flv。。。。。。1_8.flv 当然了,如果有p2就会有2_1flv这样的。

那么我的程序把1个aid下面的所有视频下载下来之后,每个文件夹(aid为单位)下面,只会是n_x.flv这样的格式。 然后会进行两次合并: 第一次合并:比如你的视频,就会把1_1.flv到1_8.flv合并成1.flv,这个1.flv就代表一个cid了。当然了,你的视频作者没分p,所以1.flv已经是所有p了。 第二次合并,会把所有n.flv(也就是cid)合并成一个contact.flv(最后aid输出)。

然后清除所有临时文件,也就是所有除了contact.flv文件的文件。

两次合并,都会以contact.txt里面的内容为参数。第一次合并前往这个文本文档写一次,第一次合并后不删除从头再写一次。

所以你现在contact.txt里面是第二次写的内容。

这么看来,第一次合并已经成功了,输出了1.flv

sodaling commented 4 years ago

那么问题来了,为什么第一次成功了第二次没有?有点神奇。这样,如果你方便的话,帮我在你那里调试一下。在这一行: https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/persist/videomerge.go#L75 下面直接加return,也就是不让它合并第二次了直接结束。因为下面的是第二次合并的内容了,同时contact.txt里面的会被重写第二次。我想知道,第一次到底写了什么,为啥第一次成功合并了第二次没有?

sodaling commented 4 years ago

而且让我有点疑惑的是,ffmpeg命令为啥是

A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1.flv,这个路径的斜杠为啥有/\这两种斜杠。而我里面路径拼接都不是自己手拼的而是用golang的join函数拼的,按道理不会错啊?

justin201802 commented 4 years ago

找到问题所在了,createMergeCidInfoTxt创建的时候, 路径虽然带有\和/,但这2个windows都可以识别。 但是, ffmpeg的-i参数, 如果用了 ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/contact.txt -c copy 1.flv 就不行, -i的参数, 一定要是这样的 ffmpeg -f concat -safe 0 -i A:\FastestBilibiliDownloader-master\cmd\download\28899117_28899117\contact.txt -c copy 1.flv

或者contact.txt的内容从

file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_1.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_2.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_3.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_4.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_5.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_6.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_7.flv'
file 'A:\FastestBilibiliDownloader-master\cmd/download/28899117_28899117/1_8.flv'

改为

file '1_1.flv'
file '1_2.flv'
file '1_3.flv'
file '1_4.flv'
file '1_5.flv'
file '1_6.flv'
file '1_7.flv'
file '1_8.flv'

这样的话, 就算ffmpeg命令的分隔符带/,但也能正常工作。

sodaling commented 4 years ago

那我知道为啥了,cmd前面\格式,是在 https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/tool/path.go#L11 获取的,这里获取出的,在Windows时候是\,但是在后面接download时候,是在https://github.com/sodaling/FastestBilibiliDownloader/blob/3d145d37b196caa59515af1e70fc0d7eca43b61f/tool/path.go#L15 利用path.join来连接的,这里用的是/。其实对于Windows来说两个都能识别,但是对于ffmpeg来说就不行了,彻底明白了

sodaling commented 4 years ago

我下意识的以为,golang的path.join是会根据系统来区分符号连接路径的,但是刚刚查了一下文档,按照文档的说法:

Join joins any number of path elements into a single path, separating them with slashes.

也就是golang无脑用的是/。彻底明白了。我用错函数了,应该用的是filepath.Join,而不是path.join。在filepath.Join的文档有说:

Join joins any number of path elements into a single path, separating them with an OS specific Separator.

这样明白了,我等等提交一份更新,你有空的话可以帮忙测一下嘛?

sodaling commented 4 years ago

4bd630957a1294eec547ba70d953bbef5759015e,这里提交了一个commit,修改了所有类似错误的地方。谢谢兄弟,1个issue发现了2个大bug

justin201802 commented 4 years ago

晚上回去试试, 公司的电脑无法下载go的那几个组件。 BTW: cid需要merge我理解, 那aid为啥也需要merge? aid下有多少章节的视频, 不应该就有多少个视频文件吗?

sodaling commented 4 years ago

你的意思是,假设一个aid下面有几个p,比如p1,p2之类的,就不用把他merge起来的意思么。也有道理。主要是之前我看的几个项目都是merge起来的,所以下意识想的就把他merge了。

但是你觉得不用merge的话我也觉得也行,那就在读取配置时候加个参数让使用者决定?

justin201802 commented 4 years ago

测试成功,现在可以正确输出output.mp4了

justin201802 commented 4 years ago

我个人使用下来, 觉得aid不需要合并, 因为很多章节视频都是带标题的, 可以很清晰的分辨出是什么内容。

sodaling commented 4 years ago

成,晚点我会在readme好好感谢你一下。顺便你说你写了bid的功能,方便提一下pr不?你提了pr后我继续更新选择合并aid的代码。

justin201802 commented 4 years ago

嗯, 我在下载另一个视频的时候又遇到点问题, bvid与avid互转的信息参考以下网址, 其实有api可以调用 https://www.v2ex.com/t/655569

sodaling commented 4 years ago

擦???又有啥问题???我的项目这么千疮百孔么擦

调用api就算了,有思路就直接用就是了,不过我想着你如果愿意提交代码的话可以作为contributor,这项目你也帮忙真心不少

justin201802 commented 4 years ago

嗯, 我还在测试。你现在的版本, 是最终输出一个视频文件, 我修改成了每个cid输出一个视频, 最终merge的时候, 只输出了一个, 我还再看代码, 解决了这个问题我再提交代码。