
微信交流群
老孟导读:没有接触过音乐字幕方面知识的话,会对字幕的实现比较迷茫,什么时候转到下一句?看了这篇文章,你就会明白字幕 so easy。
先来一张效果图:

# 字幕格式
目前市面上有很多种字幕格式,比如 srt, ssa, ass(文本形式)和 idx+sub(图形格式),但不管哪一种格式都会包含 2 个属性:时间戳和字幕内容,格式如下:
00:00 歌词:
00:25 我要穿越这片沙漠
00:28 找寻真的自我
00:30 身边只有一匹骆驼陪我
00:34 这片风儿吹过
00:36 那片云儿飘过
1
2
3
4
5
6
2
3
4
5
6
上面字幕的意思是:在 25 秒的时候跳转到下一句,在 28 秒的时候跳转到下一句...
# 字幕实现
了解了字幕文件的形式,字幕实现起来就比较简单了,使用ListWheelScrollView
控件,然后通过ScrollController
在合适的时机进行滚动,使当前字幕始终保持在屏幕中间。
解析字幕文件,获取字幕数据:
loadData() async {
var jsonStr =
await DefaultAssetBundle.of(context).loadString('assets/subtitle.txt');
var list = jsonStr.split(RegExp('\n'));
list.forEach((f) {
if (f.isNotEmpty) {
var r = f.split(RegExp(' '));
if (r.length >= 2) {
_subtitleList.add(SubtitleEntry(r[0], r[1]));
}
}
});
setState(() {});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
设置字幕控件及背景图片:
build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('弹幕'),
),
body: Stack(
children: <Widget>[
Positioned.fill(
child: Image.asset(
'assets/imgs/background.png',
fit: BoxFit.cover,
)),
Positioned.fill(
child: Subtitle(
_subtitleList,
selectedTextStyle: TextStyle(color: Colors.white,fontSize: 18),
unSelectedTextStyle: TextStyle(
color: Colors.black.withOpacity(.6),
),
diameterRatio: 5,
itemExtent: 45,
))
],
),
);
}
Widget
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
字幕控件的构建:
build(BuildContext context) {
if (widget.data == null || widget.data.length == 0) {
return Container();
}
return ListWheelScrollView.useDelegate(
controller: _controller,
diameterRatio: widget.diameterRatio,
itemExtent: widget.itemExtent,
childDelegate: ListWheelChildBuilderDelegate(
builder: (context, index) {
return Container(
alignment: Alignment.center,
child: Text(
'${widget.data[index].content}',
style: _currentIndex == index
? widget.selectedTextStyle
: widget.unSelectedTextStyle,
),
);
},
childCount: widget.data.length),
);
}
Widget
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
字幕控件封装了选中字体和未选中字体样式参数,用法如下:
Subtitle(
_subtitleList,
selectedTextStyle: TextStyle(color: Colors.white,fontSize: 18),
unSelectedTextStyle: TextStyle(
color: Colors.black.withOpacity(.6),
)
)
1
2
3
4
5
6
7
2
3
4
5
6
7
效果如下:

设置圆筒直径和主轴渲染窗口的尺寸的比,默认值是 2,越小表示圆筒越圆
Subtitle(
_subtitleList,
diameterRatio: 5,
)
1
2
3
4
2
3
4
下面是 1 和 5 的对比:


Github 地址:https://github.com/781238222/flutter-do/tree/master/flutter_subtitle_example
版权所有,禁止私自转发、克隆网站。