高级弹幕教程1.1——S-Haya

高级弹幕教程1.1——S-Haya

bas弹幕使用教程

开始前的亿些说明

什么是bas弹幕?

Bas弹幕全称bilibili animation script,也可称作m9或mode9,是新一代的bilibili 高级弹幕系统

难度如何?

bas弹幕虽然主要使用代码编写,但并不需要编程基础。只要愿意花时间去研究难度不会太大

代码排版格式方面的注意事项?

官方的文档(下面有)是一个很好的参考,最终如何编写还是看个人习惯,不过把代码给别人看时最好注意下注释和美观和可读性(

2

高级弹幕系统间的区别?

·  “高级弹幕”是一个比较广泛的统称,主要指以下三种:

mode7-高级弹幕:在视频中看到的”高级弹幕”基本属于m7,在弹幕列表中显示为特殊弹幕。点击弹幕列表旁边的按钮即可进入编辑页面,支付2硬币并获取up授权后可拥有在该视频使用权限。功能相对简单,支持移动端,由于播放器改版bug严重

(av297197美丽之物,此为录屏版)

mode8-代码弹幕:基于flash播放器,功能极为强大的弹幕系统,可以实现复杂动画,特效,甚至制作弹幕游戏,支持插入矢量图。数年前常见的op转跳便由代码弹幕实现。但在16年左右因安全问题被禁止发送(有傻逼尝试用代码炸播放器)。仅支持PC端flash播放器

(av2775802 世界终结舞厅)

mode9-bas弹幕:基于html5播放器,算是m8的替代品,功能相对较弱但仍远强于m7,也可以制作复杂动画,支持矢量图,互动方面较为简易。无字幕君权限只能在自己的视频里发送,仅支持PC端 html5播放器。bas弹幕在浏览器适配上有点问题,接下来的教程均以Chrome为准

(av796642408 p2 カワキヲアメク)

一.最基本的工具/软件

  1.       bas弹幕的官方文档,https://bilibili.github.io/bas/#/guide(无法加载可以使用本地版)。详细代码介绍与实验室都在这里,并且有大量实例,务必配合使用。
  2.       一个文本编辑器,如notepad++,笔记本也问题不大
  3.       Chrome浏览器,不保证bas在所有浏览器上效果相同,以Chrome为准
  4.       一个自己的弹幕测试视频,视频页编辑器比实验室完善,编写测试更方便

二.¨C11C实验室与视频页编辑器

b站官方实验室
  1. 实验室,位于官方文档右上方,功能简陋,不显示错误信息,个人不推荐使用
  1. 视频页编辑器,在自己的视频中点击弹幕列表旁按钮,选择bas弹幕,点击代码模式打开代码编辑器(普通编辑器基本是m7+,就不介绍了)
  1. 视频/弹幕显示区
  2. 帮助,点击转跳至官方文档
  3. 清屏,清空屏幕(点击进度条会重载常驻弹幕和已发送弹幕)
  4. 测试弹幕,测试当前分页的代码
  5. ¨C12C测试弹幕常驻,启用后测试效果更接近实际发送效果,但测试的弹幕只能通过刷新页面清除,容易导致卡顿
  6. 以当前时间作为弹幕出现时间
  7. 弹幕出现时间,单位为ms,启用测试弹幕常驻后才能在弹幕测试中生效
  8. 分页,每个分页可编写不同弹幕代码,由于bug切换分p时可能会吞弹幕
  9. 颜色拾取,可选取颜色
  10. 坐标拾取,可在视频界面中显示网格,点击获取坐标
  11. 发送弹幕,单条上限512k,发送后仍可修改,以发送顺序叠加(大概)
  12. 代码编辑区,有代码补全功能(比较玄学)

2021.4.24补充

目前单条上限只有10kb,不知道什么时候修。。。

三.text-文本弹幕

  1. “定义”一条弹幕

Bas弹幕的格式为:

def text/path/button 名称{属性}

def用于定义一条新弹幕,注意这与弹幕列表中的”一条弹幕”不同,”一条”bas弹幕可包含多个def

text即为文本,path与button会在后面介绍

弹幕名称只能含有字母和数字且必须以字母开头,弹幕名称重复只执行最后一个,区分大小写

各种符号均为英文字符

在任意字符前添加”\”可使后续同行文字变成注释

属性格式为{xxx=x xxx=x xxx=x},属性重复只执行最后一个

属性包含了弹幕的内容和样式,下表为官方文档中文本类型弹幕所有可用属性,官方文档有大量代码实例可以测试

属性名值类型必要默认值可变渐变补充说明 >(属性名注意大小写)
xnumber0x 坐标,可以为百分比值
ynumber0y 坐标,可以为百分比值
zIndexnumber0层次权重,值高的对象在上层
scalenumber1缩放
durationtime元素生命周期,有动画时默认为动画总时间,无动画时默认4s
contentstring‘请输入内容’文本内容
alphanumber1透明度,取值范围 [0, 1],0 完全透明, 1 完全不透明
colornumber0xffffff文本颜色
anchorXnumber0锚点,位置为长度的百分比
anchorYnumber0锚点,位置为宽度的百分比
fontSizenumber25文本字体大小,可以为百分比,百分比字体大小为当前屏幕宽度字体百分比px(务必在文本弹幕中写入该属性并设为百分比,否则弹幕会受播放器分辨率影响,导致全屏错位)
fontFamilystring文本字体,默认值为平台默认字体。字体不存在时,使用浏览器默认字体(所以不要乱用字体,别人大概率无法显示)
boldnumber1加粗
textShadownumber1字体阴影
strokeWidthnumber0描边宽度
strokeColornumber0xffffff描边颜色
rotateXnumber0X轴旋转
rotateYnumber0Y轴旋转
rotateZnumber0Z轴旋转
parenttext所属层
  1. 文本内容-content

   {

content=“文本”

}

不能含有”\”字符,但可用”\n”进行换行,不支持enter换行

¨C13C {

content=”a\naa\naaa\naaaa”

}

  1. 坐标-x,y

{

x=a/a%

y=b/b%

}

a,b可为负数,以视频左上角为坐标轴原点,坐标轴受视频比例影响。强烈建议使用百分比值

  1. 锚点-anchorX/Y

 {

anchorX=a

anchorY=b

}

锚点是xy坐标的定位点,适当调整锚点可以减少弹幕定位难度。同时弹幕旋转,缩放等功能也以锚点为中心

bas实际范围是一个矩形¨C14C,通常比可见字符大一圈,(0,0)时锚点位于矩形左上角,(0.5,0.5)位于矩形中心,(1,0)时位于矩形右上角,以此类推。a,b可为任意值

(0,0)

(1,0)紫色

(-1,0)绿色

(0,1)蓝色

(0,-1)青色

xy坐标均相同

  1. 缩放-scale

{

scale=a

}

以锚点为中心对整条弹幕进行缩放,a为负数时弹幕以锚点为中心翻转,为0时弹幕消失

scale值过大会导致弹幕模糊,对于文本类型弹幕如果不需要动画渐变效果建议使用fontSize而不是scale

¨C15C {

scale=1/-1/0.5/-0.5

}

对应颜色(紫色/红色/灰色/绿色)

  1. 旋转-rotateX/Y/Z

{

rotateX

rotateY

rotateZ

}

¨C16C以锚点为中心绕X/Y/Z轴旋转对应角度。

(α,β,γ)

(60,0,0)红色

(0,60,0)紫色

(0,0,60)灰色

(30,45,20)绿色

特性:

rx和ry透视效果受xy坐标和弹幕大小影响

弹幕作为子级时rx,ry透视效果消失(parent部分说明)

  1. 字体大小-fontSize

{

fontSize=a/a%

}

效果与scale类似,但fontSize不可渐变,a可为负数,使用百分比时固定弹幕与播放器的比例,可以避免因分辨率造成的错位,非常重要

  1. 生命周期-duration

 {

duration=xhxmxs/xxs/xxms

}

用于规定弹幕的生存时间,单位可以为h/m/s/ms。除duration外也有其他方法可以调整弹幕生存时间,将在动画部分介绍

  1. 字体-fontFamily

 {

fontFamily=“字体名称”

}

指定文本字体,可输入中文名称,若没有安装指定字体将显示默认字体

  1. 层次-zIndex

 {

zIndex=a

}

设置弹幕的层级,默认为0,可为负数,层级高的弹幕会覆盖层级低的弹幕,层级相同按照在代码文本中的”def”顺序,先”def”的弹幕会被后”def”的弹幕覆盖,仅在”同一条”弹幕内生效

¨C17C {

zIndex=0/1(红色/绿色)

}

  1. 其他文本效果

颜色-color 格式为 color=0x 后接16进制颜色值

粗体-bold 格式为 bold=0/1 ,0为关闭,1为启用,默认启用

描边宽度-strokeWidth为0时不显示描边

描边颜色-strokeColor 格式与color相同,默认为0xffffff白色

字体阴影-textShadow 格式与bold相同,默认启用,需要纯色弹幕可设为0

  1. 所属层-parent

主要用于动画,稍后说明

四.简单弹幕动画

对弹幕属性进行变动可做出丰富的动画效果,这时需要用到set语句

  1. 基本格式

set 名称{

}动画时间

set可以改变弹幕的属性,制作渐变动画

def text a{

content=”AAA”

x=20%

y=20%

fontSize=8%

}set a{

alpha=0.5

x=40%

color=0xaa0000

fontSize=12%

}2s

以上代码使用2s将弹幕透明度变为0.5,x坐标变为40%,颜色变为aa0000,字体大小变为12%。

注意如fontSize,content等属性是不可渐变的,这些属性的变化会在瞬间完成(与0s动画时间效果相同),anchorX/Y,fontFamily,zIndex等属性完全不可变

set语句不必须紧跟原弹幕,可以放在原弹幕下方的任意位置

  1. 并联动画

set a{…}2s

set a{…}1s

set a{…}3s

连续出现的set语句可以并联多个动画,每个语句的动画时间可以独立设置。但x y rotateX rotateY rotateZ scale会被视为相同属性,只能任取其一

  1. 串联动画

}

