tiansh / us-danmaku

Firefox 扩展版本见 https://github.com/tiansh/ass-danmaku ;在线转换见 https://tiansh.github.io/ass-danmaku-online/ ;【用户脚本已停止维护】用户脚本 以ass格式下载 AcFun 和 bilibili 的弹幕
210 stars 48 forks source link

有没有办法独立出可程序调用的转换功能 #17

Closed otakustay closed 7 years ago

otakustay commented 7 years ago

有不少老番手上有弹幕文件但是全部从网页上传转换心好累……现在的程序有没有可能有一个模块支持“输入字符串输出ass的内容”,方便clone后直接用node调用

tiansh commented 7 years ago

目前出运行于 Node 平台的程序的可能性不大,因为脚本中需要“度量文字的宽度”以方便排版。而这个操作是通过 canvas 或隐藏的 DOM 节点(取决于浏览器支持情况)实现的。

如果你能提供实现这个功能的,可以运行于 NodeJS 的方法,我可以考虑制作支持 NodeJS 的转换工具。

otakustay commented 7 years ago

多谢提供情报,以前有使用过node-canvas在node端绘制图表,我去研究一下具体的使用确定是否可用于实现“度量文字宽度”,有了结论再来回复这个issue

Gray Zhang

在 2016年9月17日 at 下午11:05:54, 田生 (notifications@github.com) 写到:

目前出运行于 Node 平台的程序的可能性不大,因为脚本中需要“度量文字的宽度”以方便排版。而这个操作是通过 canvas 或隐藏的 DOM 节点(取决于浏览器支持情况)实现的。

如果你能提供实现这个功能的,可以运行于 NodeJS 的方法,我可以考虑制作支持 NodeJS 的转换工具。

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tiansh/us-danmaku/issues/17#issuecomment-247779524, or mute the thread https://github.com/notifications/unsubscribe-auth/AAnCPQBvOa6Dcg7akVxmQl6vJmzHNAAQks5qrAHSgaJpZM4J_nVk .

otakustay commented 7 years ago

我实际测试了一下,node-canvas的measureText对中文是无效的,所以估计确实做不了,要不要考虑下phantomjs的可行性?如果不方便的话还请Close掉吧

tiansh commented 7 years ago

话说,XULRunner现在还活着吗……

otakustay commented 7 years ago

翻mozilla的mailing list看似乎已经是死掉了,也找不到新的和这货的状态相关的情报……

otakustay commented 7 years ago

研究了一段时间,用phantom可以拿字符的宽度,具体脚本大致如下:

let measureText = async character => {
    let phantom = await require('phantom').create();
    let page = await phantom.createPage();
    page.setContent(
        `<!DOCTYPE html><canvas id="test"></canvas><span id="character">${character}</span>`,
        'http://about.blank'
    );
    let measureByCanvas = () => {
        let canvas = document.getElementById('test');
        let context = canvas.getContext('2d');
        context.font = '25px 黑体';
        let character = document.getElementById('character').innerText;
        return context.measureText(character);
    };
    let measure = await page.evaluate(measureByCanvas);
    await phantom.exit();
    return measure;
};

measureText('我').then(measure => console.log(measure));

babel-node --presets=es2015,stage-0 xxx.js可以跑出来宽度,和在Chrome中的基本一致

不过这个方法非常慢,所以如果可以有个脚本只用一次获取字符宽度,然后批量转一大堆文件会更好些……

otakustay commented 7 years ago

根据和node-canvas的沟通,使用node-canvas现在也已经成功能够获取字符的宽度(至少在macOS上),速度比phantom要快很多:https://github.com/Automattic/node-canvas/issues/818#issuecomment-251957646

逻辑比较简单:

let Canvas = require('Canvas');
let canvas = new Canvas();
let context = canvas.getContext('2d');
context.font = '48px Hiragino Sans GB';
console.log(context.font);
let measure = context.measureText('首');
console.log(measure);

如果可以基于此搞出命令行版,或者大致告诉我其他的逻辑部分是怎么样的来让我尝试下实现就好了

tiansh commented 7 years ago

可以参考一下网页上转换的那个是怎么调用的,把读写文件和canvas换掉应该就可以。改起来应该不难。不过最近没空管它……

otakustay commented 7 years ago

简单参考了一下代的代码,自己实现了一份,不过弹幕防冲撞布局这一块你的实现压缩了各种变量名我有点看不懂,所以自己搞了一套比较暴力的,没办法PR给你了…… https://github.com/otakustay/danmaku-to-ass

多谢指导~

tiansh commented 7 years ago

那段计算排版的其实并没有压缩,变量名可以参考那一大段注释。比较不太容易说清楚,所以就成这样了……