mod: show live media notification

Closes #584

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-02 17:34:08 +08:00
parent 2abf01362c
commit f64d543ec7
4 changed files with 47 additions and 12 deletions

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/http/video.dart';
import 'package:PiliPlus/models/live/danmu_info.dart'; import 'package:PiliPlus/models/live/danmu_info.dart';
import 'package:PiliPlus/models/live/quality.dart'; import 'package:PiliPlus/models/live/quality.dart';
import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/pages/mine/controller.dart';
import 'package:PiliPlus/services/service_locator.dart';
import 'package:PiliPlus/tcp/live.dart'; import 'package:PiliPlus/tcp/live.dart';
import 'package:PiliPlus/utils/danmaku.dart'; import 'package:PiliPlus/utils/danmaku.dart';
import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage.dart';
@@ -20,6 +21,8 @@ import '../../models/live/room_info_h5.dart';
import '../../utils/video_utils.dart'; import '../../utils/video_utils.dart';
class LiveRoomController extends GetxController { class LiveRoomController extends GetxController {
LiveRoomController(this.heroTag);
final String heroTag;
late int roomId; late int roomId;
dynamic liveItem; dynamic liveItem;
double volume = 0.0; double volume = 0.0;
@@ -118,6 +121,11 @@ class LiveRoomController extends GetxController {
var res = await LiveHttp.liveRoomInfoH5(roomId: roomId); var res = await LiveHttp.liveRoomInfoH5(roomId: roomId);
if (res['status']) { if (res['status']) {
roomInfoH5.value = res['data']; roomInfoH5.value = res['data'];
videoPlayerServiceHandler.onVideoDetailChange(
roomInfoH5.value,
roomId,
heroTag,
);
} }
return res; return res;
} }

View File

@@ -4,6 +4,7 @@ import 'dart:ui';
import 'package:PiliPlus/http/live.dart'; import 'package:PiliPlus/http/live.dart';
import 'package:PiliPlus/pages/live_room/widgets/chat.dart'; import 'package:PiliPlus/pages/live_room/widgets/chat.dart';
import 'package:PiliPlus/services/service_locator.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
@@ -55,14 +56,17 @@ class _LiveRoomPageState extends State<LiveRoomPage>
plPlayerController.play(); plPlayerController.play();
} }
late final String heroTag;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
_roomId = int.parse(Get.parameters['roomid'] ?? '-1'); _roomId = int.parse(Get.parameters['roomid'] ?? '-1');
heroTag = Utils.makeHeroTag(_roomId);
_liveRoomController = Get.put( _liveRoomController = Get.put(
LiveRoomController(), LiveRoomController(heroTag),
tag: Utils.makeHeroTag(_roomId), tag: heroTag,
); );
PlPlayerController.setPlayCallBack(playCallBack); PlPlayerController.setPlayCallBack(playCallBack);
if (Platform.isAndroid) { if (Platform.isAndroid) {
@@ -107,6 +111,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
@override @override
void dispose() { void dispose() {
videoPlayerServiceHandler.onVideoDetailDispose(heroTag);
_listener?.cancel(); _listener?.cancel();
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
ScreenBrightness().resetApplicationScreenBrightness(); ScreenBrightness().resetApplicationScreenBrightness();

View File

@@ -853,7 +853,10 @@ class PlPlayerController {
playerStatus.status.value = PlayerStatus.paused; playerStatus.status.value = PlayerStatus.paused;
} }
videoPlayerServiceHandler.onStatusChange( videoPlayerServiceHandler.onStatusChange(
playerStatus.status.value, isBuffering.value); playerStatus.status.value,
isBuffering.value,
videoType.value == 'live',
);
/// 触发回调事件 /// 触发回调事件
for (var element in _statusListeners) { for (var element in _statusListeners) {
@@ -900,7 +903,10 @@ class PlPlayerController {
videoPlayerController!.stream.buffering.listen((bool event) { videoPlayerController!.stream.buffering.listen((bool event) {
isBuffering.value = event; isBuffering.value = event;
videoPlayerServiceHandler.onStatusChange( videoPlayerServiceHandler.onStatusChange(
playerStatus.status.value, event); playerStatus.status.value,
event,
videoType.value == 'live',
);
}), }),
// videoPlayerController!.stream.log.listen((event) { // videoPlayerController!.stream.log.listen((event) {
// debugPrint('videoPlayerController!.stream.log.listen'); // debugPrint('videoPlayerController!.stream.log.listen');
@@ -952,7 +958,11 @@ class PlPlayerController {
// }), // }),
// 媒体通知监听 // 媒体通知监听
onPlayerStatusChanged.listen((PlayerStatus event) { onPlayerStatusChanged.listen((PlayerStatus event) {
videoPlayerServiceHandler.onStatusChange(event, isBuffering.value); videoPlayerServiceHandler.onStatusChange(
event,
isBuffering.value,
videoType.value == 'live',
);
}), }),
onPositionChanged.listen((Duration event) { onPositionChanged.listen((Duration event) {
EasyThrottle.throttle( EasyThrottle.throttle(

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/models/live/room_info_h5.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:audio_service/audio_service.dart'; import 'package:audio_service/audio_service.dart';
import 'package:PiliPlus/models/bangumi/info.dart'; import 'package:PiliPlus/models/bangumi/info.dart';
@@ -66,7 +67,8 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
if (!mediaItem.isClosed) mediaItem.add(newMediaItem); if (!mediaItem.isClosed) mediaItem.add(newMediaItem);
} }
Future<void> setPlaybackState(PlayerStatus status, bool isBuffering) async { Future<void> setPlaybackState(
PlayerStatus status, bool isBuffering, bool isLive) async {
if (!enableBackgroundPlay || if (!enableBackgroundPlay ||
_item.isEmpty || _item.isEmpty ||
PlPlayerController.instanceExists().not) { PlPlayerController.instanceExists().not) {
@@ -87,11 +89,13 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
processingState: processingState:
isBuffering ? AudioProcessingState.buffering : processingState, isBuffering ? AudioProcessingState.buffering : processingState,
controls: [ controls: [
MediaControl.rewind if (isLive.not)
.copyWith(androidIcon: 'drawable/ic_baseline_replay_10_24'), MediaControl.rewind
.copyWith(androidIcon: 'drawable/ic_baseline_replay_10_24'),
if (playing) MediaControl.pause else MediaControl.play, if (playing) MediaControl.pause else MediaControl.play,
MediaControl.fastForward if (isLive.not)
.copyWith(androidIcon: 'drawable/ic_baseline_forward_10_24'), MediaControl.fastForward
.copyWith(androidIcon: 'drawable/ic_baseline_forward_10_24'),
], ],
playing: playing, playing: playing,
systemActions: const { systemActions: const {
@@ -100,11 +104,11 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
)); ));
} }
onStatusChange(PlayerStatus status, bool isBuffering) { onStatusChange(PlayerStatus status, bool isBuffering, isLive) {
if (!enableBackgroundPlay) return; if (!enableBackgroundPlay) return;
if (_item.isEmpty) return; if (_item.isEmpty) return;
setPlaybackState(status, isBuffering); setPlaybackState(status, isBuffering, isLive);
} }
onVideoDetailChange(dynamic data, int cid, String herotag) { onVideoDetailChange(dynamic data, int cid, String herotag) {
@@ -147,6 +151,14 @@ class VideoPlayerServiceHandler extends BaseAudioHandler with SeekHandler {
duration: Duration(milliseconds: current?.duration ?? 0), duration: Duration(milliseconds: current?.duration ?? 0),
artUri: Uri.parse(data.cover ?? ""), artUri: Uri.parse(data.cover ?? ""),
); );
} else if (data is RoomInfoH5Model) {
mediaItem = MediaItem(
id: id,
title: data.roomInfo?.title ?? '',
artist: data.anchorInfo?.baseInfo?.uname ?? '',
artUri: Uri.parse(data.roomInfo?.cover ?? ''),
isLive: true,
);
} }
if (mediaItem == null) return; if (mediaItem == null) return;
// debugPrint("exist: ${PlPlayerController.instanceExists()}"); // debugPrint("exist: ${PlPlayerController.instanceExists()}");