set a{…}1s

then set a{…}1s

then set a{…}1s

set语句可以被then连接,依次进行动画,与并联动画相比没有属性限制,但想实现类似并联的效果需要准确计算动画时间和属性值,较为麻烦

与set不同,then set必须紧跟上一个set语句

  1. 动画时间与duration

duration属性优先度高于动画时间,到达duration所定时间弹幕会直接消失,无论弹幕动画是否结束。若动画在duration所定时间前结束,弹幕保持不变直至指定时间。

不写入duration属性时系统会取默认值4s,并降低优先度,弹幕生存时间由动画时间决定

  1. 维持弹幕

set语句后的大括号可以为空

利用这个特性可以更灵活地制作动画或设定生存时间,如

set a{}10sthen set a{}10s

效果为保持弹幕十秒不变,没有后续set语句弹幕消失

  1. 隐藏弹幕

Bas没有规定弹幕出现时间的属性,但可以使用set{}和alpha=0隐藏弹幕,如

def text a{

alpha=0

}set a{}10s

then set a{

alpha=1

}0s then set a{}10s

以上代码使弹幕保持透明10s后再出现,并维持10s

五.path-图形弹幕

def path a{

d=“”

}

path类型弹幕可以发送svg格式的矢量图,可用属性列表如下

属性名值类型必要默认值可变渐变说明
xnumber0x 坐标,可以为百分比值
ynumber0y 坐标,可以为百分比值
zIndexnumber0层次权重,值高的对象在上层
scalenumber1缩放
durationtime元素生命周期,有动画时默认为动画总时间,无动画时默认4s
dstring“”svg 路径
borderWidthnumber0描边宽度
borderColornumber0描边颜色
borderAlphanumber1描边透明度
fillColornumber0xffffff填充颜色
fillAlphanumber1填充透明度
viewBoxstringsvg 画布大小,默认完整显示
widthnumber宽度,可以为百分比值,需要设置 viewBox 才可生效
heightnumber高度,可以为百分比值,需要设置 viewBox 才可生效
parenttext所属层
  1. 获取svg

