# B23Downloader **Repository Path**: boarmy_1_boarmy/B23Downloader ## Basic Information - **Project Name**: B23Downloader - **Description**: 下载B站 视频(投稿视频、番剧、电影、课程)、直播、漫画。(使用 Qt C++ 开发) - **Primary Language**: Unknown - **License**: GPL-3.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2022-02-02 - **Last Updated**: 2022-02-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
简单,但也够用了。没有历史记录功能。(当然,对于正在下载的任务,关闭程序后再打开还是在的)
在上图中,选择的下载位置为 **E:/tmp**,那么选中的两个视频分别下载到
- **E:/tmp/天气之子 原版.flv** 和
- **E:/tmp/天气之子 预告花絮 MV1 爱能做到的还有什么.flv**
### 漫画
如上图,下载位置还是 **E:/tmp**,选中的两项分别下载到文件夹
- **E:/tmp/恋如雨止 81 第81话/** 和
- **E:/tmp/恋如雨止 82 最终话/**
漫画是一页一页下载的,在该示例中,*82 最终话* 将下载为 **E:/tmp/恋如雨止 82 最终话/01.jpg - 32.jpg**(32 张图片)。
> 目前删除漫画下载任务会粗暴地删除整个文件夹,如示例中的 E:/tmp/82 最终话/
### 直播
上图中,对话框的标题为 *【哔哩哔哩英雄联盟赛事】【直播】HLE vs LNG*,其命名规则为【<用户名>】<房间标题>,示例中用户名为 *哔哩哔哩英雄联盟赛事*,房间标题为 *【直播】HLE vs LNG*。
下载文件的命名为 <标题> <下载开始时间>.flv,比如【哔哩哔哩英雄联盟赛事】【直播】HLE vs LNG [2021.10.05] 18.59.22.flv,其所在文件夹为上图中所选的 **E:/tmp/**
目前的直播下载任务策略为:
- 暂停直播下载任务后重新开始,会写入另一个文件,比如 【哔哩哔哩英雄联盟赛事】【直播】HLE vs LNG [2021.10.05] **19.32.11**.flv
- 删除任务不会删除任何相关文件
- 任务不会被保存,即退出程序后再启动,之前的直播下载任务不被保留
> 如果添加直播下载任务时,正在下载的任务数量超过最大可同时下载任务数(代码里硬编码为 3),那么这个直播下载任务会处于“等待下载”状态。
最初我是用 ffmpeg 来下载直播的,那时得到的文件并没有问题。2021 年 05 月,我尝试用 wget 直接下载而不是通过 ffmpeg,发现下载的文件有「无法拖动进度条」的问题,如果用 ffmpeg 处理 (remux) 一下就正常了:ffmpeg -i <raw_file> -c copy <remuxed_file>。
由于不想引入 ffmpeg 依赖,而且 FLV 还算简单,我决定自己实现 FLV remuxing. 首先就是读 Adobe FLV 文档,挺少的也就 10 页。然后写了些代码解析并打印信息(FlvParse.exe 这小工具有些问题,没解析出 AMF Object,tag header 中 duration 也是错的)。
![]() | ![]() |
"keyframes:{ "times":[], "filepositions":[], "spacer":[] }""keyframes:{ "times":[], "spacer1":[], "filepositions":[], "spacer2":[] }"位置:main.cpp
需求:在打开时,如果应用已在运行,则弹出已在运行的应用窗口,新运行的应用退出。
通过搜索引擎可以找到 QtSingleApplication, SingleApplication, 以及一些轻量些的解决方法。其中,因为一些资源在 Unix 平台上由 qt 而不是 os 拥有,其在程序崩溃后不会被回收,所以在 Unix 平台时要多一些操作。简单起见,我就不管 Windows 之外的平台了。
要判断应用是否已在运行,可以在执行时尝试创建某种命名的资源,如果返回错误“已被创建”,则说明应用已在运行。可选的有: QSharedMemory, QLockFile, CreateMutexA (WinApi) 等
弹出已在运行的应用,网上找到的都是用 QLocalServer 和 QLocalSocket 实现的,本质就是进程间通信。在 Windows 上,设置窗口到最前方 (foreground) 是有限制的,即应用不能自己把自己弹到最前面(防止流氓程序)。foreground 程序将另一个程序设置为 foreground 是允许的,这里新运行的那个程序就是 foreground。让新进程获取原进程的 hWnd (handle to a window),如果已最小化就调用 ShowWindow(hWnd, SW_RESTORE),否则调用 SetForegroundWindow(hWnd)。
最后选择用 QSharedMemory 来实现 HWND 的共享,QSharedMemory::create() 用来判断应用是否已运行。