decodeLrcString static method

LyricSrcEntity_c decodeLrcString(
  1. String lrcStr, {
  2. bool removeEmptyLine = true,
  3. bool parseHtmlEscape = true,
  4. bool limitInfoType(
    1. String typeStr
    )?,
})
  • 解析歌词文件 .lrc
  • removeEmptyLine 是否删除包含歌词时间,但内容却为空的行
  • limitInfoType 限制需要的 info 类型,默认不传入则接收所有的 info

Implementation

static LyricSrcEntity_c decodeLrcString(
  String lrcStr, {
  bool removeEmptyLine = true,
  bool parseHtmlEscape = true,
  bool Function(String typeStr)? limitInfoType,
}) {
  final lrcObj = LyricSrcEntity_c();
  // 按行切割
  var lrcArr = lrcStr.split(RegExp(r"\n|\r"));
  for (int i = 0; i < lrcArr.length; ++i) {
    // 去掉空白符
    StringUtilxx_c.removeAllSpace(lrcArr[i]);
    if (lrcArr[i].isEmpty) {
      // 如果是空行则丢弃这一行
      continue;
    }
    // 逐行解析
    final relist = _decodeLrcStrLine(
      lrcArr[i],
      removeEmptyLine: removeEmptyLine,
      parseHtmlEscape: parseHtmlEscape,
    );
    if (null == relist) {
      continue;
    }
    for (final line in relist) {
      switch (line.type) {
        case _ParseLyricType_e.Lrc:
          lrcObj.lrc.add(LyricSrcItemEntity_c(
            time: line.time ?? -1,
            content: line.content,
          ));
          break;
        case _ParseLyricType_e.Info:
          if (true == line.infoKey?.isNotEmpty &&
              line.infoKey != "lrc" &&
              false != limitInfoType?.call(line.infoKey!)) {
            lrcObj.info[line.infoKey!] = line.content;
          }
          break;
      }
    }
  }
  // 排序
  // <time, index>
  final templist = <MapEntry<double, LyricSrcItemEntity_c>>[];
  // 保存最近一次时间为正的值
  double lastAvailTime = 0;
  // *  将待排序歌词行进行临时时间转换,
  // 以保持没有指定时间的歌词行仍然可以跟随在正确的歌词行后面
  // 确保app显示解析的正确。
  for (int i = 0; i < lrcObj.lrc.length; ++i) {
    final item = lrcObj.lrc[i];
    if (item.time >= 0) {
      // 时间为正,取其时间
      lastAvailTime = item.time;
      templist.add(MapEntry(item.time, item));
    } else {
      // 没有指定时间,则回退取最近一行歌词的正的时间
      templist.add(MapEntry(lastAvailTime, item));
    }
  }
  // 进行稳定排序
  final relist = Utilxx_c.mergeSort<MapEntry<double, LyricSrcItemEntity_c>>(
    templist,
    (left, right) => ((left.key - right.key) * 1000).toInt(),
  );
  lrcObj.lrc = [];
  for (int i = 0; i < relist.length; ++i) {
    lrcObj.lrc.add(relist[i].value);
  }
  return lrcObj;
}