path弹幕格式为svg,普通图片需经转换才能使用,这个过程通常会对图片造成很大的损伤

放两个转换网站↓

pngtosvg.com 功能简单,免费,颜色识别精度低,适用于转换一些比较简单的图形

¨C18Cwww.vectorizer.io 功能强大,半免费(每小时有操作上限,图片上传限制1m)下方补充,精度非常高,但也导致图片体积巨大,适当调整设置可以在保证质量的同时缩小体积。

(pid 79936421)转换后大小1.3m,远超单条弹幕上限,只能分为多条弹幕发送,且容易造成卡顿

若需要特殊图形(如齿轮,曲线,多边形)或字体,path可以降低弹幕编写难度,请勿滥用path,bas是弹幕,不是图片发送器

看查或手动绘制svg可以使用Inkscape

  1. 属性差异

x, y, zIndex, duration没有变动

描边替换为borderWidth, borderColor, borderAlpha

color替换为fillColor, alpha换为fillAlpha,且不可变

scale可用但不可变

大部分文本弹幕属性在path弹幕不可用

  1. Svg路径-d

用文本编辑器打开svg文件,下图中d=” “便是svg路径,决定了svg的图形,可作为属性写入弹幕。简单图形的路径长度一般只有几k或更少,一些复杂图形路径长度可达数百k,使用path时注意不要超过512k的弹幕大小限制

