diff --git a/lib/http/api.dart b/lib/http/api.dart index 5074ccfe..b32c7e40 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -288,4 +288,8 @@ class Api { // github 获取最新版 static const String latestApp = 'https://api.github.com/repos/guozhigq/pilipala/releases/latest'; + + // 多少人在看 + // https://api.bilibili.com/x/player/online/total?aid=913663681&cid=1203559746&bvid=BV1MM4y1s7NZ&ts=56427838 + static const String onlineTotal = '/x/player/online/total'; } diff --git a/lib/http/video.dart b/lib/http/video.dart index f67702f0..a6084a6c 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -399,4 +399,16 @@ class VideoHttp { return {'status': false, 'msg': res.data['result']['toast']}; } } + + // 查看视频同时在看人数 + static Future onlineTotal({int? aid, String? bvid, int? cid}) async { + var res = await Request().get(Api.onlineTotal, data: { + 'aid': aid, + 'bvid': bvid, + 'cid': cid, + }); + if (res.data['code'] == 0) { + return {'status': true, 'data': res.data['data']}; + } + } } diff --git a/lib/pages/setting/play_setting.dart b/lib/pages/setting/play_setting.dart index 524b014a..77f6f269 100644 --- a/lib/pages/setting/play_setting.dart +++ b/lib/pages/setting/play_setting.dart @@ -66,6 +66,12 @@ class _PlaySettingState extends State { setKey: SettingBoxKey.enableHA, defaultVal: true, ), + const SetSwitchItem( + title: '观看人数', + subTitle: '展示同时在看人数', + setKey: SettingBoxKey.enableOnlineTotal, + defaultVal: false, + ), ListTile( dense: false, title: Text('默认画质', style: titleStyle), diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index 0817a046..ea63c14d 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -51,6 +53,12 @@ class VideoIntroController extends GetxController { RxInt lastPlayCid = 0.obs; var userInfo; + // 同时观看 + bool isShowOnlineTotal = false; + RxInt totel = 1.obs; + Timer? timer; + bool isPaused = false; + @override void onInit() { super.onInit(); @@ -78,6 +86,12 @@ class VideoIntroController extends GetxController { } userLogin = userInfo != null; lastPlayCid.value = int.parse(Get.parameters['cid']!); + isShowOnlineTotal = + setting.get(SettingBoxKey.enableOnlineTotal, defaultValue: false); + if (isShowOnlineTotal) { + queryOnlineTotal(); + startTimer(); // 在页面加载时启动定时器 + } } // 获取视频简介&分p @@ -417,4 +431,33 @@ class VideoIntroController extends GetxController { lastPlayCid.value = cid; await queryVideoIntro(); } + + void startTimer() { + const duration = Duration(seconds: 10); // 设置定时器间隔为10秒 + timer = Timer.periodic(duration, (Timer timer) { + if (!isPaused) { + queryOnlineTotal(); // 定时器回调函数,发起请求 + } + }); + } + + // 查看同时在看人数 + Future queryOnlineTotal() async { + var result = await VideoHttp.onlineTotal( + aid: IdUtils.bv2av(bvid), + bvid: bvid, + cid: lastPlayCid.value, + ); + if (result['status']) { + totel.value = int.parse(result['data']['total']); + } + } + + @override + void onClose() { + if (timer != null) { + timer!.cancel(); // 销毁页面时取消定时器 + } + super.onClose(); + } } diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 5f99dd9b..76acbad1 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -255,6 +255,17 @@ class _VideoInfoState extends State with TickerProviderStateMixin { color: t.colorScheme.outline, ), ), + const SizedBox(width: 10), + if (videoIntroController.isShowOnlineTotal) + Obx( + () => Text( + '${videoIntroController.totel.value}人在看', + style: TextStyle( + fontSize: 12, + color: t.colorScheme.outline, + ), + ), + ), ], ), ), diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index ddb53a79..5ece20a8 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -37,6 +37,8 @@ class _VideoDetailPageState extends State PlPlayerController? plPlayerController; final ScrollController _extendNestCtr = ScrollController(); late StreamController appbarStream; + final VideoIntroController videoIntroController = + Get.put(VideoIntroController(), tag: Get.arguments['heroTag']); PlayerStatus playerStatus = PlayerStatus.playing; // bool isShowCover = true; @@ -104,6 +106,7 @@ class _VideoDetailPageState extends State // 离开当前页面时 void didPushNext() async { videoDetailController.defaultST = plPlayerController!.position.value; + videoIntroController.isPaused = true; plPlayerController!.pause(); super.didPushNext(); } @@ -112,6 +115,7 @@ class _VideoDetailPageState extends State // 返回当前页面时 void didPopNext() async { videoDetailController.playerInit(); + videoIntroController.isPaused = false; if (_extendNestCtr.position.pixels == 0) { await Future.delayed(const Duration(milliseconds: 300)); plPlayerController!.play(); diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index 39654fab..c23ffb28 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -94,6 +94,7 @@ class SettingBoxKey { static const String danmakuEnable = 'danmakuEnable'; static const String defaultPicQa = 'defaultPicQa'; static const String enableHA = 'enableHA'; + static const String enableOnlineTotal = 'enableOnlineTotal'; static const String blackMidsList = 'blackMidsList';