将bilibili缓存的m4s音视频文件合并(基于ffmpeg/含xml弹幕转ass/附exe程序)

您所在的位置:网站首页 缓存视频合并助手apk下载 将bilibili缓存的m4s音视频文件合并(基于ffmpeg/含xml弹幕转ass/附exe程序)

将bilibili缓存的m4s音视频文件合并(基于ffmpeg/含xml弹幕转ass/附exe程序)

2023-12-23 21:36| 来源: 网络整理| 查看: 265

将bilibili缓存的m4s音视频文件合并(基于ffmpeg/含xml弹幕转ass/附exe程序)

全水平向:萌新大佬都可食用 B站上视频资源很多,无论你是看番还是学习,它都能很大程度上满足你。可如果想下载B站上的视频方便随时观看 或是为了防止b站上的视频被删而保存到自己的设备上,又该如何操作呢? 首先下载b站上的视频官方的途径只有手机端的缓存(直接点app视频播放页面下的缓存按钮,或点击右上角“…”调出菜单再从里面点缓存)。我也比较推荐直接在手机端缓存后再复制到电脑或别的地方,毕竟官方渠道,稳定且下载速度快,操作简单。

###更新版本v1.8### 1.主程序和程序设置GUI; 2.支持xml2.0格式弹幕转换,支持自动下载封面和cc字幕; 3.通用模式(合并任意音视频文件)和兼容模式 4.现有预设加上搜索模式创建向导,软件理论上可以合并所有B站客户端的缓存视频 #################

[下面是旧版本的回答。新版本功能更加丰富,但由于代码量太大的原因不便于展示,具体的源代码可以联系软件里附的qq获取] 那么现在切入主题…(最新程序安装包的下载链接请往下翻) 现在(2020年)直接从b站缓存的视频都是video.m4s+audio.m4s音视频分开的形式,同时缓存的弹幕文件也是xml格式(仅部分视频软件可以读取显示),于是我的想法就是利用现在性能最好的通用音视频编码器ffmpeg实现快速合并,弹幕格式转换就用GitHub上一大佬@m13253 之前发布的的danmaku2ass源码。 xml转ass的python源码danmaku2ass.py:danmaku2ass.py

网上关于利用ffmpeg合并视频的方法都要求使用者电脑安装了ffmpeg,直接利用cmd输入指令。这样既不便于新人操作也不便于移植,这里我直接把安装的ffmpeg复制出来,删掉一些用不上的组件后内嵌到软件里; 大小只有186MB,而且可移植,让合并软件在未安装ffmpeg的电脑上也能正常运行:ffmpeg文件夹

然后用python(我用的是较新的版本python3.8.1,v3以上都可)写主程序代码,实现对内嵌ffmpeg和danmaku2ass文件的调用,主程序代码如下: 1.程序只使用os,json,time 3个模组

import os import json import time

2.获取文件路径,检测danmaku2ass文件

if __name__ == '__main__': path = "..\\" save_path = "..\\bili_merge" # 与用户交互获取对象路径 print("---自动扫描 程序文件夹 所在目录下的可合并文件(输入‘1’)\n---手动输入 需扫描文件夹 的路径(输入‘2’)\n---退出程序(输入除1,2外的任何字符):") a = input("---") if a == '1':pass elif a == '2': path = input("请在这里输入 缓存视频所在文件夹 的路径:").replace("/","\\\\") save_path = f"{path}\\bili_merge" else:os._exit(0) source1_path = os.path.abspath("./ffmpeg/tools/ffmpeg/bin/ffmpeg.exe") source2_path = "./danmaku2ass.py" # 检测danmaku2ass.py文件是否在指定路径 try: import danmaku2ass switch = 1 print("danmaku2ass.py文件检测成功,自动开启弹幕转换","\n") except ModuleNotFoundError: print("未检测到弹幕转换资源文件!","\n") switch = 0

3.利用os.walk()函数获取所以文件的路径

