From 19377e8e707e286e19fca6d47523dd44c58ca631 Mon Sep 17 00:00:00 2001 From: PuerNya Date: Tue, 19 Nov 2024 00:24:56 +0800 Subject: [PATCH] feat: prefetch live room danmu (#4) --- lib/http/api.dart | 5 +++++ lib/http/live.dart | 15 +++++++++++++++ lib/pages/live_room/controller.dart | 26 +++++++++++++++++++++++++- lib/pages/live_room/widgets/chat.dart | 15 +++++++-------- 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 428204ac..72099597 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -289,6 +289,11 @@ class Api { static const String liveRoomInfoH5 = '${HttpString.liveBaseUrl}/xlive/web-room/v1/index/getH5InfoByRoom'; + // 直播间弹幕预获取 + // roomid roomId + static const String liveRoomDmPrefetch = + '${HttpString.liveBaseUrl}/xlive/web-room/v1/dM/gethistory'; + //直播间弹幕密钥获取接口 static const String liveRoomDmToken = '${HttpString.liveBaseUrl}/xlive/web-room/v1/index/getDanmuInfo'; diff --git a/lib/http/live.dart b/lib/http/live.dart index f513cfd3..4f6c4f00 100644 --- a/lib/http/live.dart +++ b/lib/http/live.dart @@ -111,6 +111,21 @@ class LiveHttp { } } + static Future liveRoomDanmaPrefetch({roomId}) async { + var res = await Request().get(Api.liveRoomDmPrefetch, data: { + 'roomid': roomId, + }); + if (res.data['code'] == 0) { + return {'status': true, 'data': res.data['data']['room']}; + } else { + return { + 'status': false, + 'data': [], + 'msg': res.data['message'], + }; + } + } + static Future liveRoomGetDanmakuToken({roomId}) async { var res = await Request().get(Api.liveRoomDmToken, data: { 'id': roomId, diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index 1ecc3528..9b359e08 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -120,6 +120,24 @@ class LiveRoomController extends GetxController { } void liveMsg() { + LiveHttp.liveRoomDanmaPrefetch(roomId: roomId).then((v) { + if (v['status']) { + for (var obj in v['data'] as List) { + messages.add({ + 'name': obj['user']['base']['name'], + 'uid': obj['user']['uid'], + 'text': obj['text'], + 'emots': obj['emots'], + 'uemote': obj['emoticon']['emoticon_unique'] != "" + ? obj['emoticon'] + : null, + }); + WidgetsBinding.instance.addPostFrameCallback( + (_) => scrollToBottom(), + ); + } + } + }); LiveHttp.liveRoomGetDanmakuToken(roomId: roomId).then((v) { if (v['status']) { LiveDanmakuInfo info = v['data']; @@ -134,7 +152,13 @@ class LiveRoomController extends GetxController { msgStream?.addEventListener((obj) { if (obj['cmd'] == 'DANMU_MSG') { // logger.i(' 原始弹幕消息 ======> ${jsonEncode(obj)}'); - messages.add(obj); + messages.add({ + 'name': obj['info'][0][15]['user']['base']['name'], + 'uid': obj['info'][0][15]['user']['uid'], + 'text': obj['info'][1], + 'emots': jsonDecode(obj['info'][0][15]['extra'])['emots'], + 'uemote': obj['info'][0][13], + }); Map json = jsonDecode(obj['info'][0][15]['extra']); if (showDanmaku) { controller?.addItems([ diff --git a/lib/pages/live_room/widgets/chat.dart b/lib/pages/live_room/widgets/chat.dart index 282b790f..962ca43a 100644 --- a/lib/pages/live_room/widgets/chat.dart +++ b/lib/pages/live_room/widgets/chat.dart @@ -49,7 +49,7 @@ class _LiveRoomChatState extends State { children: [ TextSpan( text: - '${widget.liveRoomController.messages[index]['info'][0][15]['user']['base']['name']}: ', + '${widget.liveRoomController.messages[index]['name']}: ', style: const TextStyle( color: Color(0xFFAAAAAA), fontSize: 14, @@ -57,9 +57,8 @@ class _LiveRoomChatState extends State { recognizer: TapGestureRecognizer() ..onTap = () { try { - dynamic uid = - widget.liveRoomController.messages[index] - ['info'][0][15]['user']['uid']; + dynamic uid = widget + .liveRoomController.messages[index]['uid']; Get.toNamed( '/member?mid=$uid', arguments: { @@ -102,8 +101,8 @@ class _LiveRoomChatState extends State { } TextSpan _buildMsg(obj) { - dynamic emots = jsonDecode(obj['info'][0][15]['extra'])['emots']; - dynamic uemote = obj['info'][0][13]; + dynamic emots = obj['emots']; + dynamic uemote = obj['uemote']; List list = [ if (emots != null) emots.keys, if (uemote is Map) uemote['emoticon_unique'].replaceFirst('upower_', '') @@ -117,7 +116,7 @@ class _LiveRoomChatState extends State { }).toList(); RegExp regExp = RegExp(list.join('|')); final List spanChildren = []; - (obj['info'][1] as String).splitMapJoin( + (obj['text'] as String).splitMapJoin( regExp, onMatch: (Match match) { String key = match[0]!; @@ -150,7 +149,7 @@ class _LiveRoomChatState extends State { return TextSpan(children: spanChildren); } else { return TextSpan( - text: obj['info'][1], + text: obj['text'], style: const TextStyle( color: Color(0xFFFFFFFF), fontSize: 14,