移动开发音视频【免费下载链接】BilibiliCacheVideoMergeAndroid上将bilibili缓存视频合并导出为mp4支持安卓5.0 ~ 13视频挂载弹幕播放(Android consolidates and exports the bilibilibili cache video to mp4, supports Android 5.0~13, and plays the video on the screen)项目地址https://gitcode.com/gh_mirrors/bi/BilibiliCacheVideoMerge点击查看免费下载本篇技术指南围绕开源项目 BilibiliCacheVideoMerge应用名HLB站缓存合并展开系统讲解其在 Android 上将哔哩哔哩缓存视频合并导出为 MP4 的完整原理与实现从缓存文件结构解析、entry.json元数据提取到三种导出模式有声音视频 / 无声音视频 / 仅音频、双 FFmpeg 引擎抽象、Android 5.0 ~ 13 的存储访问适配以及合并后视频挂载本地弹幕xml播放的完整链路。读完本文你将掌握该项目缓存扫描 → 元数据解析 → 合并导出 → 弹幕播放的整体架构并可直接参照源码复现或扩展同类工具。一、项目定位与核心能力BilibiliCacheVideoMerge 是运行在 Android 端的 B 站缓存视频合并工具正如其在 README.md 中的定位Android 上将 bilibili 缓存视频合并导出为 mp4支持安卓 5.0 ~ 13视频挂载弹幕播放。作者将其比喻为专用的格式工厂它不做任何破解只负责把 B 站 App 已经缓存的视频文件重组为标准媒体文件仅用于学习技术交流。特性清单来自 README.md 的特性列表含已完成与未完成项合并导出B 站缓存有声音视频、无声音视频、仅音频番剧、电影合并导出支持安卓 5.0 ~ 13理论上视频挂载弹幕播放未完成更新本地弹幕、下载封面未完成的两项在 MainToolsFragment.kt 的工具页有对应入口执行 ffmpeg 命令、下载弹幕、下载封面但按钮点击目前统一回调Mtools.toast(开发中....)与 README 中的未勾选状态一致。需要特别说明的是README 顶部已声明此项目已不再维护作者已使用 Flutter 重构了同名项目hlbmerge_flutter。因此本文以当前仓库源码为准介绍其设计与实现细节供学习与二次开发参考。二、B 站缓存文件结构解析合并的原料从哪来要合并 B 站缓存第一步是理解 B 站缓存目录的组织形式。仓库通过数据模型 CacheFile.kt 对缓存条目做了三级建模合集Collection对应一部番剧/一个视频合集含多个章节章节Chapter合集下的每一集返回Back列表导航用的返回上一级虚拟条目对应的常量定义在 BaseCacheFileManager.ktcompanion object { const val FLAG_CACHE_FILE_COLLECTION: Int 0 // 合集 const val FLAG_CACHE_FILE_CHAPTER: Int 1 // 章节 const val FLAG_CACHE_FILE_BACK: Int -1 // 返回 }缓存目录的物理结构B 站各版本 App 的默认缓存根目录被硬编码在 ConfigData.ktB 站版本包名默认缓存路径Android/data 下国内版tv.danmaku.bili/tv.danmaku.bili/download国际版com.bilibili.app.in/com.bilibili.app.in/download平板 HDtv.danmaku.bilibilihd/tv.danmaku.bilibilihd/download概念版com.bilibili.app.blue/com.bilibili.app.blue/download一个典型章节缓存目录形如download/ └── 合集ID/ └── 章节ID/ ├── audio.m4s # 纯音频流 ├── video.m4s # 纯视频流 ├── entry.json # 元数据标题、分P、封面、BV号 └── danmaku.xml # 本地弹幕可选关键文件的递归定位FileTool.java 中的getNeedPath以递归方式遍历章节目录按文件名精确匹配audio.m4s、video.m4s、entry.json、danmaku.xml并写入泛型容器 CacheSrc.ktswitch (files[i].getName()) { case audio.m4s: result.setAudio(files[i].getAbsolutePath()); break; case video.m4s: result.setVideo(files[i].getAbsolutePath()); break; case entry.json: result.setJson(files[i].getAbsolutePath()); break; case danmaku.xml:result.setDanmaku(files[i].getAbsolutePath());break; }其中CacheSrcT是一个支持链式 setter 的四字段泛型容器audio/video/json/danmaku它既可以被填充为String文件路径也可以填充为UriAndroid 11 的文档 URI这是项目同时支持两种存储访问模式的关键设计。完整性校验FileTool.needSrcErrorHandle会对扫描结果做校验audio.m4s、video.m4s、entry.json三者缺一即返回错误文案如xxx下audio.m4s,video.m4s,entry.json没找到注意danmaku.xml在错误拼接中被注释掉即弹幕缺失不影响合并仅影响后续弹幕播放。entry.json 元数据解析FileTool.java 的getCollectionChapterNameByJsonStr负责从entry.json提取列表展示与输出命名所需的全部信息解析优先级如下封面cover字段 →result[2]用于列表 Glide 加载封面图视频 ID优先bvid缺失时回退为av avid→result[3]写入导出视频的metadata title合集名title字段并会经LConstants.SPECIAL_CHARACTERS_REGULAR_RULE正则剔除\t\r\n及各种特殊符号[\t\r\n\~!#$%^*()|{}:;,[]./?~#%……——|{}【】‘”“’。、-]避免生成非法文件名章节名优先取page_data.download_subtitle普通视频番剧则取ep.index_title若page为 1仅一集直接以合集名代替章节名解析失败时回退到part字段再失败则用 UUID 兜底缓存扫描完成后PathCacheFileManager.kt 会把每个合集/章节组装成CacheFile交给列表展示合集条目显示collectionName collectionPath章节条目显示chapterName chapterPath见 CacheFileListAdapter.kt。三、三种导出模式与完整合并流程导出模式定义三种导出模式定义在 strings.xml 的judge_merge_dialog_export_type数组中在 MergeProgressDialog.java 中对应exportType的 0/1/2 三个分支exportType模式输入文件输出格式处理方式0有声音视频audio.m4svideo.m4s.mp4FFmpeg 音视频流合并-c copy拷贝1无声音视频video.m4s.mp4直接复制并重命名2仅音频audio.m4s.mp3直接复制并重命名合并选项弹窗点击章节或点击底部的合并按钮后MergeOptionDialog.kt 会弹出 dialog_judge_merge.xml 对话框包含标题提示你确定要转换该视频或者合集吗MaterialSpinner下拉框选择导出模式有声音视频/无声音视频/仅音频SwitchButton开关导出弹幕(xml)开启后合并的同时会把danmaku.xml复制到输出目录同名.xml文件合并执行流程MergeProgressDialog.java 的showMergeProgressDialog是合并主入口流程如下合集转章节若选中合集先通过PathCacheFileManager.collection2ChapterCacheFileList或UriCacheFileManager.collection2ChapterCacheFileList将合集展开为所有章节进度弹窗以章节数为总进度准备输出目录outRoot ConfigData.getOutputFilePath()若配置了单一输出目录singleOutputDir所有文件直接输出到根目录否则按outRoot/合集名/章节名.扩展名分层输出逐章节执行输出文件已存在时弹出文件已经存在对话框提供都保存自动追加(0)(1)...序号、覆盖、取消三个选项若开启导出弹幕先FileUtils.copy(danmakuPath, completeOutPath .xml)按exportType走 FFmpeg 合并或直接复制任务链收尾使用 xuexiangjys/XTick源码中为XTask.getTaskChain串行执行完成后弹窗显示成功数/失败数/保存目录失败时显示错误信息FFmpeg 命令模板合并的核心命令模板保存在ConfigData.getFfmpegCmdTemplate()默认值ConfigData.ktffmpeg -i %s -i %s -metadata title%s -c copy %s四个%s占位符依次为输入音频、输入视频、bvId、输出视频设置页提示文案原话为请使用三个%s分别代表输入音频、输入视频、bvId、输出视频。-metadata title%s会把 BV 号写入导出文件的元数据播放页据此跳转原视频。strings.xml 还预置了第二套模板带aac_adtstoascbitstream filter 的兼容写法ffmpeg -i %s -i %s -metadata title%s -c:a copy -c:v copy -bsf:a aac_adtstoasc %s用户在设置页可自定义模板。需要注意命令最终会被按空格分割成参数数组执行见下文 FFmpeg 核心因此模板中不应出现带空格的文件路径。四、FFmpeg 双引擎抽象RxFFmpeg 与 FFmpegCommand项目将 FFmpeg 执行能力抽象为 BaseFFmpegCore.kt定义四个核心方法setDebug、getFFmpegCallback、runCommand同步执行、exitRunCommand取消任务。两个引擎实现RxFFmpegCore.kt基于 microshow/RxFFmpeg调用RxFFmpegInvoke.getInstance().runCommand(cmd, listener)退出用exit()FFmpegCommandCore.kt基于 AnJoiner/FFmpegCommand调用FFmpegCommand.runCmd(cmd, callback)取消用cancel()两者都将命令字符串cmdStr.split( )拆分为参数数组后执行且执行前会Mtools.log打印核心类名 完整命令便于调试。回调与进度统计BaseFFmpegCallback.kt 统一回调逻辑onFinish()进度 1、successNum、清理临时目录onError()进度 1、failNumonProgress()把progress与时间戳除以 1000000 转秒更新到弹窗内容onCancel()取消弹窗RxFFmpegCallback与FFmpegCommandCallback分别实现各自引擎的回调接口后委托给上述基类。引擎的反射加载在 ConfigData.kt 的initFFmpegCore中根据构建类型BuildConfig.FFMPEG_CORE_TYPE决定加载哪个引擎当构建同时打包两个引擎FFMPEG_CORE_TYPE_All时运行时通过getFfmpegCoreType()配置选择并使用反射ReflectUtils.reflect(...).newInstance()实例化使 App 在不改代码的情况下于设置页切换引擎SettingsActivity.kt 的ms_ffmpeg_core_type下拉框。五、Android 5.0 ~ 13 存储访问适配路径模式与 SAF Uri 模式这是本项目最具兼容性价值的设计。Android 11R开始强制分区存储直接访问/Android/data目录受限因此项目针对两种场景提供双套文件管理器统一实现 ICacheFileManager.kt实现类适用场景数据载体元数据来源PathCacheFileManager.ktAndroid 10 及以下或路径可直读String绝对路径直接读取entry.json文件UriCacheFileManager.ktAndroid 11/Android/data受限Uri文档 URI通过 SAF 读取并用 MMKV 缓存自动判断与权限授权MainFileShowFragment.java 初始化列表时调用FileTools.underAndroidDataUseUri(ConfigData.getCacheFilePath())判断当前缓存路径是否需要走 Uri 模式UriTool.java 的grantedUriPermission在需要时引导用户通过系统文件选择器授权目录访问权限Shizuku 与 SAF 双通道见 GeneralTools.kt 的getShizukuPermission与 AndroidManifest.xml 中声明的 ShizukuProvider。MMKV 元数据缓存与临时文件落地Uri 模式下每次扫描目录都通过ContentResolver读取entry.json开销较大因此 UriCacheFileManager.kt 用腾讯 MMKV 做缓存key 为TEMP_DATA_PERFIX_ documentFile.getUri()value 为 CacheDo.javaParcelable存 audio/video/json/danmaku 的 Uri 字符串及 title/subTitle/coverUrl/bvId缓存过期时间MMKV.ExpireInMinute并配合 ConfigData.kt 的autoClearTempData每周自动清理一次合并时MergeProgressDialog.java 的cacheFileUri2File会把 Uri 指向的audio.m4s/video.m4s/danmaku.xml通过 UriTool.java 的documentFile2File流式复制到临时目录/bilibili视频合并/temp并实时更新复制音频/视频/弹幕进度随后克隆一份CacheFile指向临时文件再交给 FFmpeg保证不污染源数据。六、合并完成后的弹幕挂载播放播放器组装PlayVideoActivity.kt 接收videoPath用 DKVideoPlayer。后者是一个GestureVideoController通过addControlComponent注册了标题栏、底部控制条、设置面板、手势、完成页、弹幕层等多个组件。关键设计弹幕与视频同文件名挂载。VideoDanmakuView.java 初始化时执行String localXmlPath videoPath.replace(FileUtils.getFileExtension(videoPath), xml);即把xxx.mp4替换为同目录的xxx.xml。若不存在则加载空弹幕集存在则用自定义解析器BiliDanmukuParserTools解析。本地弹幕 XML 解析器BiliDanmukuParserTools.java 继承 DanmakuFlameMaster 的BaseDanmakuParser用 SAX 解析 B 站弹幕 XML。其代码注释完整描述了d p...属性的 8 个字段含义0: 时间弹幕出现时间秒 1: 类型1 从右至左滚动 | 6 从左至右滚动 | 5 顶端固定 | 4 底端固定 | 7 高级弹幕 | 8 脚本弹幕 2: 字号 3: 颜色 4: 时间戳 5: 弹幕池 id 6: 用户 hash 7: 弹幕 id解析器还做了多处细节处理XML 实体反转义amp;→、quot;→、gt;→、lt;→、高级/脚本弹幕的 JSON 数组解析运动路径、透明度渐变、旋转、描边等、chatid节点捕获网络弹幕文件 ID。渲染前还会根据屏幕宽高计算mDispScaleX/mDispScaleY缩放系数适配不同分辨率。弹幕显示配置VideoDanmakuView.java 的initDanmakuConfig从ConfigData读取三档弹幕参数并作用于DanmakuContext字号danmakuSizesetScaleTextSize(size / 100)滑杆范围 30 ~ 250默认 100透明度danmakuAlphasetDanmakuTransparency(alpha / 100)范围 0 ~ 100默认 100速度danmakuSpeedsetScrollSpeedFactor((200 - speed) / 100)范围 1 ~ 200默认 100注意取值越大实际滚动越慢以上三项在 VideoSettingView.java 中以XSeekBar实时调节并在视图销毁onDetachedFromWindow时写回ConfigData持久化。设置面板同时提供视频重复播放开关播放完成自动pressPlayBtn()重播与屏幕锁按钮DKVideoController.java 的iv_lock锁定后拦截手势与返回键。播放页还支持跳转原视频读取导出文件元数据中的 BV 号并拼接https://www.bilibili.com/video/、分享与复制路径。七、配置体系基于 MMKV 的设置中心所有配置由 ConfigData.kt 统一管理底层存储为腾讯 MMKV首次启动init()写入默认值。核心配置项一览配置键默认值说明cacheFilePath按已安装 B 站版本自动匹配缓存根目录outputFilePath根目录/bilibili视频合并/complete合并输出根目录exportType0有声音视频导出模式exportDanmakufalse是否同时导出弹幕 xmlsingleOutputDirfalse是否单一输出目录ffmpegCmdTemplateffmpeg -i %s -i %s -metadata title%s -c copy %sffmpeg 命令模板ffmpegCoreType0RxFFmpegFFmpeg 引擎选择danmakuSize / Alpha / Speed100 / 100 / 100弹幕字号/透明度/速度openBarragetrue播放器是否默认显示弹幕updateFrequency1每周自动检查更新频率videoReplyfalse播放完成后是否自动重播此外还定义了三个固定输出目录常量complete导出成品、tempUri 模式临时文件、zip完成页压缩输出路径中的中文目录名为bilibili视频合并。SettingsActivity.kt 是这些配置的可视化入口支持缓存路径按 B 站版本国内/国际/平板/概念/自定义下拉切换或用路径选择器手动选择 download 目录输出路径路径选择器指定点击文本可复制FFmpeg 命令从预设两条模板中选择或自定义输入FFmpeg 核心RxFFmpeg / FFmpegCommand 切换需构建时打包双引擎单一输出目录开关自动更新频率每天 / 每周 / 每月 / 永不恢复默认一键还原缓存路径、输出路径、更新频率、FFmpeg 核心八、软件分发、更新与问题反馈更新机制README 给出的更新优先级依次为交流群群文件 网盘链接 GitHub/Gitee Release 软件内。软件内更新由 UpdateTools.kt 基于 XUpdate 实现主通道指向 Gitee 仓库的 jsonapi/update_release.json备用通道为 GitLink失败时自动切换备用通道自动检查频率由updateFrequency控制手动点击检查有频率限制5 分钟内最多 3 次提示为了减小服务器压力请5分钟后再试update_release.json 的字段结构可作为自建更新通道的参考{ Code: 0, UpdateStatus: 1, VersionCode: 58, VersionName: 1.6.9.8, UploadTime: 2023-09-19, ModifyContent: 1、升级权限请求依赖。2、细节优化。, DownloadUrl: ...apk, ApkSize: 17828, ApkMd5: }仓库 jsonapi 目录下还有update_custom.json、update_forced.json、update_ignore.json等变体分别对应不同更新策略场景。问题反馈模板README 要求反馈时提供类别、设备信息、描述、触发方式、视频链接五要素。其中设备信息由 MainActivity.kt 侧边栏一键复制生成Android:9 App版本:1.6.9.2beta 机型:HUAWEI/VOG-AL10 设备id:2f5e3c3905abc3dc5b757787725d28e43崩溃日志方面InitTool.kt 集成了友盟统计与腾讯 Bugly用户同意协议后才初始化用于统计与崩溃上报。九、开源许可与致谢项目采用 Apache License 2.0 开源LICENSEREADME 列出的主要依赖与致谢包括bilibili/DanmakuFlameMaster弹幕渲染、microshow/RxFFmpeg 与 AnJoiner/FFmpegCommandFFmpeg 执行、xuexiangjys/XUI 与 XUpdateUI 与更新、Tencent/MMKV键值存储、molihuan/mlhfileselectorlib路径选择器、Doikki/DKVideoPlayer视频播放器。总结BilibiliCacheVideoMerge 的完整技术链路可以概括为缓存目录扫描Path/Uri 双模式→ entry.json 元数据解析 → 合集/章节列表展示 → 导出模式与弹幕开关选择 → FFmpegRxFFmpeg/FFmpegCommand 双引擎合并或直接复制 → 输出目录管理 → 本地播放器挂载弹幕 xml 播放。其中双存储访问适配、FFmpeg 引擎抽象、命令模板化、弹幕 XML 解析等设计对开发同类缓存视频提取/格式转换类 Android 工具具有直接的可复用价值。需要注意的是项目已停止维护生产使用请评估其仅覆盖 Android 5.0 ~ 13README 标注为理论上的适用范围。赞分享移动开发音视频【免费下载链接】BilibiliCacheVideoMergeAndroid上将bilibili缓存视频合并导出为mp4支持安卓5.0 ~ 13视频挂载弹幕播放(Android consolidates and exports the bilibilibili cache video to mp4, supports Android 5.0~13, and plays the video on the screen)项目地址https://gitcode.com/gh_mirrors/bi/BilibiliCacheVideoMerge点击查看免费下载相关推荐如何快速合并B站缓存视频BilibiliCacheVideoMerge一键导出MP4完整指南如何快速合并B站缓存视频BilibiliCacheVideoMerge一键导出MP4完整指南 BilibiliCacheVideoMerge是一款专为安卓用户移动开发音视频如何快速合并B站缓存视频HLB站缓存合并工具完整指南如何快速合并B站缓存视频HLB站缓存合并工具完整指南 你是否遇到过这样的情况在B站缓存了喜欢的视频想要离线观看时却发现文件被分割成了多个片段无法直接播放移动开发音视频如何快速合并B站缓存视频HLB站缓存合并工具完整指南如何快速合并B站缓存视频HLB站缓存合并工具完整指南 HLB站缓存合并是一款专为Android用户设计的实用工具能够帮助你轻松将哔哩哔哩B站缓存的分段视移动开发音视频上一篇微信好友关系终极检测指南5分钟找出谁悄悄删除了你下一篇Mist 使用指南5 分钟下载 macOS 固件4 种安装器格式一次导出创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考