# 所有目录名和需要转换的文件名 all_title = [] all_video = [] all_audio = [] all_danma = [] # a:所在根目录,b:根目录下所有文件夹(列表形式),c:根目录下所有文件(列表形式) for k, (a, b, c) in enumerate(os.walk(path)): # 因为os.walk()是树检索,所以3类文件会一一对应 for i in c: if i == 'entry.json': title_path = os.path.join(a, i) all_title.append(title_path) elif i == "video.m4s": video_path = os.path.join(a, i) all_video.append(video_path) elif i == "audio.m4s": audio_path = os.path.join(a, i) all_audio.append(audio_path) elif i == "danmaku.xml": danma_path = os.path.join(a, i) all_danma.append(danma_path)

4.显示提示信息,创建bili_merge文件夹,准备开始转码

num = len(all_title) if num == 0: print("未找到可合并文件,请检查路径或文件格式。") time.sleep(30) os._exit(0) os.makedirs(f"{save_path}", exist_ok=True) print("共检测到 %s 个待合并文件\n合并进程已开始,请耐心等待~~~"%num,"\n")

5.按照之前获取的文件路径循环。读取entry文件对文件进行命名和分组;os.system()调用shell脚本带参执行内嵌的ffmpeg.exe进行音视频合并;调用danmaku2ass.Danmaku2ASS()函数进行xml转ass(这里的参数我已经调试过,如有其他需求可以自行修改)

failed = 0 tabel = str.maketrans("","",'''\/:*?"| ''') # 一个个打开对应路径文件 for i, j in enumerate(all_title): #解析entry.json文件 with open(j, encoding='utf-8') as data: title_ = json.load(data) # 目录名 title1 = title_["title"].translate(tabel) # 视频名 try: title2 = title_.get("ep","N/A") if title2 == "N/A":title2 = title_["page_data"]["part"].translate(tabel) else: try: index = int(title2['index']) title2 = f"EP{index}_"+title2["index_title"].translate(tabel) except ValueError: title2 = title2['index'] except KeyError: title2 = title1 print(f"输出目录:{title1}") print(f"输出文件:{title2}.mp4......") _path = f"{save_path}\\{title1}" os.makedirs(_path, exist_ok=True) cmd1 = f'{source1_path} -i {all_video[i]} -i {all_audio[i]} -c copy \"{_path}/{title2}.mp4' # python调用Shell脚本执行cmd命令 os.system(cmd1) # 调用danmaku2ass内建函数将xml弹幕文件转换成ass格式(弹幕参数在这里调) if switch==1: os.makedirs(f"{_path}/danmuAss", exist_ok=True) danmaku2ass.Danmaku2ASS(f"{all_danma[i]}","Bilibili",f"{_path}/danmuAss/{title2}.ass",1080,720,\ reserve_blank=480,font_size=23.0, text_opacity=0.6, duration_marquee=12.0, duration_still=6.0) #备用代码1#cmd2 = f'python {source2_path} {all_danma[i]} -o {_path}/danmuAss/{title2}.ass -s 1080x720 -a 0.5 -fs 22 -dm 12 -ds 6 -p 480' #备用代码2#os.popen(cmd2) #检测视频文件是否成功合并并输出 if f"{title2}.mp4" in os.listdir(_path): print("*" * 15, f"已完成{i+1-failed}个文件", "*" * 15,"\n") else: print("*" * 15, "合并失败或终止", "*" * 15,"\n") failed += 1

6.打印完成提示,并于30s后自动关闭窗口

print("当前任务已完成!") time.sleep(30) os._exit(0)

代码在Windows和Unix运行没有问题,其他操作系统目前还不清楚,水平高的可以针对其他系统自己改写

将程序打包成exe,没有运行环境要求 打包用的pyinstaller,很方便(利用windows powershell下的chocolatey安装,具体使用方法自行百度)

下面是我打包好可以直接使用的软件: ★★★阿里云盘下载链接★★★

▪操作图示(我是直接把程序文件夹与视频缓存文件夹放在一个目录下,这样程序会自动添加待合并视频; 你也可以选择手动输入扫描路径): 使用图示1 使用图示2 使用图示3

▪软件展示(还没有添加用户图形页面,所以软件运行页面就是一个shell: 软件示意图 运行示意图1:选择扫描模式或退出 运行示意图2:转码完成 第一次打包程序发文章,如果上面有错误或者程序不能正常运行请及时通过软件说明里的qq联系我或直接在这里留言。另外软件我也会定期更新,敬请关注。

更新于2022/3/17



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3