feat: 新增媒体通知

This commit is contained in:
Riri
2023-10-25 16:27:14 +08:00
parent eda8a5c6a7
commit 0a5dea0535
16 changed files with 235 additions and 21 deletions

View File

@ -0,0 +1,116 @@
import 'package:audio_service/audio_service.dart';
import 'package:pilipala/models/video_detail_res.dart';
import 'package:get/get.dart';
import 'package:pilipala/plugin/pl_player/index.dart';
Future<VideoPlayerServiceHandler> initAudioService() async {
return await AudioService.init(
builder: () => VideoPlayerServiceHandler(),
config: const AudioServiceConfig(
androidNotificationChannelId: 'com.guozhigq.pilipala.audio',
androidNotificationChannelName: 'Audio Service Pilipala',
androidNotificationOngoing: true,
androidStopForegroundOnPause: true,
fastForwardInterval: Duration(seconds: 10),
rewindInterval: Duration(seconds: 10),
androidNotificationChannelDescription: 'Media notification channel',
),
);
}
class VideoPlayerServiceHandler extends BaseAudioHandler
with QueueHandler, SeekHandler {
static final List<MediaItem> _item = [];
@override
Future<void> play() async {
PlPlayerController.getInstance().play();
}
@override
Future<void> pause() async {
PlPlayerController.getInstance().pause();
}
@override
Future<void> seek(Duration position) async {
playbackState.add(playbackState.value.copyWith(
updatePosition: position,
));
await PlPlayerController.getInstance().seekTo(position);
}
Future<void> setMediaItem(MediaItem newMediaItem) async {
mediaItem.add(newMediaItem);
addQueueItem(newMediaItem);
}
Future<void> setPlaybackState(PlayerStatus status, bool isBuffering) async {
final AudioProcessingState processingState;
final playing = status == PlayerStatus.playing;
if (status == PlayerStatus.completed) {
processingState = AudioProcessingState.completed;
} else if (isBuffering) {
processingState = AudioProcessingState.buffering;
} else {
processingState = AudioProcessingState.ready;
}
playbackState.add(playbackState.value.copyWith(
processingState:
isBuffering ? AudioProcessingState.buffering : processingState,
controls: [
MediaControl.rewind.copyWith(androidIcon: 'drawable/ic_stat_replay_10'),
if (playing) MediaControl.pause else MediaControl.play,
MediaControl.fastForward
.copyWith(androidIcon: 'drawable/ic_stat_forward_10'),
],
playing: playing,
systemActions: const {
MediaAction.seek,
},
));
}
onStatusChange(PlayerStatus status, bool isBuffering) {
if (_item.isEmpty) return;
setPlaybackState(status, isBuffering);
}
onVideoIntroChange(VideoDetailData data) {
Map argMap = Get.arguments;
final heroTag = argMap['heroTag'];
final mediaItem = MediaItem(
id: heroTag,
title: data.title ?? "",
artist: data.owner?.name ?? "",
duration: Duration(seconds: data.duration ?? 0),
artUri: Uri.parse(data.pic ?? ""),
);
setMediaItem(mediaItem);
_item.add(mediaItem);
}
onVideoIntroDispose() {
playbackState.add(playbackState.value.copyWith(
processingState: AudioProcessingState.idle,
playing: false,
));
stop();
_item.removeLast();
if (_item.isNotEmpty) {
setMediaItem(_item.last);
}
if (_item.isEmpty) {
playbackState
.add(playbackState.value.copyWith(updatePosition: Duration.zero));
}
}
onPositionChange(Duration position) {
playbackState.add(playbackState.value.copyWith(
updatePosition: position,
));
}
}

View File

@ -0,0 +1,8 @@
import 'audio_handler.dart';
late VideoPlayerServiceHandler videoPlayerServiceHandler;
Future<void> setupServiceLocator() async {
final audio = await initAudioService();
videoPlayerServiceHandler = audio;
}