fill对应当前路径的颜色,颜色值可以直接使用

每条路径只对应一种颜色,一种颜色能有多条路径,多色svg的路径数一般较多

  1. 画布大小-viewBox

viewBox=x1 y1 x2 y2

viewBox决定svg的画布大小和偏移,设置viewBox后只有画布范围内的图形会被显示,画布的左上角也是path弹幕的锚点

x1 y1对应x,y轴偏移量;x2,y2对应画布宽高。Svg文件中一般带有viewBox值,可以直接使用

viewBox也可用于分割svg

  1. 弹幕宽高-width/height

作用类似text中的fontSize,设置viewBox后生效。为百分比时固定画布与弹幕显示区的比例,一般使用其一足够,可以避免全屏错位

  1. 弹幕叠加

Svg文件中可能有多条路径,保证xy,viewBox,width等属性相同即可正常叠加

  1. 附赠-Inkscape的一些功能

由于技术力不足+懒,这只是一些比较实用的功能,详细教程建议百度

查看viewBox

svg自带的viewBox会以一个黑框的形式显示

合并路径

用vectorizer转换的svg虽然按颜色区分了图层,但路径基本是分割过的。可以用“路径”选项中的“合并”将同色路径并为一条

优化格式

可以优化svg文件的代码结构,将文件另存为一次即可

文字转svg

左侧工具栏中有输入文字的选项,并且可以转化成路径。使用“分离”可以拆分路径(需要断开连接),用“互斥”能在其他图形上扣洞

临摹位图轮廓

Inkscape可以将图片以各种形式转换成svg,但不建议把精度调太高,体积会非常巨大 (原图↓)

2021.4.24补充

vectorizer网站改版了,撤掉了操作数限制,但免费下载次数被彻底限制(10欧100次),有条件可以支持网站(毕竟确实好用),也可以f12

把蓝色部分整体复制到一个txt里,后缀改svg,丢inkscape里重写格式

简单图形推荐自己画,难度不高

