diff --git a/lib/main.dart b/lib/main.dart index 988cbb864..1c34de2e3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,8 +4,6 @@ import 'package:PiliPlus/build_config.dart'; import 'package:PiliPlus/common/widgets/custom_toast.dart'; import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/models/common/theme/theme_color_type.dart'; -import 'package:PiliPlus/pages/main/view.dart'; -import 'package:PiliPlus/pages/video/view.dart'; import 'package:PiliPlus/router/app_pages.dart'; import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/services/loggeer.dart'; @@ -13,6 +11,7 @@ import 'package:PiliPlus/services/service_locator.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/cache_manage.dart'; import 'package:PiliPlus/utils/date_util.dart'; +import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; @@ -227,8 +226,7 @@ class MyApp extends StatelessWidget { ), navigatorObservers: [ FlutterSmartDialog.observer, - VideoDetailPageV.routeObserver, - MainApp.routeObserver, + PageUtils.routeObserver, ], ); }), diff --git a/lib/pages/live/view.dart b/lib/pages/live/view.dart index a1047b5bc..1a844d244 100644 --- a/lib/pages/live/view.dart +++ b/lib/pages/live/view.dart @@ -259,6 +259,7 @@ class _LivePageState extends CommonPageState ), const Spacer(), GestureDetector( + behavior: HitTestBehavior.opaque, onTap: () => Get.to(const LiveFollowPage()), child: Row( mainAxisSize: MainAxisSize.min, @@ -293,6 +294,7 @@ class _LivePageState extends CommonPageState return SizedBox( width: 65, child: GestureDetector( + behavior: HitTestBehavior.opaque, onTap: () => PageUtils.toLiveRoom(item.roomid), onLongPress: () { Feedback.forLongPress(context); diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index 973f74c09..dd33313e1 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -32,6 +32,7 @@ class LiveRoomController extends GetxController { final String heroTag; int roomId = Get.arguments; + DanmakuController? danmakuController; PlPlayerController plPlayerController = PlPlayerController.getInstance( isLive: true, ); @@ -61,7 +62,7 @@ class LiveRoomController extends GetxController { List? savedDanmaku; RxList messages = [].obs; RxBool disableAutoScroll = false.obs; - LiveMessageStream? msgStream; + LiveMessageStream? _msgStream; late final ScrollController scrollController = ScrollController() ..addListener(listener); @@ -73,6 +74,10 @@ class LiveRoomController extends GetxController { late final isLogin = accountService.isLogin.value; AccountService accountService = Get.find(); + String? videoUrl; + bool? isPlaying; + late bool isFullScreen = false; + @override void onInit() { super.onInit(); @@ -83,10 +88,13 @@ class LiveRoomController extends GetxController { } } - Future playerInit(String source) { + Future? playerInit({bool autoplay = true}) { + if (videoUrl == null) { + return null; + } return plPlayerController.setDataSource( DataSource( - videoSource: source, + videoSource: videoUrl, audioSource: null, type: DataSourceType.network, httpHeaders: { @@ -95,7 +103,8 @@ class LiveRoomController extends GetxController { 'referer': HttpString.baseUrl, }, ), - autoplay: true, + isLive: true, + autoplay: autoplay, isVertical: isPortrait.value, ); } @@ -145,8 +154,8 @@ class LiveRoomController extends GetxController { .firstWhereOrNull((element) => element.code == currentQn) ?.description ?? currentQn.toString(); - String videoUrl = VideoUtils.getCdnUrl(item); - await playerInit(videoUrl); + videoUrl = VideoUtils.getCdnUrl(item); + await playerInit(); isLoaded.value = true; } } @@ -198,7 +207,12 @@ class LiveRoomController extends GetxController { } } - void liveMsg() { + void closeLiveMsg() { + _msgStream?.close(); + _msgStream = null; + } + + void startLiveMsg() { if (messages.isEmpty) { LiveHttp.liveRoomDanmaPrefetch(roomId: roomId).then((v) { if (v['status']) { @@ -225,7 +239,7 @@ class LiveRoomController extends GetxController { } }); } - if (msgStream != null) { + if (_msgStream != null) { return; } if (dmInfo != null) { @@ -259,8 +273,7 @@ class LiveRoomController extends GetxController { cancelLiveTimer(); savedDanmaku?.clear(); savedDanmaku = null; - msgStream?.close(); - msgStream = null; + closeLiveMsg(); scrollController ..removeListener(listener) ..dispose(); @@ -285,7 +298,7 @@ class LiveRoomController extends GetxController { if (info.hostList.isNullOrEmpty) { return; } - msgStream = + _msgStream = LiveMessageStream( streamToken: info.token!, roomId: roomId, @@ -321,9 +334,11 @@ class LiveRoomController extends GetxController { selfSend: isLogin && uid == accountService.mid, ), ); - WidgetsBinding.instance.addPostFrameCallback( - (_) => scrollToBottom(), - ); + if (!isFullScreen) { + WidgetsBinding.instance.addPostFrameCallback( + (_) => scrollToBottom(), + ); + } } } } catch (_) {} diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index 6b7ab5ce9..f10907098 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -37,7 +37,7 @@ class LiveRoomPage extends StatefulWidget { } class _LiveRoomPageState extends State - with WidgetsBindingObserver { + with WidgetsBindingObserver, RouteAware { final String heroTag = Utils.generateRandomString(6); late final LiveRoomController _liveRoomController; late final PlPlayerController plPlayerController; @@ -63,18 +63,64 @@ class _LiveRoomPageState extends State ..addStatusLister(playerListener); } - void playerListener(PlayerStatus? status) { - if (status != PlayerStatus.playing) { - plPlayerController.danmakuController?.pause(); + @override + void didChangeDependencies() { + super.didChangeDependencies(); + PageUtils.routeObserver.subscribe( + this, + ModalRoute.of(context)! as PageRoute, + ); + } + + @override + Future didPopNext() async { + WidgetsBinding.instance.addObserver(this); + PlPlayerController.setPlayCallBack(plPlayerController.play); + plPlayerController.danmakuController = + _liveRoomController.danmakuController; + _liveRoomController.startLiveTimer(); + if (plPlayerController.playerStatus.playing) { _liveRoomController - ..cancelLiveTimer() - ..msgStream?.close() - ..msgStream = null; + ..danmakuController?.resume() + ..startLiveMsg(); } else { - plPlayerController.danmakuController?.resume(); + final shouldPlay = _liveRoomController.isPlaying ?? false; + if (shouldPlay) { + _liveRoomController + ..danmakuController?.resume() + ..startLiveMsg(); + } + await _liveRoomController.playerInit(autoplay: shouldPlay); + } + plPlayerController.addStatusLister(playerListener); + + super.didPopNext(); + } + + @override + void didPushNext() { + WidgetsBinding.instance.removeObserver(this); + plPlayerController.removeStatusLister(playerListener); + _liveRoomController + ..danmakuController?.clear() + ..danmakuController?.pause() + ..cancelLiveTimer() + ..closeLiveMsg() + ..isPlaying = plPlayerController.playerStatus.playing; + super.didPushNext(); + } + + void playerListener(PlayerStatus? status) { + if (status == PlayerStatus.playing) { _liveRoomController + ..danmakuController?.resume() ..startLiveTimer() - ..liveMsg(); + ..startLiveMsg(); + } else { + _liveRoomController + ..danmakuController?.pause() + ..cancelLiveTimer() + ..closeLiveMsg(); } } @@ -87,6 +133,7 @@ class _LiveRoomPageState extends State plPlayerController ..removeStatusLister(playerListener) ..dispose(); + PageUtils.routeObserver.unsubscribe(this); super.dispose(); } @@ -150,6 +197,7 @@ class _LiveRoomPageState extends State Alignment? alignment, bool needDm = true, }) { + _liveRoomController.isFullScreen = isFullScreen; return PopScope( canPop: !isFullScreen, onPopInvokedWithResult: (bool didPop, Object? result) { @@ -182,6 +230,7 @@ class _LiveRoomPageState extends State danmuWidget: !needDm ? null : LiveDanmaku( + liveRoomController: _liveRoomController, plPlayerController: plPlayerController, isFullScreen: isFullScreen, isPipMode: isPipMode, @@ -743,12 +792,14 @@ class _LiveRoomPageState extends State } class LiveDanmaku extends StatefulWidget { + final LiveRoomController liveRoomController; final PlPlayerController plPlayerController; final bool isPipMode; final bool isFullScreen; const LiveDanmaku({ super.key, + required this.liveRoomController, required this.plPlayerController, this.isPipMode = false, required this.isFullScreen, @@ -791,7 +842,8 @@ class _LiveDanmakuState extends State { duration: const Duration(milliseconds: 100), child: DanmakuScreen( createdController: (DanmakuController e) { - plPlayerController.danmakuController = e; + widget.liveRoomController.danmakuController = + plPlayerController.danmakuController = e; }, option: DanmakuOption( fontSize: _fontSize, diff --git a/lib/pages/main/view.dart b/lib/pages/main/view.dart index 55750e426..9b956b64a 100644 --- a/lib/pages/main/view.dart +++ b/lib/pages/main/view.dart @@ -11,6 +11,7 @@ import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/context_ext.dart'; import 'package:PiliPlus/utils/extension.dart'; +import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; @@ -23,9 +24,6 @@ class MainApp extends StatefulWidget { @override State createState() => _MainAppState(); - - static final RouteObserver routeObserver = - RouteObserver(); } class _MainAppState extends State @@ -43,7 +41,10 @@ class _MainAppState extends State super.didChangeDependencies(); NetworkImgLayer.reduce = NetworkImgLayer.reduceLuxColor != null && context.isDarkMode; - MainApp.routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute); + PageUtils.routeObserver.subscribe( + this, + ModalRoute.of(context) as PageRoute, + ); } @override @@ -74,7 +75,7 @@ class _MainAppState extends State @override void dispose() { - MainApp.routeObserver.unsubscribe(this); + PageUtils.routeObserver.unsubscribe(this); WidgetsBinding.instance.removeObserver(this); GStorage.close(); PiliScheme.listener?.cancel(); diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index d45039f15..f38e44f0f 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -68,8 +68,6 @@ class VideoDetailPageV extends StatefulWidget { @override State createState() => _VideoDetailPageVState(); - static final RouteObserver routeObserver = - RouteObserver(); } class _VideoDetailPageVState extends State @@ -381,7 +379,7 @@ class _VideoDetailPageVState extends State } else { PlPlayerController.updatePlayCount(); } - VideoDetailPageV.routeObserver.unsubscribe(this); + PageUtils.routeObserver.unsubscribe(this); showStatusBar(); _introScrollController?.dispose(); super.dispose(); @@ -476,7 +474,7 @@ class _VideoDetailPageVState extends State @override void didChangeDependencies() { super.didChangeDependencies(); - VideoDetailPageV.routeObserver.subscribe( + PageUtils.routeObserver.subscribe( this, ModalRoute.of(context)! as PageRoute, ); diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 78f1cbec3..4cdb2d6de 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -507,14 +507,17 @@ class PlPlayerController { // 获取实例 传参 static PlPlayerController getInstance({bool isLive = false}) { // 如果实例尚未创建,则创建一个新实例 - _instance ??= PlPlayerController._().._isLive = isLive; - _instance!._playerCount.value += 1; + _instance ??= PlPlayerController._(); + _instance! + .._isLive = isLive + .._playerCount.value += 1; return _instance!; } // 初始化资源 Future setDataSource( DataSource dataSource, { + bool isLive = false, List? segmentList, List? viewPointList, bool? showVP, @@ -542,6 +545,7 @@ class PlPlayerController { VoidCallback? callback, }) async { try { + _isLive = isLive; _videoType = videoType ?? VideoType.ugc; this.width = width; this.height = height; diff --git a/lib/utils/page_utils.dart b/lib/utils/page_utils.dart index 1386520f8..c2144426c 100644 --- a/lib/utils/page_utils.dart +++ b/lib/utils/page_utils.dart @@ -15,7 +15,6 @@ import 'package:PiliPlus/pages/contact/view.dart'; import 'package:PiliPlus/pages/fav_panel/view.dart'; import 'package:PiliPlus/pages/share/view.dart'; import 'package:PiliPlus/pages/video/introduction/ugc/widgets/menu_row.dart'; -import 'package:PiliPlus/plugin/pl_player/controller.dart'; import 'package:PiliPlus/services/shutdown_timer_service.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/context_ext.dart'; @@ -35,6 +34,9 @@ import 'package:get/get.dart' hide ContextExtensionss; import 'package:url_launcher/url_launcher.dart'; class PageUtils { + static final RouteObserver routeObserver = + RouteObserver(); + static Future imageView({ int initialPage = 0, required List imgList, @@ -690,10 +692,6 @@ class PageUtils { if (roomId == null) { return; } - if (PlPlayerController.instanceExists()) { - SmartDialog.showToast('unsupported'); - return; - } if (off) { Get.offNamed('/liveRoom', arguments: roomId); } else { @@ -716,10 +714,6 @@ class PageUtils { int? id, bool off = false, }) { - if (PlPlayerController.instance?.isLive == true) { - SmartDialog.showToast('Living'); - return; - } final arguments = { 'aid': aid ?? IdUtils.bv2av(bvid!), 'bvid': bvid ?? IdUtils.av2bv(aid!),