美文网首页Flutter圈子All in FlutterFlutter
Flutter 实现网易云音乐字幕

Flutter 实现网易云音乐字幕

作者: 老孟程序员 | 来源:发表于2020-04-14 20:47 被阅读0次

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

    先来一张效果图:

    image

    字幕格式

    目前市面上有很多种字幕格式,比如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),
        )
    )
    

    效果如下:

    image

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

    Subtitle(
        _subtitleList,
        diameterRatio: 5,
    )
    

    下面是1和5的对比:

    image
    image

    Github地址:https://github.com/781238222/flutter-do/tree/master/flutter_subtitle_example

    交流

    Github地址:https://github.com/781238222/flutter-do

    170+组件详细用法:http://laomengit.com

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

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

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

    相关文章

      网友评论

        本文标题:Flutter 实现网易云音乐字幕

        本文链接:https://www.haomeiwen.com/subject/iwexvhtx.html