BAS advanced barrage

January 25, 2018 · Creations
Table of Contents Expand

written in front

If you are curious about whether the work at Bilibili is interesting, or what I have been doing since I came to Bilibili, then this article may answer some of your questions.

After coming to Bilibili, in addition to being responsible for some modules, reconstruction and daily maintenance of the HTML5 player, BAS advanced barrage is the largest project I have been responsible for development in the past six months.

This article is compiled from today’s sharing of superpolar electromagnetic waves in the company (it is said that I am still the youngest lecturer in history (=・ω・=)), and it can also be regarded as a phased summary of this project.

What is BAS barrage?

BAS, the full name of Bilibili Animation Script, is a new generation of bilibili’s advanced barrage script language. It is a text used to describe advanced barrage styles, interactions and animations.

BAS barrage is an advanced barrage described by BAS. It consists of elements and animations. Elements are divided into text objects, interactive buttons, and path objects. Animations are divided into simple animations, series animations, and parallel animations.

BAS Danmaku is mainly aimed at high-end players such as subtitle writers, and can be used in subtitles, special effects, interactive applications, games, pure Danmaku works and other scenarios.

At present, the web client has been launched and the mobile client has been basically developed. It is expected to be used in next year’s activities or New Year celebrations.

We made several videos to visually demonstrate BAS barrages:

The first one is the barrage PV made by Mr. Maojiang: https://www.bilibili.com/video/av257649/

The second one is a rotten apple implemented by barrages: https://www.bilibili.com/video/av18682336/

The third is a demonstration of interactive buttons: https://www.bilibili.com/video/av16558829/index_3.html#page=3. In addition, Bilibili Ranking Weekly is also a good application scenario.

In terms of subtitle applications, it is easy to implement a tool such as converting subtitle files to BAS, and we will continue to do such things in the future.

Comparison of several advanced barrages

mode7

Danmaku is set through the interface and does not require writing code. It is simple to use but has limited functions.

bas1

mode8

That is, the code barrage is very powerful but requires writing code, is complex to use, has poor security, and only supports the Flash platform.

bas2

mode9

That is, BAS barrage is a compromise between mode 7 and mode 8.

Compared with mode 7, mode 9 requires scripting and is slightly more complex to use, but it supports interaction, graphics and more complex animations, and is much more powerful.

Compared with mode 8, mode 9 simplifies the syntax and uses declarative style, which is simpler to use; safer, the player parses the implementation, illegal scripts will not be released, the program is controllable, instead of directly operating the barrage; it can be cross-platform.

bas3

Use BAS barrage

Send permission

First of all, there are strict restrictions on the permission to send BAS barrages. In terms of design, ordinary users need to purchase it with coins first, and then wait for confirmation from the UP owner before they can use it. Only users with special permissions such as subtitlers can use it directly, but it is currently only open to subtitlers. After subtitlers use it and improve it, they will consider expanding the use scenarios.

Coin PurchaseUP Master Confirmation
Ordinary members
UP main×
VIP×
Subtitler/Administrator××

Send entry

  1. bas4
  2. bas5

Note that the entrance is hidden when there is no sending permission. At this time, you can try it in Laboratory.

Write script

Let’s try to write some simple scripts. BAS script is very simple. It is a declarative and descriptive script with easy-to-use syntax, which ensures the independence of object blocks and operation blocks.

The easiest way to try BAS barrages is to use the examples and labs on Documentation. You can open it in a new tab in your browser and follow the examples to try out some basic usage.

Taking text objects as an example, a simple text object with fade animation looks like this:

def text demo {
    content = "BAS"
}
set demo {
    alpha = 0
} 5s

In this way, we successfully created a fading BAS barrage. It looks very simple, but js does a lot of work behind the scenes. js will first parse the BAS script into an object that js can recognize, apply the default attributes, and then render it into the player and start the animation at the same time. At this time, you can see a fading white text in the upper left corner of the player.

Positioning

Positioning is also very simple. The positioning of BAS barrage is determined by the barrage anchor point (anchorX anchorY) and the stage position (x y). The anchor point is the center point of the barrage, (0, 0) is the upper left corner of the barrage, and (1, 1) is the lower right corner of the barrage.

