mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-19 19:01:24 +08:00
refactor device orientation
Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
@@ -6,8 +6,6 @@ PODS:
|
||||
- FlutterMacOS
|
||||
- audio_session (0.0.1):
|
||||
- Flutter
|
||||
- auto_orientation (0.0.1):
|
||||
- Flutter
|
||||
- battery_plus (1.0.0):
|
||||
- Flutter
|
||||
- chat_bottom_container (0.0.1):
|
||||
@@ -83,6 +81,8 @@ PODS:
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
- native_device_orientation (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (6.0.3)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
@@ -114,7 +114,6 @@ DEPENDENCIES:
|
||||
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||
- audio_service (from `.symlinks/plugins/audio_service/darwin`)
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
|
||||
- battery_plus (from `.symlinks/plugins/battery_plus/ios`)
|
||||
- chat_bottom_container (from `.symlinks/plugins/chat_bottom_container/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
@@ -133,6 +132,7 @@ DEPENDENCIES:
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
- native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- saver_gallery (from `.symlinks/plugins/saver_gallery/ios`)
|
||||
@@ -160,8 +160,6 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/audio_service/darwin"
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
auto_orientation:
|
||||
:path: ".symlinks/plugins/auto_orientation/ios"
|
||||
battery_plus:
|
||||
:path: ".symlinks/plugins/battery_plus/ios"
|
||||
chat_bottom_container:
|
||||
@@ -198,6 +196,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/media_kit_native_event_loop/ios"
|
||||
media_kit_video:
|
||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||
native_device_orientation:
|
||||
:path: ".symlinks/plugins/native_device_orientation/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
permission_handler_apple:
|
||||
@@ -221,7 +221,6 @@ SPEC CHECKSUMS:
|
||||
app_links: a754cbec3c255bd4bbb4d236ecc06f28cd9a7ce8
|
||||
audio_service: aa99a6ba2ae7565996015322b0bb024e1d25c6fd
|
||||
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
|
||||
auto_orientation: a1600c9ed72e6e96982fb4e1214463343342432a
|
||||
battery_plus: b42253f6d2dde71712f8c36fef456d99121c5977
|
||||
chat_bottom_container: f1eb8323db77a87db50f361142c679f11e892d1b
|
||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||
@@ -243,6 +242,7 @@ SPEC CHECKSUMS:
|
||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||
media_kit_native_event_loop: 5fba1a849a6c87a34985f1e178a0de5bd444a0cf
|
||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||
native_device_orientation: e3580675687d5034770da198f6839ebf2122ef94
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:PiliPlus/common/widgets/scale_app.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_behavior.dart';
|
||||
import 'package:PiliPlus/http/init.dart';
|
||||
import 'package:PiliPlus/models/common/theme/theme_color_type.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/router/app_pages.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/services/download/download_service.dart';
|
||||
@@ -28,6 +29,7 @@ import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/theme_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:catcher_2/catcher_2.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -82,6 +84,10 @@ Future<void> _initAppPath() async {
|
||||
appSupportDirPath = (await getApplicationSupportDirectory()).path;
|
||||
}
|
||||
|
||||
Future<void> _initSdkInt() async {
|
||||
Utils.sdkInt = (await DeviceInfoPlugin().androidInfo).version.sdkInt;
|
||||
}
|
||||
|
||||
void main() async {
|
||||
ScaledWidgetsFlutterBinding.ensureInitialized();
|
||||
MediaKit.ensureInitialized();
|
||||
@@ -104,15 +110,8 @@ void main() async {
|
||||
|
||||
if (PlatformUtils.isMobile) {
|
||||
await Future.wait([
|
||||
SystemChrome.setPreferredOrientations(
|
||||
[
|
||||
DeviceOrientation.portraitUp,
|
||||
if (Pref.horizontalScreen) ...[
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
],
|
||||
],
|
||||
),
|
||||
if (Platform.isAndroid) _initSdkInt(),
|
||||
if (Pref.horizontalScreen) ?fullMode() else ?portraitUpMode(),
|
||||
setupServiceLocator(),
|
||||
]);
|
||||
} else if (Platform.isWindows) {
|
||||
@@ -131,12 +130,10 @@ void main() async {
|
||||
Request.setCookie();
|
||||
RequestUtils.syncHistoryStatus();
|
||||
|
||||
SmartDialog.config.toast = SmartConfigToast(
|
||||
displayType: SmartToastType.onlyRefresh,
|
||||
);
|
||||
SmartDialog.config.toast = SmartConfigToast(displayType: .onlyRefresh);
|
||||
|
||||
if (PlatformUtils.isMobile) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
SystemChrome.setEnabledSystemUIMode(.edgeToEdge);
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
const SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
|
||||
@@ -30,7 +30,6 @@ import 'package:PiliPlus/pages/video/widgets/player_focus.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/danmaku_options.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/view/view.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
@@ -92,6 +91,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
maxWidth = size.width;
|
||||
maxHeight = size.height;
|
||||
isPortrait = size.isPortrait;
|
||||
plPlayerController.screenRatio = maxHeight / maxWidth;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -169,19 +169,12 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (plPlayerController.visible = state == .resumed) {
|
||||
if (!plPlayerController.showDanmaku) {
|
||||
_liveRoomController.startLiveTimer();
|
||||
plPlayerController.showDanmaku = true;
|
||||
if (isFullScreen && Platform.isIOS) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!_liveRoomController.isPortrait.value) {
|
||||
landscape();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
} else if (state == .paused) {
|
||||
_liveRoomController.cancelLiveTimer();
|
||||
plPlayerController
|
||||
..showDanmaku = false
|
||||
@@ -353,7 +346,8 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
}
|
||||
return popScope(
|
||||
canPop: !isFullScreen && !plPlayerController.isDesktopPip,
|
||||
onPopInvokedWithResult: plPlayerController.onPopInvokedWithResult,
|
||||
onPopInvokedWithResult: (didPop, result) =>
|
||||
plPlayerController.onPopInvokedWithResult(didPop, result, isPortrait),
|
||||
child: player,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/bottom_progress_behavior.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/fullscreen_mode.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart'
|
||||
show allowRotateScreen;
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
@@ -175,14 +173,6 @@ List<SettingsModel> get playSettings => [
|
||||
setKey: SettingBoxKey.enableLongShowControl,
|
||||
defaultVal: false,
|
||||
),
|
||||
SwitchModel(
|
||||
title: '全向旋转',
|
||||
subtitle: '小屏可受重力转为临时全屏,若系统锁定旋转仍触发请关闭,关闭会影响横屏适配',
|
||||
leading: const Icon(Icons.screen_rotation_alt_outlined),
|
||||
setKey: SettingBoxKey.allowRotateScreen,
|
||||
defaultVal: true,
|
||||
onChanged: (value) => allowRotateScreen = value,
|
||||
),
|
||||
if (PlatformUtils.isMobile)
|
||||
const SwitchModel(
|
||||
title: '后台播放',
|
||||
|
||||
@@ -35,7 +35,6 @@ import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:flutter/material.dart' hide StatefulBuilder;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
@@ -69,9 +68,9 @@ List<SettingsModel> get styleSettings => [
|
||||
defaultVal: Pref.horizontalScreen,
|
||||
onChanged: (value) {
|
||||
if (value) {
|
||||
autoScreen();
|
||||
fullMode();
|
||||
} else {
|
||||
AutoOrientation.portraitUpMode();
|
||||
portraitUpMode();
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
@@ -61,7 +61,6 @@ import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
import 'package:PiliPlus/utils/storage_key.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
@@ -162,7 +161,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
|
||||
videoSourceInit();
|
||||
autoScreen();
|
||||
|
||||
addObserverMobile(this);
|
||||
}
|
||||
@@ -184,29 +182,14 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
late final ctr = videoDetailController.plPlayerController;
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
final isResume = state == .resumed;
|
||||
final ctr = videoDetailController.plPlayerController..visible = isResume;
|
||||
if (isResume) {
|
||||
if (!ctr.showDanmaku) {
|
||||
introController.startTimer();
|
||||
ctr.showDanmaku = true;
|
||||
|
||||
// 修复从后台恢复时全屏状态下屏幕方向错误的问题
|
||||
if (isFullScreen && Platform.isIOS) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// 根据视频方向重新设置屏幕方向
|
||||
final isVertical = videoDetailController.isVertical.value;
|
||||
final mode = ctr.mode;
|
||||
|
||||
if (!(mode == FullScreenMode.vertical ||
|
||||
(mode == FullScreenMode.auto && isVertical) ||
|
||||
(mode == FullScreenMode.ratio &&
|
||||
(isVertical || maxHeight / maxWidth < kScreenRatio)))) {
|
||||
landscape();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (state == AppLifecycleState.paused) {
|
||||
} else if (state == .paused) {
|
||||
introController.cancelTimer();
|
||||
ctr.showDanmaku = false;
|
||||
}
|
||||
@@ -362,9 +345,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
pgcIntroController.cancelTimer();
|
||||
}
|
||||
}
|
||||
if (!videoDetailController.horizontalScreen) {
|
||||
AutoOrientation.portraitUpMode();
|
||||
}
|
||||
|
||||
if (!videoDetailController.plPlayerController.isCloseAll) {
|
||||
videoPlayerServiceHandler?.onVideoDetailDispose(heroTag);
|
||||
if (plPlayerController != null) {
|
||||
@@ -414,7 +395,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
void didPopNext() {
|
||||
super.didPopNext();
|
||||
|
||||
if (plPlayerController?.isCloseAll ?? false) {
|
||||
if (videoDetailController.plPlayerController.isCloseAll) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,6 +453,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
maxWidth = size.width;
|
||||
maxHeight = size.height;
|
||||
videoDetailController.plPlayerController.screenRatio = maxHeight / maxWidth;
|
||||
|
||||
final shortestSide = size.shortestSide;
|
||||
final minVideoHeight = shortestSide / Style.aspectRatio16x9;
|
||||
@@ -528,34 +510,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
videoDetailController.animationController
|
||||
..removeListener(animListener)
|
||||
..addListener(animListener);
|
||||
if (PlatformUtils.isMobile && mounted && isShowing && !isFullScreen) {
|
||||
if (isPortrait) {
|
||||
showStatusBar();
|
||||
} else if (!videoDetailController.horizontalScreen) {
|
||||
hideStatusBar();
|
||||
}
|
||||
}
|
||||
if (PlatformUtils.isMobile) {
|
||||
if (!isPortrait &&
|
||||
!isFullScreen &&
|
||||
plPlayerController != null &&
|
||||
videoDetailController.autoPlay) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
plPlayerController!.triggerFullScreen(
|
||||
status: true,
|
||||
isManualFS: false,
|
||||
mode: FullScreenMode.gravity,
|
||||
);
|
||||
});
|
||||
} else if (isPortrait &&
|
||||
isFullScreen &&
|
||||
plPlayerController?.isManualFS == false &&
|
||||
plPlayerController?.controlsLock.value == false) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
plPlayerController!.triggerFullScreen(status: false);
|
||||
});
|
||||
}
|
||||
}
|
||||
return Obx(
|
||||
() {
|
||||
final isFullScreen = this.isFullScreen;
|
||||
@@ -701,15 +655,9 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailController
|
||||
.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until(
|
||||
(route) => route.isFirst,
|
||||
);
|
||||
},
|
||||
onPressed: videoDetailController
|
||||
.plPlayerController
|
||||
.onCloseAll,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1239,12 +1187,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
),
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailController.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
},
|
||||
onPressed:
|
||||
videoDetailController.plPlayerController.onCloseAll,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2174,14 +2118,11 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
}
|
||||
|
||||
void _onPopInvokedWithResult(bool didPop, result) {
|
||||
if (plPlayerController?.onPopInvokedWithResult(didPop, result) ?? false) {
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils.isMobile &&
|
||||
!videoDetailController.horizontalScreen &&
|
||||
!isPortrait) {
|
||||
verticalScreenForTwoSeconds();
|
||||
}
|
||||
videoDetailController.plPlayerController.onPopInvokedWithResult(
|
||||
didPop,
|
||||
result,
|
||||
isPortrait,
|
||||
);
|
||||
}
|
||||
|
||||
void onShowMemberPage(int? mid) {
|
||||
|
||||
@@ -35,7 +35,6 @@ import 'package:PiliPlus/pages/video/widgets/header_mixin.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/data_source.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/services/shutdown_timer_service.dart'
|
||||
show shutdownTimerService;
|
||||
@@ -1757,21 +1756,11 @@ class HeaderControlState extends State<HeaderControl>
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
if (plPlayerController.onPopInvokedWithResult(
|
||||
false,
|
||||
null,
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
if (PlatformUtils.isMobile &&
|
||||
!horizontalScreen &&
|
||||
!isPortrait) {
|
||||
verticalScreenForTwoSeconds();
|
||||
} else {
|
||||
Get.back();
|
||||
}
|
||||
},
|
||||
onPressed: () => plPlayerController.onPopInvokedWithResult(
|
||||
false,
|
||||
null,
|
||||
videoDetailCtr.isPortrait,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!plPlayerController.isDesktopPip &&
|
||||
@@ -1787,12 +1776,7 @@ class HeaderControlState extends State<HeaderControl>
|
||||
size: 15,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
videoDetailCtr.plPlayerController
|
||||
..isCloseAll = true
|
||||
..dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
},
|
||||
onPressed: plPlayerController.onCloseAll,
|
||||
),
|
||||
),
|
||||
title,
|
||||
|
||||
@@ -56,6 +56,7 @@ import 'package:get/get.dart';
|
||||
import 'package:hive_ce/hive.dart';
|
||||
import 'package:media_kit/media_kit.dart';
|
||||
import 'package:media_kit_video/media_kit_video.dart';
|
||||
import 'package:native_device_orientation/native_device_orientation.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
@@ -513,26 +514,68 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
Box video = GStorage.video;
|
||||
|
||||
bool visible = true;
|
||||
|
||||
StreamSubscription<NativeDeviceOrientation>? _orientationListener;
|
||||
|
||||
void _stopOrientationListener() {
|
||||
_orientationListener?.cancel();
|
||||
_orientationListener = null;
|
||||
}
|
||||
|
||||
void _onOrientationChanged(NativeDeviceOrientation value) {
|
||||
if (!visible) return;
|
||||
switch (value) {
|
||||
case .portraitUp:
|
||||
if (!_isVertical && controlsLock.value) return;
|
||||
if (!horizontalScreen && !_isVertical && isFullScreen.value) {
|
||||
triggerFullScreen(status: false, orientation: value);
|
||||
} else {
|
||||
portraitUpMode();
|
||||
}
|
||||
case .landscapeLeft:
|
||||
if (!horizontalScreen && !isFullScreen.value) {
|
||||
triggerFullScreen(orientation: value);
|
||||
} else {
|
||||
landscapeLeftMode();
|
||||
}
|
||||
case .landscapeRight:
|
||||
if (!horizontalScreen && !isFullScreen.value) {
|
||||
triggerFullScreen(orientation: value);
|
||||
} else {
|
||||
landscapeRightMode();
|
||||
}
|
||||
case _:
|
||||
}
|
||||
}
|
||||
|
||||
// 添加一个私有构造函数
|
||||
PlPlayerController._() {
|
||||
if (PlatformUtils.isMobile) {
|
||||
_orientationListener = NativeDeviceOrientationPlatform.instance
|
||||
.onOrientationChanged(
|
||||
useSensor: Platform.isAndroid,
|
||||
checkIsAutoRotate: mode != .gravity,
|
||||
)
|
||||
.listen(_onOrientationChanged);
|
||||
}
|
||||
|
||||
if (!Accounts.heartbeat.isLogin || Pref.historyPause) {
|
||||
enableHeart = false;
|
||||
}
|
||||
|
||||
if (Platform.isAndroid && autoPiP) {
|
||||
Utils.sdkInt.then((sdkInt) {
|
||||
if (sdkInt < 36) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
if (call.method == 'onUserLeaveHint') {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
if (Utils.sdkInt < 36) {
|
||||
Utils.channel.setMethodCallHandler((call) async {
|
||||
if (call.method == 'onUserLeaveHint') {
|
||||
if (playerStatus.isPlaying && _isCurrVideoPage) {
|
||||
enterPip();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_shouldSetPip = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_shouldSetPip = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1360,69 +1403,71 @@ class PlPlayerController with BlockConfigMixin {
|
||||
updateSubtitleStyle();
|
||||
}
|
||||
|
||||
late bool isManualFS = true;
|
||||
double screenRatio = 0.0;
|
||||
late final FullScreenMode mode = Pref.fullScreenMode;
|
||||
late final horizontalScreen = Pref.horizontalScreen;
|
||||
|
||||
// 全屏
|
||||
bool fsProcessing = false;
|
||||
bool _fsProcessing = false;
|
||||
Future<void> triggerFullScreen({
|
||||
bool status = true,
|
||||
bool inAppFullScreen = false,
|
||||
bool isManualFS = true,
|
||||
FullScreenMode? mode,
|
||||
NativeDeviceOrientation? orientation,
|
||||
}) async {
|
||||
if (isDesktopPip) return;
|
||||
if (isFullScreen.value == status) return;
|
||||
|
||||
if (fsProcessing) {
|
||||
return;
|
||||
}
|
||||
fsProcessing = true;
|
||||
if (_fsProcessing) return;
|
||||
_fsProcessing = true;
|
||||
toggleFullScreen(status);
|
||||
try {
|
||||
mode ??= this.mode;
|
||||
this.isManualFS = isManualFS;
|
||||
|
||||
if (status) {
|
||||
if (PlatformUtils.isMobile) {
|
||||
hideStatusBar();
|
||||
if (mode == FullScreenMode.none) {
|
||||
if (orientation == null && mode == .none) {
|
||||
return;
|
||||
}
|
||||
if (mode == FullScreenMode.gravity) {
|
||||
await fullAutoModeForceSensor();
|
||||
return;
|
||||
}
|
||||
late final size = MediaQuery.sizeOf(Get.context!);
|
||||
if ((mode == FullScreenMode.vertical ||
|
||||
(mode == FullScreenMode.auto && isVertical) ||
|
||||
(mode == FullScreenMode.ratio &&
|
||||
(isVertical || size.height / size.width < kScreenRatio)))) {
|
||||
await verticalScreenForTwoSeconds();
|
||||
if (orientation == null &&
|
||||
(mode == .vertical ||
|
||||
(mode == .auto && isVertical) ||
|
||||
(mode == .ratio &&
|
||||
(isVertical || screenRatio < kScreenRatio)))) {
|
||||
await portraitUpMode();
|
||||
} else {
|
||||
await landscape();
|
||||
// https://github.com/flutter/flutter/issues/73651
|
||||
// https://github.com/flutter/flutter/issues/183708
|
||||
if (Platform.isAndroid) {
|
||||
if (orientation == .landscapeRight) {
|
||||
await landscapeRightMode();
|
||||
} else {
|
||||
await landscapeLeftMode();
|
||||
}
|
||||
} else {
|
||||
if (orientation == .landscapeLeft) {
|
||||
await landscapeLeftMode();
|
||||
} else {
|
||||
await landscapeRightMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await enterDesktopFullscreen(inAppFullScreen: inAppFullScreen);
|
||||
await enterDesktopFullScreen(inAppFullScreen: inAppFullScreen);
|
||||
}
|
||||
} else {
|
||||
if (PlatformUtils.isMobile) {
|
||||
showStatusBar();
|
||||
if (mode == FullScreenMode.none) {
|
||||
if (orientation == null && mode == .none) {
|
||||
return;
|
||||
}
|
||||
if (!horizontalScreen) {
|
||||
await verticalScreenForTwoSeconds();
|
||||
} else {
|
||||
await autoScreen();
|
||||
await portraitUpMode();
|
||||
}
|
||||
} else {
|
||||
await exitDesktopFullscreen();
|
||||
await exitDesktopFullScreen();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fsProcessing = false;
|
||||
_fsProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,12 +1565,29 @@ class PlPlayerController with BlockConfigMixin {
|
||||
});
|
||||
}
|
||||
|
||||
bool isCloseAll = false;
|
||||
bool _isCloseAll = false;
|
||||
bool get isCloseAll => _isCloseAll;
|
||||
|
||||
void resetScreenRotation() {
|
||||
if (horizontalScreen) {
|
||||
fullMode();
|
||||
} else {
|
||||
portraitUpMode();
|
||||
}
|
||||
}
|
||||
|
||||
void onCloseAll() {
|
||||
_isCloseAll = true;
|
||||
dispose();
|
||||
Get.until((route) => route.isFirst);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
// 每次减1,最后销毁
|
||||
resetScreenRotation();
|
||||
cancelLongPressTimer();
|
||||
_cancelSubForSeek();
|
||||
if (!isCloseAll && _playerCount > 1) {
|
||||
if (!_isCloseAll && _playerCount > 1) {
|
||||
_playerCount -= 1;
|
||||
_heartDuration = 0;
|
||||
if (!_isPreviousVideoPage) {
|
||||
@@ -1536,6 +1598,7 @@ class PlPlayerController with BlockConfigMixin {
|
||||
|
||||
_playerCount = 0;
|
||||
danmakuController = null;
|
||||
_stopOrientationListener();
|
||||
_disableAutoEnterPip();
|
||||
setPlayCallBack(null);
|
||||
dmState.clear();
|
||||
@@ -1683,25 +1746,27 @@ class PlPlayerController with BlockConfigMixin {
|
||||
});
|
||||
}
|
||||
|
||||
bool onPopInvokedWithResult(bool didPop, Object? result) {
|
||||
void onPopInvokedWithResult(bool didPop, Object? result, bool isPortrait) {
|
||||
if (didPop) {
|
||||
if (Platform.isAndroid) {
|
||||
_disableAutoEnterPipIfNeeded();
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (controlsLock.value) {
|
||||
onLockControl(false);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (isDesktopPip) {
|
||||
exitDesktopPip();
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (isFullScreen.value) {
|
||||
triggerFullScreen(status: false);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (!horizontalScreen && !isPortrait) {
|
||||
Get.back();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:auto_orientation/auto_orientation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/services.dart'
|
||||
show SystemChrome, MethodChannel, SystemUiOverlay, DeviceOrientation;
|
||||
|
||||
bool _isDesktopFullScreen = false;
|
||||
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> enterDesktopFullscreen({bool inAppFullScreen = false}) async {
|
||||
Future<void> enterDesktopFullScreen({bool inAppFullScreen = false}) async {
|
||||
if (!inAppFullScreen && !_isDesktopFullScreen) {
|
||||
_isDesktopFullScreen = true;
|
||||
try {
|
||||
@@ -22,7 +20,7 @@ Future<void> enterDesktopFullscreen({bool inAppFullScreen = false}) async {
|
||||
}
|
||||
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> exitDesktopFullscreen() async {
|
||||
Future<void> exitDesktopFullScreen() async {
|
||||
if (_isDesktopFullScreen) {
|
||||
_isDesktopFullScreen = false;
|
||||
try {
|
||||
@@ -33,60 +31,50 @@ Future<void> exitDesktopFullscreen() async {
|
||||
}
|
||||
}
|
||||
|
||||
//横屏
|
||||
@pragma('vm:notify-debugger-on-exception')
|
||||
Future<void> landscape() async {
|
||||
try {
|
||||
await AutoOrientation.landscapeAutoMode(forceSensor: true);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
//竖屏
|
||||
Future<void> verticalScreenForTwoSeconds() async {
|
||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
await autoScreen();
|
||||
}
|
||||
|
||||
//全向
|
||||
bool allowRotateScreen = Pref.allowRotateScreen;
|
||||
Future<void> autoScreen() async {
|
||||
if (PlatformUtils.isMobile && allowRotateScreen) {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
// DeviceOrientation.portraitDown,
|
||||
DeviceOrientation.landscapeLeft,
|
||||
DeviceOrientation.landscapeRight,
|
||||
]);
|
||||
List<DeviceOrientation>? _lastOrientation;
|
||||
Future<void>? _setPreferredOrientations(List<DeviceOrientation> orientations) {
|
||||
if (_lastOrientation == orientations) {
|
||||
return null;
|
||||
}
|
||||
_lastOrientation = orientations;
|
||||
return SystemChrome.setPreferredOrientations(orientations);
|
||||
}
|
||||
|
||||
Future<void> fullAutoModeForceSensor() {
|
||||
return AutoOrientation.fullAutoMode(forceSensor: true);
|
||||
Future<void>? portraitUpMode() {
|
||||
return _setPreferredOrientations(const [.portraitUp]);
|
||||
}
|
||||
|
||||
Future<void>? landscapeLeftMode() {
|
||||
return _setPreferredOrientations(const [.landscapeLeft]);
|
||||
}
|
||||
|
||||
Future<void>? landscapeRightMode() {
|
||||
return _setPreferredOrientations(const [.landscapeRight]);
|
||||
}
|
||||
|
||||
Future<void>? fullMode() {
|
||||
return _setPreferredOrientations(
|
||||
const [.portraitUp, .landscapeLeft, .landscapeRight],
|
||||
);
|
||||
}
|
||||
|
||||
bool _showStatusBar = true;
|
||||
Future<void> hideStatusBar() async {
|
||||
Future<void>? hideStatusBar() {
|
||||
if (!_showStatusBar) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
_showStatusBar = false;
|
||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||
return SystemChrome.setEnabledSystemUIMode(.immersiveSticky);
|
||||
}
|
||||
|
||||
//退出全屏显示
|
||||
Future<void> showStatusBar() async {
|
||||
Future<void>? showStatusBar() {
|
||||
if (_showStatusBar) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
_showStatusBar = true;
|
||||
SystemUiMode mode;
|
||||
if (Platform.isAndroid && (await Utils.sdkInt < 29)) {
|
||||
mode = SystemUiMode.manual;
|
||||
} else {
|
||||
mode = SystemUiMode.edgeToEdge;
|
||||
}
|
||||
await SystemChrome.setEnabledSystemUIMode(
|
||||
mode,
|
||||
return SystemChrome.setEnabledSystemUIMode(
|
||||
Platform.isAndroid && Utils.sdkInt < 29 ? .manual : .edgeToEdge,
|
||||
overlays: SystemUiOverlay.values,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -300,10 +300,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (!plPlayerController.continuePlayInBackground.value) {
|
||||
late final player = plPlayerController.videoPlayerController;
|
||||
if (const [
|
||||
AppLifecycleState.paused,
|
||||
AppLifecycleState.detached,
|
||||
].contains(state)) {
|
||||
if (const <AppLifecycleState>[.paused, .detached].contains(state)) {
|
||||
if (player != null && player.state.playing) {
|
||||
_pauseDueToPauseUponEnteringBackgroundMode = true;
|
||||
player.pause();
|
||||
|
||||
@@ -78,12 +78,12 @@ abstract final class ImageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> checkPermissionDependOnSdkInt() async {
|
||||
static Future<bool> checkPermissionDependOnSdkInt() {
|
||||
if (Platform.isAndroid) {
|
||||
if (await Utils.sdkInt < 29) {
|
||||
if (Utils.sdkInt < 29) {
|
||||
return requestPer();
|
||||
} else {
|
||||
return true;
|
||||
return Future.syncValue(true);
|
||||
}
|
||||
}
|
||||
return requestPer();
|
||||
|
||||
@@ -32,7 +32,6 @@ abstract final class SettingBoxKey {
|
||||
static const String enableVerticalExpand = 'enableVerticalExpand',
|
||||
feedBackEnable = 'feedBackEnable',
|
||||
enableLongShowControl = 'enableLongShowControl',
|
||||
allowRotateScreen = 'allowRotateScreen',
|
||||
horizontalScreen = 'horizontalScreen',
|
||||
CDNService = 'CDNService',
|
||||
disableAudioCDN = 'disableAudioCDN',
|
||||
|
||||
@@ -193,7 +193,9 @@ abstract final class Pref {
|
||||
static FullScreenMode get fullScreenMode =>
|
||||
FullScreenMode.values[_setting.get(
|
||||
SettingBoxKey.fullScreenMode,
|
||||
defaultValue: FullScreenMode.auto.index,
|
||||
defaultValue: horizontalScreen
|
||||
? FullScreenMode.none.index
|
||||
: FullScreenMode.auto.index,
|
||||
)];
|
||||
|
||||
static BtmProgressBehavior get btmProgressBehavior =>
|
||||
@@ -636,9 +638,6 @@ abstract final class Pref {
|
||||
static bool get enableBackgroundPlay =>
|
||||
_setting.get(SettingBoxKey.enableBackgroundPlay, defaultValue: true);
|
||||
|
||||
static bool get allowRotateScreen =>
|
||||
_setting.get(SettingBoxKey.allowRotateScreen, defaultValue: true);
|
||||
|
||||
static bool get disableLikeMsg =>
|
||||
_setting.get(SettingBoxKey.disableLikeMsg, defaultValue: false);
|
||||
|
||||
|
||||
@@ -87,10 +87,7 @@ abstract final class Utils {
|
||||
int.parse('${color.substring(7)}${color.substring(1, 7)}', radix: 16),
|
||||
);
|
||||
|
||||
static int? _sdkInt;
|
||||
static Future<int> get sdkInt async {
|
||||
return _sdkInt ??= (await DeviceInfoPlugin().androidInfo).version.sdkInt;
|
||||
}
|
||||
static late int sdkInt;
|
||||
|
||||
static bool? _isIpad;
|
||||
static Future<bool> get isIpad async {
|
||||
|
||||
18
pubspec.lock
18
pubspec.lock
@@ -121,15 +121,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
auto_orientation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: ca2bb137bd0e4b221df3bc5ba1492d2902c78624
|
||||
url: "https://github.com/bggRGjQaUbCoE/auto_orientation.git"
|
||||
source: git
|
||||
version: "2.3.1"
|
||||
battery_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1239,6 +1230,15 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
native_device_orientation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: "42454199133e83a9a31f0fb0107d14af1f96f959"
|
||||
url: "https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git"
|
||||
source: git
|
||||
version: "2.0.5"
|
||||
native_toolchain_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -126,9 +126,13 @@ dependencies:
|
||||
flutter_volume_controller: ^1.3.3
|
||||
wakelock_plus: ^1.2.8
|
||||
# universal_platform: ^1.1.0
|
||||
auto_orientation:
|
||||
# auto_orientation:
|
||||
# git:
|
||||
# url: https://github.com/bggRGjQaUbCoE/auto_orientation.git
|
||||
# ref: master
|
||||
native_device_orientation:
|
||||
git:
|
||||
url: https://github.com/bggRGjQaUbCoE/auto_orientation.git
|
||||
url: https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git
|
||||
ref: master
|
||||
protobuf: ^6.0.0
|
||||
# animations: ^2.0.11
|
||||
|
||||
Reference in New Issue
Block a user