Inkscape的群组问题,文字转换成路径后会是一个群组,虽然群组在当前选择的图层,但其中的路径实际上被转移到了一个子图层,导致无法直接与其他路径进行互斥,并集等操作。双击群组进入路径所在图层,才可选择路径本体进行操作,双击空白处回到初始图层。为了方便可以把路径转移到需要的图层。另外建议使用“并集”而不是“合并”,合并也会造成上述问题

¨C23C¨C24C

合并vectorizer转换的路径时,节点量往往非常巨大,并集会重新计算节点位置,产生大量小数点导致路径长度激增,这时候还是建议使用合并,需要编辑可以先用图层功能将各色路径重新分层

推荐一个软件,svgo-gui,可以压缩路径大小,但会干掉inkscape加入的数据(如新加入的图层,注释),而且会直接覆盖源文件,注意备份

六.弹幕模板

制作大量弹幕时可以简化代码

  1. let

def text a{…}

let b=a{…}

弹幕b将继承弹幕a的属性,可以在大括号中添加或修改属性

  1. 模板

除了直接使用弹幕,也可以定义模板,如:

def text a(content=a alpha=1 color=0x000000 x=20%){

content=content

color=color

x=x

alpha=alpha

fontSize=5%

}

let b=a(ccc ,0.5,0xaaaaaa,30%)

其他格式在官方文档里有说明

  1. 匿名实例

可以用于set语句简化代码

def text a{

content=aaa

fontSize=5%

}

set (a{content=bbb fontSize=8%}){

x=50%

alpha=0.5

}1s

set (a{content=ccc fontSize=3%}){

y=50%

scale=2

}1s

