mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
mod: close listener on dispose
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -43,6 +45,7 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
|
||||
late BangumiIntroController bangumiIntroController;
|
||||
late VideoDetailController videoDetailCtr;
|
||||
late int cid;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
// 添加页面缓存
|
||||
@override
|
||||
@@ -55,13 +58,19 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
|
||||
bangumiIntroController =
|
||||
Get.put(BangumiIntroController(), tag: widget.heroTag);
|
||||
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||
videoDetailCtr.cid.listen((int p0) {
|
||||
_listener = videoDetailCtr.cid.listen((int p0) {
|
||||
cid = p0;
|
||||
if (!mounted) return;
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
@@ -140,6 +149,8 @@ class _BangumiInfoState extends State<BangumiInfo>
|
||||
late final _coinKey = GlobalKey<ActionItemState>();
|
||||
late final _favKey = GlobalKey<ActionItemState>();
|
||||
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -149,13 +160,19 @@ class _BangumiInfoState extends State<BangumiInfo>
|
||||
bangumiItem = bangumiIntroController.bangumiItem;
|
||||
cid = widget.cid!;
|
||||
debugPrint('cid: $cid');
|
||||
videoDetailCtr.cid.listen((p0) {
|
||||
_listener = videoDetailCtr.cid.listen((p0) {
|
||||
cid = p0;
|
||||
if (!mounted) return;
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 收藏
|
||||
showFavBottomSheet() {
|
||||
if (bangumiIntroController.userInfo == null) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPalaX/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -41,6 +43,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
late int cid;
|
||||
late final VideoDetailController videoDetailCtr;
|
||||
final ItemScrollController itemScrollController = ItemScrollController();
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -54,7 +57,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
}
|
||||
videoDetailCtr = Get.find<VideoDetailController>(tag: widget.heroTag);
|
||||
|
||||
videoDetailCtr.cid.listen((int p0) {
|
||||
_listener = videoDetailCtr.cid.listen((int p0) {
|
||||
cid = p0;
|
||||
currentIndex = widget.pages.indexWhere((EpisodeItem e) => e.cid == cid);
|
||||
if (!mounted) return;
|
||||
@@ -65,6 +68,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
listViewScrollCtr.dispose();
|
||||
listViewScrollCtr_2.dispose();
|
||||
super.dispose();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -33,6 +35,8 @@ class _PlDanmakuState extends State<PlDanmaku> {
|
||||
late bool enableShowDanmaku;
|
||||
int latestAddedPosition = -1;
|
||||
bool? _isFullScreen;
|
||||
StreamSubscription? _listenerDanmaku;
|
||||
StreamSubscription? _listenerFS;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -55,14 +59,14 @@ class _PlDanmakuState extends State<PlDanmaku> {
|
||||
..addStatusLister(playerListener)
|
||||
..addPositionListener(videoPositionListen);
|
||||
}
|
||||
playerController.isOpenDanmu.listen((p0) {
|
||||
_listenerDanmaku = playerController.isOpenDanmu.listen((p0) {
|
||||
if (p0 && !_plDanmakuController.initiated) {
|
||||
_plDanmakuController.initiate(
|
||||
playerController.duration.value.inMilliseconds,
|
||||
playerController.position.value.inMilliseconds);
|
||||
}
|
||||
});
|
||||
playerController.isFullScreen.listen((isFullScreen) {
|
||||
_listenerFS = playerController.isFullScreen.listen((isFullScreen) {
|
||||
if (isFullScreen != _isFullScreen) {
|
||||
_isFullScreen = isFullScreen;
|
||||
if (_controller != null) {
|
||||
@@ -119,6 +123,8 @@ class _PlDanmakuState extends State<PlDanmaku> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listenerDanmaku?.cancel();
|
||||
_listenerFS?.cancel();
|
||||
playerController.removePositionListener(videoPositionListen);
|
||||
playerController.removeStatusLister(playerListener);
|
||||
_plDanmakuController.dispose();
|
||||
|
||||
@@ -33,6 +33,7 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
|
||||
late DynamicsTabController _dynamicsTabController;
|
||||
late bool dynamicsWaterfallFlow;
|
||||
late final DynamicsController dynamicsController;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
@@ -61,7 +62,7 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
|
||||
searchBarStream.add(false);
|
||||
}
|
||||
});
|
||||
dynamicsController.mid.listen((mid) {
|
||||
_listener = dynamicsController.mid.listen((mid) {
|
||||
// debugPrint('midListen: $mid');
|
||||
_dynamicsTabController.mid = mid;
|
||||
_dynamicsTabController.scrollController.jumpTo(0);
|
||||
@@ -73,6 +74,7 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
_dynamicsTabController.scrollController.removeListener(() {});
|
||||
dynamicsController.mid.close();
|
||||
super.dispose();
|
||||
|
||||
@@ -40,6 +40,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
late Future _futureBuilderFutureUp;
|
||||
Box userInfoCache = GStorage.userInfo;
|
||||
late UpPanelPosition upPanelPosition;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
@@ -91,7 +92,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
// .onSelectType(_dynamicsController.tabController.index);
|
||||
// }
|
||||
// });
|
||||
_dynamicsController.userLogin.listen((status) {
|
||||
_listener = _dynamicsController.userLogin.listen((status) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_futureBuilderFutureUp = _dynamicsController.queryFollowUp();
|
||||
@@ -118,6 +119,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
_dynamicsController.tabController.removeListener(() {});
|
||||
_dynamicsController.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:PiliPalaX/http/live.dart';
|
||||
@@ -39,6 +40,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
late final _isLogin = GStorage.userInfo.get('userInfoCache') != null;
|
||||
late final _node = FocusNode();
|
||||
late final _ctr = TextEditingController();
|
||||
StreamSubscription? _listener;
|
||||
|
||||
int latestAddedPosition = -1;
|
||||
bool? _isFullScreen;
|
||||
@@ -61,7 +63,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
_futureBuilderFuture = _liveRoomController.queryLiveInfo();
|
||||
plPlayerController.autoEnterFullscreen();
|
||||
_liveRoomController.liveMsg();
|
||||
plPlayerController.isFullScreen.listen((isFullScreen) {
|
||||
_listener = plPlayerController.isFullScreen.listen((isFullScreen) {
|
||||
if (isFullScreen != _isFullScreen) {
|
||||
_isFullScreen = isFullScreen;
|
||||
_updateFontSize();
|
||||
@@ -101,6 +103,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
ScreenBrightness().resetApplicationScreenBrightness();
|
||||
PlPlayerController.setPlayCallBack(null);
|
||||
|
||||
@@ -21,6 +21,7 @@ class MediaPage extends StatefulWidget {
|
||||
class _MediaPageState extends State<MediaPage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
late MediaController mediaController;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
@@ -32,7 +33,7 @@ class _MediaPageState extends State<MediaPage>
|
||||
StreamController<bool> mainStream =
|
||||
Get.find<MainController>().bottomBarStream;
|
||||
|
||||
mediaController.userLogin.listen((status) {
|
||||
_listener = mediaController.userLogin.listen((status) {
|
||||
mediaController.onReload();
|
||||
});
|
||||
mediaController.scrollController.addListener(
|
||||
@@ -50,6 +51,7 @@ class _MediaPageState extends State<MediaPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
mediaController.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPalaX/utils/storage.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -19,13 +21,14 @@ class _MinePageState extends State<MinePage> {
|
||||
final MineController mineController = Get.put(MineController())
|
||||
..themeType.value = ThemeType.values[GStorage.themeType];
|
||||
late Future _futureBuilderFuture;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_futureBuilderFuture = mineController.queryUserInfo();
|
||||
|
||||
mineController.userLogin.listen((status) {
|
||||
_listener = mineController.userLogin.listen((status) {
|
||||
if (mounted) {
|
||||
_futureBuilderFuture = mineController.queryUserInfo();
|
||||
_futureBuilderFuture.then((value) => setState(() {}));
|
||||
@@ -33,6 +36,12 @@ class _MinePageState extends State<MinePage> {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget get _header => FittedBox(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPalaX/common/widgets/self_sized_horizontal_list.dart';
|
||||
import 'package:PiliPalaX/pages/search/widgets/search_text.dart';
|
||||
import 'package:PiliPalaX/utils/extension.dart';
|
||||
@@ -50,7 +52,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
late String heroTag;
|
||||
late VideoIntroController videoIntroController;
|
||||
VideoDetailData? videoDetail;
|
||||
// late Future? _futureBuilderFuture;
|
||||
StreamSubscription? _listener;
|
||||
|
||||
// 添加页面缓存
|
||||
@override
|
||||
@@ -68,11 +70,17 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||
videoIntroController = Get.put(VideoIntroController(), tag: heroTag)
|
||||
..heroTag = heroTag;
|
||||
// _futureBuilderFuture = videoIntroController.queryVideoIntro();
|
||||
videoIntroController.videoDetail.listen((value) {
|
||||
_listener = videoIntroController.videoDetail.listen((value) {
|
||||
videoDetail = value;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -35,6 +36,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
late final String heroTag;
|
||||
late VideoDetailController _videoDetailController;
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
StreamSubscription? _listener;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -43,7 +45,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
heroTag = widget.heroTag;
|
||||
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
|
||||
pageIndex = widget.pages.indexWhere((Part e) => e.cid == cid);
|
||||
_videoDetailController.cid.listen((int p0) {
|
||||
_listener = _videoDetailController.cid.listen((int p0) {
|
||||
cid = p0;
|
||||
pageIndex = max(0, widget.pages.indexWhere((Part e) => e.cid == cid));
|
||||
if (!mounted) return;
|
||||
@@ -61,6 +63,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -98,6 +98,10 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
context.orientation == Orientation.landscape &&
|
||||
videoDetailController.horizontalSeasonPanel;
|
||||
|
||||
StreamSubscription? _listenerDetail;
|
||||
StreamSubscription? _listenerLoadingState;
|
||||
StreamSubscription? _listenerCid;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -114,14 +118,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
tag: heroTag);
|
||||
}
|
||||
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
||||
videoIntroController.videoDetail.listen((value) {
|
||||
_listenerDetail = videoIntroController.videoDetail.listen((value) {
|
||||
if (!context.mounted) return;
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
value, videoDetailController.cid.value);
|
||||
});
|
||||
if (videoDetailController.videoType == SearchType.media_bangumi) {
|
||||
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
|
||||
bangumiIntroController.loadingState.listen((value) {
|
||||
_listenerLoadingState =
|
||||
bangumiIntroController.loadingState.listen((value) {
|
||||
if (!context.mounted) return;
|
||||
if (value is Success) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
@@ -130,7 +135,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
);
|
||||
}
|
||||
});
|
||||
videoDetailController.cid.listen((p0) {
|
||||
_listenerCid = videoDetailController.cid.listen((p0) {
|
||||
if (!context.mounted) return;
|
||||
if (bangumiIntroController.loadingState.value is Success) {
|
||||
videoPlayerServiceHandler.onVideoDetailChange(
|
||||
@@ -323,6 +328,9 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listenerDetail?.cancel();
|
||||
_listenerLoadingState?.cancel();
|
||||
_listenerCid?.cancel();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
if (!Get.previousRoute.startsWith('/video')) {
|
||||
ScreenBrightness().resetApplicationScreenBrightness();
|
||||
|
||||
@@ -681,115 +681,113 @@ class PlPlayerController {
|
||||
|
||||
/// 播放事件监听
|
||||
void startListeners() {
|
||||
subscriptions.addAll(
|
||||
[
|
||||
videoPlayerController!.stream.playing.listen((event) {
|
||||
if (event) {
|
||||
playerStatus.status.value = PlayerStatus.playing;
|
||||
} else {
|
||||
playerStatus.status.value = PlayerStatus.paused;
|
||||
}
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value, isBuffering.value);
|
||||
subscriptions = [
|
||||
videoPlayerController!.stream.playing.listen((event) {
|
||||
if (event) {
|
||||
playerStatus.status.value = PlayerStatus.playing;
|
||||
} else {
|
||||
playerStatus.status.value = PlayerStatus.paused;
|
||||
}
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value, isBuffering.value);
|
||||
|
||||
/// 触发回调事件
|
||||
for (var element in _statusListeners) {
|
||||
element(event ? PlayerStatus.playing : PlayerStatus.paused);
|
||||
}
|
||||
if (videoPlayerController!.state.position.inSeconds != 0) {
|
||||
makeHeartBeat(positionSeconds.value, type: 'status');
|
||||
}
|
||||
}),
|
||||
videoPlayerController!.stream.completed.listen((event) {
|
||||
if (event) {
|
||||
playerStatus.status.value = PlayerStatus.completed;
|
||||
|
||||
/// 触发回调事件
|
||||
for (var element in _statusListeners) {
|
||||
element(event ? PlayerStatus.playing : PlayerStatus.paused);
|
||||
element(PlayerStatus.completed);
|
||||
}
|
||||
if (videoPlayerController!.state.position.inSeconds != 0) {
|
||||
makeHeartBeat(positionSeconds.value, type: 'status');
|
||||
}
|
||||
}),
|
||||
videoPlayerController!.stream.completed.listen((event) {
|
||||
if (event) {
|
||||
playerStatus.status.value = PlayerStatus.completed;
|
||||
} else {
|
||||
// playerStatus.status.value = PlayerStatus.playing;
|
||||
}
|
||||
makeHeartBeat(positionSeconds.value, type: 'completed');
|
||||
}),
|
||||
videoPlayerController!.stream.position.listen((event) {
|
||||
_position.value = event;
|
||||
updatePositionSecond();
|
||||
if (!isSliderMoving.value) {
|
||||
_sliderPosition.value = event;
|
||||
updateSliderPositionSecond();
|
||||
}
|
||||
|
||||
/// 触发回调事件
|
||||
for (var element in _statusListeners) {
|
||||
element(PlayerStatus.completed);
|
||||
}
|
||||
} else {
|
||||
// playerStatus.status.value = PlayerStatus.playing;
|
||||
}
|
||||
makeHeartBeat(positionSeconds.value, type: 'completed');
|
||||
}),
|
||||
videoPlayerController!.stream.position.listen((event) {
|
||||
_position.value = event;
|
||||
updatePositionSecond();
|
||||
if (!isSliderMoving.value) {
|
||||
_sliderPosition.value = event;
|
||||
updateSliderPositionSecond();
|
||||
}
|
||||
|
||||
/// 触发回调事件
|
||||
for (var element in _positionListeners) {
|
||||
element(event);
|
||||
}
|
||||
makeHeartBeat(event.inSeconds);
|
||||
}),
|
||||
videoPlayerController!.stream.duration.listen((Duration event) {
|
||||
duration.value = event;
|
||||
}),
|
||||
videoPlayerController!.stream.buffer.listen((Duration event) {
|
||||
_buffered.value = event;
|
||||
updateBufferedSecond();
|
||||
}),
|
||||
videoPlayerController!.stream.buffering.listen((bool event) {
|
||||
isBuffering.value = event;
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value, event);
|
||||
}),
|
||||
// videoPlayerController!.stream.log.listen((event) {
|
||||
// debugPrint('videoPlayerController!.stream.log.listen');
|
||||
// debugPrint(event);
|
||||
// SmartDialog.showToast('视频加载日志: $event');
|
||||
// }),
|
||||
videoPlayerController!.stream.error.listen((String event) {
|
||||
// 直播的错误提示没有参考价值,均不予显示
|
||||
if (videoType.value == 'live') return;
|
||||
if (event.startsWith("Failed to open https://") ||
|
||||
event.startsWith("Can not open external file https://") ||
|
||||
//tcp: ffurl_read returned 0xdfb9b0bb
|
||||
//tcp: ffurl_read returned 0xffffff99
|
||||
event.startsWith('tcp: ffurl_read returned ')) {
|
||||
EasyThrottle.throttle('videoPlayerController!.stream.error.listen',
|
||||
const Duration(milliseconds: 10000), () {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () {
|
||||
debugPrint("isBuffering.value: ${isBuffering.value}");
|
||||
debugPrint("_buffered.value: ${_buffered.value}");
|
||||
if (isBuffering.value && _buffered.value == Duration.zero) {
|
||||
refreshPlayer();
|
||||
SmartDialog.showToast('视频链接打开失败,重试中',
|
||||
displayTime: const Duration(milliseconds: 500));
|
||||
}
|
||||
});
|
||||
/// 触发回调事件
|
||||
for (var element in _positionListeners) {
|
||||
element(event);
|
||||
}
|
||||
makeHeartBeat(event.inSeconds);
|
||||
}),
|
||||
videoPlayerController!.stream.duration.listen((Duration event) {
|
||||
duration.value = event;
|
||||
}),
|
||||
videoPlayerController!.stream.buffer.listen((Duration event) {
|
||||
_buffered.value = event;
|
||||
updateBufferedSecond();
|
||||
}),
|
||||
videoPlayerController!.stream.buffering.listen((bool event) {
|
||||
isBuffering.value = event;
|
||||
videoPlayerServiceHandler.onStatusChange(
|
||||
playerStatus.status.value, event);
|
||||
}),
|
||||
// videoPlayerController!.stream.log.listen((event) {
|
||||
// debugPrint('videoPlayerController!.stream.log.listen');
|
||||
// debugPrint(event);
|
||||
// SmartDialog.showToast('视频加载日志: $event');
|
||||
// }),
|
||||
videoPlayerController!.stream.error.listen((String event) {
|
||||
// 直播的错误提示没有参考价值,均不予显示
|
||||
if (videoType.value == 'live') return;
|
||||
if (event.startsWith("Failed to open https://") ||
|
||||
event.startsWith("Can not open external file https://") ||
|
||||
//tcp: ffurl_read returned 0xdfb9b0bb
|
||||
//tcp: ffurl_read returned 0xffffff99
|
||||
event.startsWith('tcp: ffurl_read returned ')) {
|
||||
EasyThrottle.throttle('videoPlayerController!.stream.error.listen',
|
||||
const Duration(milliseconds: 10000), () {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () {
|
||||
debugPrint("isBuffering.value: ${isBuffering.value}");
|
||||
debugPrint("_buffered.value: ${_buffered.value}");
|
||||
if (isBuffering.value && _buffered.value == Duration.zero) {
|
||||
refreshPlayer();
|
||||
SmartDialog.showToast('视频链接打开失败,重试中',
|
||||
displayTime: const Duration(milliseconds: 500));
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
debugPrint('videoPlayerController!.stream.error.listen: ');
|
||||
if (event.startsWith('Could not open codec')) {
|
||||
SmartDialog.showToast('无法加载解码器, $event,可能会切换至软解');
|
||||
return;
|
||||
}
|
||||
SmartDialog.showToast('视频加载错误, $event');
|
||||
}),
|
||||
// videoPlayerController!.stream.volume.listen((event) {
|
||||
// if (!mute.value && _volumeBeforeMute != event) {
|
||||
// _volumeBeforeMute = event / 100;
|
||||
// }
|
||||
// }),
|
||||
// 媒体通知监听
|
||||
onPlayerStatusChanged.listen((PlayerStatus event) {
|
||||
videoPlayerServiceHandler.onStatusChange(event, isBuffering.value);
|
||||
}),
|
||||
onPositionChanged.listen((Duration event) {
|
||||
EasyThrottle.throttle(
|
||||
'mediaServicePosition',
|
||||
const Duration(seconds: 1),
|
||||
() => videoPlayerServiceHandler.onPositionChange(event));
|
||||
}),
|
||||
],
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
debugPrint('videoPlayerController!.stream.error.listen: ');
|
||||
if (event.startsWith('Could not open codec')) {
|
||||
SmartDialog.showToast('无法加载解码器, $event,可能会切换至软解');
|
||||
return;
|
||||
}
|
||||
SmartDialog.showToast('视频加载错误, $event');
|
||||
}),
|
||||
// videoPlayerController!.stream.volume.listen((event) {
|
||||
// if (!mute.value && _volumeBeforeMute != event) {
|
||||
// _volumeBeforeMute = event / 100;
|
||||
// }
|
||||
// }),
|
||||
// 媒体通知监听
|
||||
onPlayerStatusChanged.listen((PlayerStatus event) {
|
||||
videoPlayerServiceHandler.onStatusChange(event, isBuffering.value);
|
||||
}),
|
||||
onPositionChanged.listen((Duration event) {
|
||||
EasyThrottle.throttle(
|
||||
'mediaServicePosition',
|
||||
const Duration(seconds: 1),
|
||||
() => videoPlayerServiceHandler.onPositionChange(event));
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/// 移除事件监听
|
||||
|
||||
@@ -146,6 +146,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
}
|
||||
}
|
||||
|
||||
StreamSubscription? _listener;
|
||||
StreamSubscription? _listenerFS;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -178,7 +181,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
Future.microtask(() async {
|
||||
try {
|
||||
_brightnessValue.value = await ScreenBrightness().application;
|
||||
ScreenBrightness()
|
||||
_listener = ScreenBrightness()
|
||||
.onApplicationScreenBrightnessChanged
|
||||
.listen((double value) {
|
||||
if (mounted) {
|
||||
@@ -222,6 +225,8 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_listener?.cancel();
|
||||
_listenerFS?.cancel();
|
||||
animationController.dispose();
|
||||
FlutterVolumeController.removeListener();
|
||||
super.dispose();
|
||||
@@ -578,15 +583,13 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (isFullScreen) {
|
||||
plPlayerController.subtitleFontScaleFS.listen((value) {
|
||||
_updateSubtitle(value);
|
||||
});
|
||||
} else {
|
||||
plPlayerController.subtitleFontScale.listen((value) {
|
||||
_updateSubtitle(value);
|
||||
});
|
||||
}
|
||||
_listenerFS = isFullScreen
|
||||
? plPlayerController.subtitleFontScaleFS.listen((value) {
|
||||
_updateSubtitle(value);
|
||||
})
|
||||
: _listenerFS = plPlayerController.subtitleFontScale.listen((value) {
|
||||
_updateSubtitle(value);
|
||||
});
|
||||
final Color colorTheme = Theme.of(context).colorScheme.primary;
|
||||
const TextStyle textStyle = TextStyle(
|
||||
color: Colors.white,
|
||||
|
||||
Reference in New Issue
Block a user