Open HFrost0 opened 1 year ago
你好,抽离出这个功能是可行的,为了兼容更多弹幕格式,设计初就有中间 data 一层抽象,以下是一个简单例子,可以按需取其中的一部分或者打成个动态库,理论上并没有什么耦合。
#include "Define/DanmakuDef.h"
#include "Config/Config.h"
#include "CDanmakuFactory.h"
#include "AssFile/AssFile.h"
#include "List/DanmakuFactoryList.h"
int main()
{
DANMAKU *danmakuPoorHead = NULL; // 弹幕池的头指针
CONFIG config = { ... } // 配置项参照 Config/Config.h 定义
/* 读 xml */
readXml("test.xml", // 要读取的xml文件名
&danmakuPoorHead, // 弹幕池头指针的指针,需要把指针的指针传进去(好蠢,不知道为啥要这样做,这玩意儿会在执行的时候被改指向,不能通过赋值来拷贝
"n", // 读取方式,"n"清空之前弹幕池的内容并新建 "a"在之前弹幕池的基础上追加
0.00, // 时轴偏移量
NULL // 处理状态 用于多线程获取进度 可以不传
);
/* 排序弹幕池 */
sortList(&danmakuPoorHead, // 弹幕池头指针的指针
NULL // 处理状态 用于多线程获取进度 可以不传
);
/* 写 ass */
writeAss("test.ass", // 输出文件名
danmakuPoorHead, // 弹幕池头指针,注意这里却是一维指针
config, // 配置
NULL, // 字幕 空表示不插入(年代久远,这个好像只是预留但没有做)
NULL // 处理状态 用于多线程获取进度 可以不传
);
return 0;
}
关于你刚才说的python转换太慢的问题,可以细说一下是有多慢,慢的地方在哪里吗~ 因为这个项目写的太拉太难维护了,正在用python做重构,全部的业务逻辑都做插件化,开发者可以只实现其关心的任意一小部分。现本体已经写好在做插件了,因此比较关心性能问题qwq
当弹幕数量较少时看不出来,但是现在b站的电影和电视剧弹幕由于时间长数量大所以转换时间成本高,在我的转换器项目README中有做测试,大概50秒左右才能完成,而c++只需要0.2秒左右。
看您的定义似乎没有一条条添加弹幕的接口,在原本我重构的项目中,性能瓶颈主要在于向ass对象添加新的弹幕上
def add_comment(self, progress: float, ctime: int, content: str, font_size: float, mode: int, color: int) -> bool:
"""add a comment to Ass object, return True if add success"""
有这个接口,我们甚至可以混合多个网站的弹幕,而不是转换某个特定网站的xml文件
了解了~没有定义这个接口,其实可以简单实现一下,弹幕池是一个单向链表,往链表后面补一条就可以达到追加的效果了。
好的,根据您的提示我刚刚粗略看了readXml这个函数,似乎是针对bilibili xml的处理函数,可以把xml中的数据读入链表中。但似乎和b站耦合了,我非常希望抽象出之前我提到的Ass
类,Ass
类是和平台无关的一个类,上游任务主要是把数据简单处理为Ass.add_comment
接受的格式,例如提供时间戳,内容字符串等,这个上游任务是平台相关的,甚至随时受到接口变动影响的,所以交给灵活的胶水语言来做,而c模块做为底层加快转换速度。
您关心的性能瓶颈位置,py执行循环的速度,字符串format的速度都远低于c,所以核心部分非常需要c的介入
不知道这样的思路是否可行,在niconico弹幕和bilibili弹幕上我做了这样的尝试
问题在于我虽然重构了之前其他大佬写的库,但是我本人对其中的逻辑实在是欠缺了解,所以很难维护好它,不知道大佬是否有兴趣提供这类接口,或者为danmakuC提供一些代码完善它,成为它的核心维护者🥹
是的,readXml()
是针对 bilibili 的处理函数,但是sortList()
和writeAss()
是平台无关的,把readXml()
换成一个往链表里面 push back 的函数大概就可以实现你想要的功能~
链表的node结构如下,是很通用的属性:
// file: Define/DanmakuDef.h
struct SingleDanmaku
{/* 弹幕节点定义 */
float time; /* 开始时间 */
short type; /* 弹幕类型 */
short fontSize; /* 字体大小 */
int color; /* 文字颜色 */
char *text; /* 文本内容 */
struct UserPart *user; /* 用户信息 */
struct GiftPart *gift; /* 礼物属性 */
struct SpecialDanmakuPart *special; /* 特殊弹幕的额外属性 */
struct SingleDanmaku *next;
};
论性能,这玩意儿绝对快,最接地气的字符数组,链表操作,几乎没有多余拷贝😂 尽管如此,也正因为如此,我不太建议抽出来直接简单封装,因为目前这部分代码已经很难维护了~ 我现在正在用python写一个ass的包,目标是能轻松用ass画出简单图形或者动画,以及实现一个ass parser,与弹幕处理无关,但是能方便之后的开发。我现在纠结是不是应该用C++来做这个事情~ 我看了一下大佬项目的实现,目前的处理是有什么问题嘛~
我做下载工具的时候碰上过python转换弹幕文件太慢的问题,所以自己重写一个C++版本的转换器,但是因为我个人对弹幕和ass格式的了解不够所以很多功能还不完善。今天才看到大大的项目,想请教下:
由于弹幕网站提供的弹幕接口不一样,例如b站就由过去的xml格式变成了现在的protobuf,能否有一个小的c模块来实现核心的转换功能,例如下面的伪代码:
而解析proto,xml的工作交给py这类语言,因为可以更快适应网站的变化,适配更多网站。画一个简单的图来说就是:
我对c和c++包括ass都不够熟悉,所以想问问作者大大抽离出这个功能可行吗