(似乎做不了串联动画?

七.复杂弹幕动画

其实并不算复杂,主要包含了官方文档中没提到或介绍不详细的功能和特性

  1. parent-所属层

def text a{…}

def text b{

parent=a

}

使弹幕b以弹幕a为父级进行绘制,弹幕a的缩放,旋转,透明度都会影响到弹幕b,大大降低整体动画的制作难度。parent可以多层嵌套,子级和父级可以同时设定不同动画

父级属性会影响所有子级,属性也能多层叠加(如父级alpha为0.5,子级为0.3,那么子级实际透明度为0.50.3=0.15),但如color等针对文本的属性对子级无影响

1-1.  隐藏父级

使用文本类型弹幕作父级,在content输入空格可以隐藏父级同时正常对子级进行变换

1-2.  path动画

path类型弹幕的大部分属性不可变,但可以将其作为文本弹幕的子级,这样就能通过调整父级做出缩放,透明度,旋转等属性的渐变效果。

1-3.  子级旋转

一个可能的bug,弹幕作为子级使用rX和rY时会失去旋转透视,可以用于压缩或拉伸弹幕

1-4.  子级定位

子级所处坐标系与普通弹幕不同,原点为父级锚点,xy值0-100%为父级弹幕的矩形范围

  1. timing-function

def text a{

}set a{

}2s,timing-function

一个用css数据类型表示的函数,可以改变弹幕动画的渐变曲线,对所有可渐变属性生效,有以下几种类型

2-1. linear

弹幕动画的默认值,从开始到结束速度恒定不变

(0.0, 0.0, 1.0, 1.0)

2-2. ease

先加速,后减速

填入timing-function但无效时默认使用ease

(0.25, 0.1, 0.25, 1.0)

2-3. ease-in

逐渐加速

(0.42, 0.0, 1.0, 1.0)

2-4. ease-out

逐渐减速

(0.0, 0.0, 0.58, 1.0)

2-5. ease-in-out

类似ease,但加速较缓

(0.42, 0.0, 0.58, 1.0)

2-6. cubic-bezier(x1, y1, x2, y2)

演示图中的曲线实际上是一条三次贝塞尔曲线,由四个点定义,其中两点已固定(开始和结束),(x1, y1, x2, y2)即是剩余两点的坐标,其中x1,x2必须在[0,1]之间才能生效

(0.14,0.65,0.78,0.36) (0.34,1.07,0.71,-0.23) (0.12,3.56,0.86,-2.67)

调整两点坐标,可以使曲线递减甚至超出边界。

曲线递减动画逆向进行,造成弹跳效果。曲线超出边界时弹跳范围超出原属性或目标属性范围,但如color等属性到达上限/下限(ffffff或000000)时不会继续增大/减小。

2-7. step-start

动画开始后立刻转跳到结束状态,并保持到动画时间结束

2-8. step-end

动画开始后保持不变,直到动画时间结束立刻转跳到结束状态

2-9. steps(n, step-position)

使动画分步进行,n为正整数

 step-position可以为jump-start / jump-end / jump-none / jump-both / start / end

start / jump-start,初始状态不包含在分步

end / jump-end,结束状态不包含在分步内

jump-none,n大于1生效,初始和结束状态均包含在分步内

jump-both,初始和结束状态均不包含在分步内

八.button-互动按钮

def button a{

text=“”

target=av/seek/bangumi{

}

}

提供比较简单的互动按钮,可以点击转跳视频或时间

属性名值类型必要默认值可变渐变说明
xnumber0x 坐标,可以为百分比值
ynumber0y 坐标,可以为百分比值
zIndexnumber0层次权重,值高的对象在上层
scalenumber1缩放
durationtime元素生命周期,有动画时默认为动画总时间,无动画时默认4s
textstring‘请输入内容’按钮显示文字
fontSizenumber25按钮字体大小,可以为百分比(百分比字体大小为当前屏幕宽度*字体百分比px)
textColornumber0x000000按钮文字颜色
textAlphanumber1按钮字体透明度
fillColornumber0xffffff按钮填充颜色
fillAlphanumber1按钮填充透明度
target 按钮功能
fontFamliystring按钮文字字体
  1. 属性差异

与path类似,大部分文本弹幕属性不可用。作为子级时按钮功能依然生效,被旋转或缩放后按钮点击范围相应变动

  1. 按钮功能-target

指定按钮功能,格式稍微特殊,在上方有提到。分为三类

1-1.  av

用于转跳视频,支持bv和av

属性名值类型必要默认值可变渐变说明
bvid 二选一视频bv号,需带BV前缀
avnumber二选一视频av号
pagenumber1视频分P号
timetime0s视频开始播放点

1-2.  bangumi

用于转跳番剧

seasonId为番剧id,对应番剧网页链接的ssxxxxx部分

episodeId为剧集id,点开任意一集后链接出现epxxxxx

部分页面不显示ssid,可以打开网页源码寻找www.bilibili.com/bangumi/play/ssxxxx/链接

属性名值类型必要默认值可变渐变说明
seasonIdnumber番剧id
episodeIdnumber番剧分集id
timetime0s视频开始播放点

1-3.  seek

转跳视频时间

属性名值类型必要默认值可变渐变说明
timetimeseek目标时间

九.关于弹幕PV(大坑)

0.先来个提醒

能找到这个教程的应该都看过蓝白四期和以前的一些弹幕祭,基本是些比较神仙的弹幕pv,但个人不建议刚入坑就去肝pv,费时费力而且容易碰壁(深有体会)

弹幕pv需要设计画面,然后在bas弹幕的各种功能中找到实现方案,对没有实践经验的新人实在过于困难,也可能写着写着突然出现我tm写了坨屎的想法(也是深有体会)

先做些不太复杂的小动画或尝试还原一些片段是更好的选择

1-1.  ???

(这个坑不一定会填,不知道怎么写

(直接问人肯定比等我填坑靠谱

十.广告时间

想到的已经写完了,代码实例和演示用docx太麻烦就不做了

以后可能会继续更新(咕

更新了,好耶!

我的b站uid:52454723 S-Haya

社团uid:8324 弹幕Art研究社

已经复活蓝白官号:65413 弹幕娘

弹幕群:1006093326