def text tl {
    content = "左上"
    x = 0
    y = 0
    anchorX = 0
    anchorY = 0
}
def text tr {
    content = "右上"
    x = 100%
    y = 0
    anchorX = 1
    anchorY = 0
}
def text bl {
    content = "左下"
    x = 0
    y = 100%
    anchorX = 0
    anchorY = 1
}
def text br {
    content = "右下"
    x = 100%
    y = 100%
    anchorX = 1
    anchorY = 1
}
def text c {
    content = "中心"
    x = 50%
    y = 50%
    anchorX = 0.5
    anchorY = 0.5
}

Barrage stage

The barrage stage is the drawing range of the barrage. The barrage stage defaults to the real area of the video. In addition, the text object can specify other text objects as parent elements through the parent attribute, and the parent element is used as the stage for drawing. The parent element will affect the positioning, scaling, etc. of the child elements.

def text a {
    content = "□"
    fontSize = 40%
    x = 0
    y = 0
    color = 0xffff00
}
def text b {
    parent = "a"
    content = "□"
    fontSize = 20%
    x = 0
    y = 0
    color = 0xff00ff
}
set a {
    x = 50%
    y = 0
} 2s
then set a {} 3s
set b {
    y = 50%
} 3s
then set b {} 3s

Life cycle

Life cycle is another important concept of BAS. The life cycle is the survival time of the barrage. When the duration attribute is not specified, the element life cycle is the total animation time. When there is no animation, the default is 4s. After the life cycle ends, the element will be cleared from the stage.

def text a {
    content = "BAS"
}
def text a {
    content = "BAS"
    duration = 10s
}
def text a {
    content = "BAS"
}
set a {} 10s

Adaptive

When the position and font size are percentage values, they can be adapted according to the stage size, which can achieve the consistency effect of the barrage on various platforms and different player sizes, so that the position and size of the barrage relative to the video are fixed under different circumstances. The position coordinates are the current stage width and height _ percentage value px, and the font size is the current stage width _ percentage value px.

def text c {
    content = "BAS"
    x = 50%
    y = 50%
    anchorX = 0.5
    anchorY = 0.5
    fontSize = 5%
}

When the player size is changed at this time, the size of the barrage will also change with the player. As a result, its position and size relative to the video are fixed.

Interaction

Currently, only interactive buttons support some simple click effects, such as jumping to a certain time point in the video, opening other videos in a new window, etc.

seek button:

def button c {
    text = "跳转到30分钟"
    x = 35%
    y = 45%
    fontSize = 5%
    textColor = 0xffffff
    fillColor = 0x80D8FF
    target = seek {
        time = 30m
    }
}

av jump button:

def button c {
    text = "av1714157"
    x = 35%
    y = 45%
    fontSize = 5%
    textColor = 0xffffff
    fillColor = 0x80D8FF
    duration = 2s
    target = av {
        av = 1714157
        page = 1
        time = 20.5s500ms
    }
}

bangumi jump button:

def button c {
    text = "第22话 春风"
    x = 35%
    y = 45%
    fontSize = 5%
    textColor = 0xffffff
    fillColor = 0x80D8FF
    duration = 2s
    target = bangumi {
        seasonId = 1699
        episodeId = 80041
        time = 1m30s
    }
}

Graphics

You can use the path object to draw svg graphics, and the d attribute corresponds to the path of the svg.

def path p {
    d = "M30.828,30.422 18.997,16.260 Z"
    viewBox="0 0 32 34"
    x = 45%
    y = 45%
    scale = 3
    borderWidth = 1
    borderColor = 0xffffff
    borderAlpha = 0.8
    fillColor = 0x00a1d6
    fillAlpha = 0.8
}

Animation

Animation is divided into simple animation, series animation and parallel animation.

The attributes of barrage can be classified into gradient, non-gradable, and immutable. Only gradientable attributes can have normal animation effects. Setting new values for non-gradient attributes will take effect immediately, and setting values for immutable attributes will be ignored. In principle, a certain attribute can only appear once in a set statement. In terms of implementation, if it appears multiple times, the last one will prevail.

Cascaded animations run sequentially.

