muzuiget / niconvert

弹幕转换工具
252 stars 33 forks source link

请问有什么办法可以避免异步滚动字幕重叠吗 #28

Closed snowingwang closed 4 years ago

snowingwang commented 4 years ago

异步模式下有一定概率弹幕会重叠,有办法算出前一个弹幕和当前弹幕显示时长的差吗? 因为B站现在的弹幕是字数越长显示时间越短的,所以可能需要算出具体的显示时间差才能防止滚动弹幕重叠?

tiansh commented 4 years ago

那个得已知渲染使用的字体,视频纵宽比的情况下,用字体先把文本宽度量出来。

B 站大概八年前的逻辑是滚动弹幕弹幕开始进入屏幕到完全退出的时间长度一致。弹幕的速度=(屏幕宽度+弹幕文字宽度)/弹幕显示时长。现在有没有改我就不知道了。

muzuiget commented 4 years ago

用 ass 几乎做不到的,这得考虑所有情况,分辨率、字体大小、长度等等模拟一次然后生成静态信息,还别说每个播放器的 ass 渲染效果的都不一致。

实际上用 HTML 自建弹幕渲染器久简单多了,每隔毫秒做下碰撞检测,然后偏移或者减速就完事了。

snowingwang commented 4 years ago

用 ass 几乎做不到的,这得考虑所有情况,分辨率、字体大小、长度等等模拟一次然后生成静态信息,还别说每个播放器的 ass 渲染效果的都不一致。

实际上用 HTML 自建弹幕渲染器久简单多了,每隔毫秒做下碰撞检测,然后偏移或者减速就完事了。

感谢回复,请问单纯让collision.py中的beyond>=两条弹幕持续时间的差可以吗?

比如A弹幕持续时间10秒,离开时间0.1秒,弹幕B持续时间9秒。 此时按照原本niconvert的算法,0.1秒后弹幕B就可以开始滑出了,如果能使B弹幕在1.1秒后滑出是否能避免两条弹幕重叠?

假设一个文件中任意两条弹幕持续时间的差最大为3秒,理论上在leave的基础上加上3就能使所有弹幕在运动的过程中不重叠了。但是这样粗暴的做法又会导致等待时间过长,进而使得被舍弃的弹幕过多。后来也试过利用一个公式来往leave后面加一个大于0的值,这个值和弹幕本身的长度呈反比,但是这样使得大量短弹幕渲染时中间的间隔太长。

所以想着既然能算出某行空余的空间,应该能算出持续时间的差?

播放器应该用了不同的滤镜来渲染ass,如果能保证使用libass来渲染应该出来的效果就是一致的。

snowingwang commented 4 years ago

那个得已知渲染使用的字体,视频纵宽比的情况下,用字体先把文本宽度量出来。

B 站大概八年前的逻辑是滚动弹幕弹幕开始进入屏幕到完全退出的时间长度一致。弹幕的速度=(屏幕宽度+弹幕文字宽度)/弹幕显示时长。现在有没有改我就不知道了。

唔,文本宽度和视频长宽比应该脚本里已经考虑到了,其他讨论参见如上。感谢回复。

muzuiget commented 4 years ago

本来已经考虑到了,用“同步”算法基本能做到不重叠,“异步”算法比较麻烦,但是怎么还是会有些边界条件造成重叠,比如字号大小,弹幕里带有换行符、颜文字之类的,所以我这就算了,不纠结了。