欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Flutter 实现网易云音乐字幕

程序员文章站 2022-07-02 09:23:05
老孟导读:没有接触过音乐字幕方面知识的话,会对字幕的实现比较迷茫,什么时候转到下一句?看了这篇文章,你就会明白字幕so easy。 先来一张效果图: 字幕格式 目前市面上有很多种字幕格式,比如srt, ssa, ass(文本形式)和idx+sub(图形格式),但不管哪一种格式都会包含2个属性:时间戳 ......

Flutter 实现网易云音乐字幕

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

先来一张效果图:

Flutter 实现网易云音乐字幕

字幕格式

目前市面上有很多种字幕格式,比如srt, ssa, ass(文本形式)和idx+sub(图形格式),但不管哪一种格式都会包含2个属性:时间戳和字幕内容,格式如下:

00:00 歌词:
00:25 我要穿越这片沙漠
00:28 找寻真的自我
00:30 身边只有一匹骆驼陪我
00:34 这片风儿吹过
00:36 那片云儿飘过

上面字幕的意思是:在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(() {});
}

设置字幕控件及背景图片:

@override
widget 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,
        ))
      ],
    ),
  );
}

字幕控件的构建:

@override
widget 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),
  );
}

字幕控件封装了选中字体和未选中字体样式参数,用法如下:

subtitle(
	_subtitlelist,
	selectedtextstyle: textstyle(color: colors.white,fontsize: 18),
	unselectedtextstyle: textstyle(
  	color: colors.black.withopacity(.6),
	)
)

效果如下:

Flutter 实现网易云音乐字幕

设置圆筒直径和主轴渲染窗口的尺寸的比,默认值是2,越小表示圆筒越圆

subtitle(
	_subtitlelist,
	diameterratio: 5,
)

下面是1和5的对比:

Flutter 实现网易云音乐字幕Flutter 实现网易云音乐字幕

github地址:

交流

github地址:

170+组件详细用法:

如果你对flutter还有疑问或者技术方面的疑惑,欢迎加入flutter交流群(微信:laomengit)。

同时也欢迎关注我的flutter公众号【老孟程序员】,公众号首发flutter的相关内容。

flutter生态建设离不开你我他,需要大家共同的努力,点赞也是其中的一种,如果文章帮助到了你,希望点个赞。