def text a {
  content = "BAS"
}
set a {
    color = 0x000000
} 1s
then set a {
    alpha = 0
} 1s

Parallel animations are performed at the same time. When the same attributes are connected in parallel, the last conflicting animation will be ignored. Due to technical limitations, x y rotateX rotateY rotateZ scale are regarded as the same attribute.

def text a {
  content = "BAS"
}
set a {
    color = 0x000000
} 1s
set a {
    alpha = 0
} 1s

Front-end implementation of BAS barrage

From BAS script to DOM element rendered in the browser, there are mainly the following steps:

  1. Parse the BAS script into a js object (https://github.com/aristotle9/as3cc)
  2. Apply default values and calculate percentage values
  3. Monitoring life cycle
  4. Resolve attribute conflicts
  5. Draw elements, apply styles and animations
  6. Bind interactive events

Positioning

Positioning is determined by the anchor point (anchorX anchorY) and position (x y) of the BAS script. In implementation, two nested DOM elements are used. The external element locates the stage position, and the internal element locates the barrage anchor point, such as a centered text object:

def text c {
    content = "BAS"
    x = 50%
    y = 50%
    anchorX = 0.5
    anchorY = 0.5
}

The rendered DOM structure is roughly like this:

<div style="transform:translate((舞台宽度*50%)px, (舞台高度*50%)px);">
  <div style="transform:translate(-50%,-50%);">BAS弹幕</div>
</div>

Animation

Considering browser compatibility and ease of use in animation, CSS3 animation is the best choice, and the properties involved are:

PropertiesDescription
@keyframesDefine animation
animation-nameThe name of the animation corresponding to @keyframes
animation-durationThe time it takes for the animation to complete one cycle
animation-play-stateanimation running or paused
animation-timing-functionanimation speed curve

Simple animation

Using the example above:

def text demo {
    content = "BAS"
}
set demo {
    alpha = 0
} 5s

The DOM structure rendered by such a BAS script is roughly as follows:

<style>
  @keyframes a1 {
    100% {
      opacity: 0;
    }
  }
</style>
<div style="animation-name:a1;animation-duration:5s;opacity:1;">BAS</div>

keyframes defines animation keyframes, and the transparency is zero when the animation ends; animation-duration corresponds to the animation time of 5s.

Parallel animation

Define multiple keyframes to enable multiple animations to run simultaneously.

def text a {
    content = "BAS"
}
set a {
    color = 0x000000
} 1s
set a {
    alpha = 0
} 1s
<style>
  @keyframes a1 {
    100% {
      color: #000000;
    }
  }
  @keyframes a2 {
    100% {
      opacity: 0;
    }
  }
</style>
<div
  style="animation-name:a1,a2;animation-duration:1s,1s;opacity:1;color:#ffffff;"
>
  BAS
</div>

Series animation

Use animation-delay to stagger the start times of different animations to achieve a series effect.

def text a {
  content = "BAS"
}
set a {
    color = 0x000000
} 1s
then set a {
    alpha = 0
} 1s
<style>
  @keyframes a1 {
    100% {
      color: #000000;
    }
  }
  @keyframes a2 {
    0% {
      color: #000000;
    }
    100% {
      color: #000000;
      opacity: 0;
    }
  }
</style>
<div
  style="animation-name:a1,a2;animation-duration:1s,1s;animation-delay:0s,1s;opacity:1;color:#ffffff;"
>
  BAS
</div>

Status control

Start

animation-play-state: running

Pause

animation-play-state: paused

Intermediate state

Setting animation-delay to a negative value allows you to start animation from an intermediate state.

For example, the life cycle of the barrage corresponds to 1s to 5s of the video. When the video jumps to 4s, the animation-delay property of the barrage needs to be set to -1s.

End

When the life cycle ends, the element needs to be cleared in time. The principle is that the end of the animation animation will trigger the animationend event. When this event is triggered, the element can be cleared. When the element has no animation, you need to specify an empty animation.

<style>
  @keyframes a1 {
    100% {
    }
  }
</style>

End.

DIYgod Hi, DIYgod

Running for 4344 days

© 2026 DIYgod. All rights reserved. Please credit when sharing.