feat: 可否增加打开视频自动全屏的功能 issues #37
This commit is contained in:
@ -78,6 +78,18 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
setKey: SettingBoxKey.enableAutoBrightness,
|
setKey: SettingBoxKey.enableAutoBrightness,
|
||||||
defaultVal: false,
|
defaultVal: false,
|
||||||
),
|
),
|
||||||
|
const SetSwitchItem(
|
||||||
|
title: '自动全屏',
|
||||||
|
subTitle: '视频开始播放时进入全屏',
|
||||||
|
setKey: SettingBoxKey.enableAutoEnter,
|
||||||
|
defaultVal: false,
|
||||||
|
),
|
||||||
|
const SetSwitchItem(
|
||||||
|
title: '自动退出',
|
||||||
|
subTitle: '视频结束播放时退出全屏',
|
||||||
|
setKey: SettingBoxKey.enableAutoExit,
|
||||||
|
defaultVal: false,
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
title: Text('默认画质', style: titleStyle),
|
title: Text('默认画质', style: titleStyle),
|
||||||
|
|||||||
@ -73,6 +73,7 @@ class VideoDetailController extends GetxController
|
|||||||
// 默认记录历史记录
|
// 默认记录历史记录
|
||||||
bool enableHeart = true;
|
bool enableHeart = true;
|
||||||
var userInfo;
|
var userInfo;
|
||||||
|
late bool isFirstTime = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@ -193,6 +194,7 @@ class VideoDetailController extends GetxController
|
|||||||
bvid: bvid,
|
bvid: bvid,
|
||||||
cid: cid,
|
cid: cid,
|
||||||
enableHeart: enableHeart,
|
enableHeart: enableHeart,
|
||||||
|
isFirstTime: isFirstTime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +235,6 @@ class VideoDetailController extends GetxController
|
|||||||
currentDecodeFormats = VideoDecodeFormatsCode.fromString(setting.get(
|
currentDecodeFormats = VideoDecodeFormatsCode.fromString(setting.get(
|
||||||
SettingBoxKey.defaultDecode,
|
SettingBoxKey.defaultDecode,
|
||||||
defaultValue: VideoDecodeFormats.values.last.code))!;
|
defaultValue: VideoDecodeFormats.values.last.code))!;
|
||||||
print(currentDecodeFormats.description);
|
|
||||||
try {
|
try {
|
||||||
// 当前视频没有对应格式返回第一个
|
// 当前视频没有对应格式返回第一个
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
@ -287,6 +288,7 @@ class VideoDetailController extends GetxController
|
|||||||
defaultST = Duration(milliseconds: data.lastPlayTime!);
|
defaultST = Duration(milliseconds: data.lastPlayTime!);
|
||||||
if (autoPlay.value) {
|
if (autoPlay.value) {
|
||||||
await playerInit();
|
await playerInit();
|
||||||
|
isShowCover.value = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (result['code'] == -404) {
|
if (result['code'] == -404) {
|
||||||
|
|||||||
@ -31,9 +31,10 @@ class VideoIntroPanel extends StatefulWidget {
|
|||||||
|
|
||||||
class _VideoIntroPanelState extends State<VideoIntroPanel>
|
class _VideoIntroPanelState extends State<VideoIntroPanel>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
final VideoIntroController videoIntroController =
|
late String heroTag;
|
||||||
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
late VideoIntroController videoIntroController;
|
||||||
VideoDetailData? videoDetail;
|
VideoDetailData? videoDetail;
|
||||||
|
late Future? _futureBuilderFuture;
|
||||||
|
|
||||||
// 添加页面缓存
|
// 添加页面缓存
|
||||||
@override
|
@override
|
||||||
@ -42,6 +43,11 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
/// fix 全屏时参数丢失
|
||||||
|
heroTag = Get.arguments['heroTag'];
|
||||||
|
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
||||||
|
_futureBuilderFuture = videoIntroController.queryVideoIntro();
|
||||||
videoIntroController.videoDetail.listen((value) {
|
videoIntroController.videoDetail.listen((value) {
|
||||||
videoDetail = value;
|
videoDetail = value;
|
||||||
});
|
});
|
||||||
@ -57,15 +63,20 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: videoIntroController.queryVideoIntro(),
|
future: _futureBuilderFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
if (snapshot.data == null) {
|
||||||
|
return const SliverToBoxAdapter(child: SizedBox());
|
||||||
|
}
|
||||||
if (snapshot.data['status']) {
|
if (snapshot.data['status']) {
|
||||||
// 请求成功
|
// 请求成功
|
||||||
return Obx(
|
return Obx(
|
||||||
() => VideoInfo(
|
() => VideoInfo(
|
||||||
loadingStatus: false,
|
loadingStatus: false,
|
||||||
videoDetail: videoIntroController.videoDetail.value),
|
videoDetail: videoIntroController.videoDetail.value,
|
||||||
|
heroTag: heroTag,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// 请求错误
|
// 请求错误
|
||||||
@ -79,7 +90,11 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return VideoInfo(loadingStatus: true, videoDetail: videoDetail);
|
return VideoInfo(
|
||||||
|
loadingStatus: true,
|
||||||
|
videoDetail: videoDetail,
|
||||||
|
heroTag: heroTag,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -89,8 +104,10 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
class VideoInfo extends StatefulWidget {
|
class VideoInfo extends StatefulWidget {
|
||||||
final bool loadingStatus;
|
final bool loadingStatus;
|
||||||
final VideoDetailData? videoDetail;
|
final VideoDetailData? videoDetail;
|
||||||
|
final String? heroTag;
|
||||||
|
|
||||||
const VideoInfo({Key? key, this.loadingStatus = false, this.videoDetail})
|
const VideoInfo(
|
||||||
|
{Key? key, this.loadingStatus = false, this.videoDetail, this.heroTag})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -98,7 +115,8 @@ class VideoInfo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||||
final String heroTag = Get.arguments['heroTag'];
|
// final String heroTag = Get.arguments['heroTag'];
|
||||||
|
late String heroTag;
|
||||||
late final VideoIntroController videoIntroController;
|
late final VideoIntroController videoIntroController;
|
||||||
late final VideoDetailController videoDetailCtr;
|
late final VideoDetailController videoDetailCtr;
|
||||||
late final Map<dynamic, dynamic> videoItem;
|
late final Map<dynamic, dynamic> videoItem;
|
||||||
@ -117,7 +135,7 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
heroTag = widget.heroTag!;
|
||||||
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
|
||||||
videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag);
|
videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag);
|
||||||
videoItem = videoIntroController.videoItem!;
|
videoItem = videoIntroController.videoItem!;
|
||||||
|
|||||||
@ -41,7 +41,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
Get.put(VideoIntroController(), tag: Get.arguments['heroTag']);
|
||||||
|
|
||||||
PlayerStatus playerStatus = PlayerStatus.playing;
|
PlayerStatus playerStatus = PlayerStatus.playing;
|
||||||
// bool isShowCover = true;
|
|
||||||
double doubleOffset = 0;
|
double doubleOffset = 0;
|
||||||
|
|
||||||
Box localCache = GStrorage.localCache;
|
Box localCache = GStrorage.localCache;
|
||||||
@ -49,11 +48,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
late double statusBarHeight;
|
late double statusBarHeight;
|
||||||
final videoHeight = Get.size.width * 9 / 16;
|
final videoHeight = Get.size.width * 9 / 16;
|
||||||
late Future _futureBuilderFuture;
|
late Future _futureBuilderFuture;
|
||||||
|
// 自动退出全屏
|
||||||
|
late bool autoExitFullcreen;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
statusBarHeight = localCache.get('statusBarHeight');
|
statusBarHeight = localCache.get('statusBarHeight');
|
||||||
|
autoExitFullcreen =
|
||||||
|
setting.get(SettingBoxKey.enableAutoExit, defaultValue: false);
|
||||||
videoSourceInit();
|
videoSourceInit();
|
||||||
appbarStreamListen();
|
appbarStreamListen();
|
||||||
}
|
}
|
||||||
@ -63,7 +66,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
_futureBuilderFuture = videoDetailController.queryVideoUrl();
|
_futureBuilderFuture = videoDetailController.queryVideoUrl();
|
||||||
if (videoDetailController.autoPlay.value) {
|
if (videoDetailController.autoPlay.value) {
|
||||||
plPlayerController = videoDetailController.plPlayerController;
|
plPlayerController = videoDetailController.plPlayerController;
|
||||||
playerListener();
|
plPlayerController!.addStatusLister(playerListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,23 +82,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 播放器状态监听
|
// 播放器状态监听
|
||||||
void playerListener() {
|
void playerListener(PlayerStatus? status) {
|
||||||
plPlayerController!.onPlayerStatusChanged.listen(
|
if (status == PlayerStatus.completed) {
|
||||||
(PlayerStatus status) async {
|
// 结束播放退出全屏
|
||||||
playerStatus = status;
|
if (autoExitFullcreen) {
|
||||||
if (status == PlayerStatus.playing) {
|
plPlayerController!.triggerFullScreen(status: false);
|
||||||
videoDetailController.isShowCover.value = false;
|
}
|
||||||
} else {
|
// 播放完展示控制栏
|
||||||
// 播放完成停止 or 切换下一个
|
plPlayerController!.onLockControl(false);
|
||||||
if (status == PlayerStatus.completed) {
|
}
|
||||||
// 当只有1p或多p未打开自动播放时,播放完成还原进度条,展示控制栏
|
|
||||||
plPlayerController!.seekTo(Duration.zero);
|
|
||||||
plPlayerController!.onLockControl(false);
|
|
||||||
plPlayerController!.videoPlayerController!.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 继续播放或重新播放
|
// 继续播放或重新播放
|
||||||
@ -110,11 +105,11 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
plPlayerController = videoDetailController.plPlayerController;
|
plPlayerController = videoDetailController.plPlayerController;
|
||||||
videoDetailController.autoPlay.value = true;
|
videoDetailController.autoPlay.value = true;
|
||||||
videoDetailController.isShowCover.value = false;
|
videoDetailController.isShowCover.value = false;
|
||||||
playerListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
plPlayerController!.removeStatusLister(playerListener);
|
||||||
plPlayerController!.dispose();
|
plPlayerController!.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
@ -128,6 +123,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
}
|
}
|
||||||
videoDetailController.defaultST = plPlayerController!.position.value;
|
videoDetailController.defaultST = plPlayerController!.position.value;
|
||||||
videoIntroController.isPaused = true;
|
videoIntroController.isPaused = true;
|
||||||
|
plPlayerController!.removeStatusLister(playerListener);
|
||||||
plPlayerController!.pause();
|
plPlayerController!.pause();
|
||||||
super.didPushNext();
|
super.didPushNext();
|
||||||
}
|
}
|
||||||
@ -135,12 +131,14 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
@override
|
@override
|
||||||
// 返回当前页面时
|
// 返回当前页面时
|
||||||
void didPopNext() async {
|
void didPopNext() async {
|
||||||
|
videoDetailController.isFirstTime = false;
|
||||||
videoDetailController.playerInit();
|
videoDetailController.playerInit();
|
||||||
videoIntroController.isPaused = false;
|
videoIntroController.isPaused = false;
|
||||||
if (_extendNestCtr.position.pixels == 0) {
|
if (_extendNestCtr.position.pixels == 0) {
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
plPlayerController!.play();
|
plPlayerController!.play();
|
||||||
}
|
}
|
||||||
|
plPlayerController!.addStatusLister(playerListener);
|
||||||
super.didPopNext();
|
super.didPopNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,18 +11,15 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
import 'package:media_kit_video/media_kit_video.dart';
|
import 'package:media_kit_video/media_kit_video.dart';
|
||||||
import 'package:pilipala/http/video.dart';
|
import 'package:pilipala/http/video.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/models/data_source.dart';
|
import 'package:pilipala/plugin/pl_player/index.dart';
|
||||||
import 'package:pilipala/utils/feed_back.dart';
|
import 'package:pilipala/utils/feed_back.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:screen_brightness/screen_brightness.dart';
|
import 'package:screen_brightness/screen_brightness.dart';
|
||||||
import 'package:universal_platform/universal_platform.dart';
|
import 'package:universal_platform/universal_platform.dart';
|
||||||
// import 'package:wakelock_plus/wakelock_plus.dart';
|
// import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
|
||||||
import 'models/data_status.dart';
|
|
||||||
import 'models/play_speed.dart';
|
|
||||||
import 'models/play_status.dart';
|
|
||||||
|
|
||||||
Box videoStorage = GStrorage.video;
|
Box videoStorage = GStrorage.video;
|
||||||
|
Box setting = GStrorage.setting;
|
||||||
|
|
||||||
class PlPlayerController {
|
class PlPlayerController {
|
||||||
Player? _videoPlayerController;
|
Player? _videoPlayerController;
|
||||||
@ -84,6 +81,7 @@ class PlPlayerController {
|
|||||||
int _cid = 0;
|
int _cid = 0;
|
||||||
int _heartDuration = 0;
|
int _heartDuration = 0;
|
||||||
bool _enableHeart = true;
|
bool _enableHeart = true;
|
||||||
|
bool _isFirstTime = true;
|
||||||
|
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
Timer? _timerForSeek;
|
Timer? _timerForSeek;
|
||||||
@ -248,6 +246,8 @@ class PlPlayerController {
|
|||||||
int cid = 0,
|
int cid = 0,
|
||||||
// 历史记录开关
|
// 历史记录开关
|
||||||
bool enableHeart = true,
|
bool enableHeart = true,
|
||||||
|
// 是否首次加载
|
||||||
|
bool isFirstTime = true,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
_autoPlay = autoplay;
|
_autoPlay = autoplay;
|
||||||
@ -261,6 +261,7 @@ class PlPlayerController {
|
|||||||
_bvid = bvid;
|
_bvid = bvid;
|
||||||
_cid = cid;
|
_cid = cid;
|
||||||
_enableHeart = enableHeart;
|
_enableHeart = enableHeart;
|
||||||
|
_isFirstTime = isFirstTime;
|
||||||
|
|
||||||
if (_videoPlayerController != null &&
|
if (_videoPlayerController != null &&
|
||||||
_videoPlayerController!.state.playing) {
|
_videoPlayerController!.state.playing) {
|
||||||
@ -281,6 +282,12 @@ class PlPlayerController {
|
|||||||
if (!_listenersInitialized) {
|
if (!_listenersInitialized) {
|
||||||
startListeners();
|
startListeners();
|
||||||
}
|
}
|
||||||
|
bool autoEnterFullcreen =
|
||||||
|
setting.get(SettingBoxKey.enableAutoEnter, defaultValue: false);
|
||||||
|
if (autoEnterFullcreen && _isFirstTime) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
|
triggerFullScreen();
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
dataStatus.status.value = DataStatus.error;
|
dataStatus.status.value = DataStatus.error;
|
||||||
print('plPlayer err: $err');
|
print('plPlayer err: $err');
|
||||||
@ -397,6 +404,8 @@ class PlPlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<StreamSubscription> subscriptions = [];
|
List<StreamSubscription> subscriptions = [];
|
||||||
|
final List<VoidCallback> _positionListeners = [];
|
||||||
|
final List<Function(PlayerStatus status)> _statusListeners = [];
|
||||||
|
|
||||||
/// 播放事件监听
|
/// 播放事件监听
|
||||||
void startListeners() {
|
void startListeners() {
|
||||||
@ -408,11 +417,21 @@ class PlPlayerController {
|
|||||||
} else {
|
} else {
|
||||||
// playerStatus.status.value = PlayerStatus.paused;
|
// playerStatus.status.value = PlayerStatus.paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 触发回调事件
|
||||||
|
for (var element in _statusListeners) {
|
||||||
|
element(event ? PlayerStatus.playing : PlayerStatus.paused);
|
||||||
|
}
|
||||||
makeHeartBeat(_position.value.inSeconds, type: 'status');
|
makeHeartBeat(_position.value.inSeconds, type: 'status');
|
||||||
}),
|
}),
|
||||||
videoPlayerController!.stream.completed.listen((event) {
|
videoPlayerController!.stream.completed.listen((event) {
|
||||||
if (event) {
|
if (event) {
|
||||||
playerStatus.status.value = PlayerStatus.completed;
|
playerStatus.status.value = PlayerStatus.completed;
|
||||||
|
|
||||||
|
/// 触发回调事件
|
||||||
|
for (var element in _statusListeners) {
|
||||||
|
element(PlayerStatus.completed);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// playerStatus.status.value = PlayerStatus.playing;
|
// playerStatus.status.value = PlayerStatus.playing;
|
||||||
}
|
}
|
||||||
@ -423,6 +442,11 @@ class PlPlayerController {
|
|||||||
if (!isSliderMoving.value) {
|
if (!isSliderMoving.value) {
|
||||||
_sliderPosition.value = event;
|
_sliderPosition.value = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 触发回调事件
|
||||||
|
for (var element in _positionListeners) {
|
||||||
|
element();
|
||||||
|
}
|
||||||
makeHeartBeat(event.inSeconds);
|
makeHeartBeat(event.inSeconds);
|
||||||
}),
|
}),
|
||||||
videoPlayerController!.stream.duration.listen((event) {
|
videoPlayerController!.stream.duration.listen((event) {
|
||||||
@ -714,6 +738,78 @@ class PlPlayerController {
|
|||||||
_isFullScreen.value = val;
|
_isFullScreen.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 全屏
|
||||||
|
Future<void> triggerFullScreen({bool status = true}) async {
|
||||||
|
FullScreenMode mode = FullScreenModeCode.fromCode(
|
||||||
|
setting.get(SettingBoxKey.fullScreenMode, defaultValue: 0))!;
|
||||||
|
|
||||||
|
if (!isFullScreen.value && status) {
|
||||||
|
/// 按照视频宽高比决定全屏方向
|
||||||
|
switch (mode) {
|
||||||
|
case FullScreenMode.auto:
|
||||||
|
if (direction.value == 'horizontal') {
|
||||||
|
/// 进入全屏
|
||||||
|
await enterFullScreen();
|
||||||
|
// 横屏
|
||||||
|
await landScape();
|
||||||
|
} else {
|
||||||
|
// 竖屏
|
||||||
|
await verticalScreen();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FullScreenMode.vertical:
|
||||||
|
|
||||||
|
/// 进入全屏
|
||||||
|
await enterFullScreen();
|
||||||
|
// 横屏
|
||||||
|
await verticalScreen();
|
||||||
|
break;
|
||||||
|
case FullScreenMode.horizontal:
|
||||||
|
|
||||||
|
/// 进入全屏
|
||||||
|
await enterFullScreen();
|
||||||
|
// 横屏
|
||||||
|
await landScape();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFullScreen(true);
|
||||||
|
var result = await showDialog(
|
||||||
|
context: Get.context!,
|
||||||
|
useSafeArea: false,
|
||||||
|
builder: (context) => Dialog.fullscreen(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
child: PLVideoPlayer(
|
||||||
|
controller: this,
|
||||||
|
headerControl: headerControl,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (result == null) {
|
||||||
|
// 退出全屏
|
||||||
|
exitFullScreen();
|
||||||
|
await verticalScreen();
|
||||||
|
toggleFullScreen(false);
|
||||||
|
}
|
||||||
|
} else if (isFullScreen.value) {
|
||||||
|
Get.back();
|
||||||
|
exitFullScreen();
|
||||||
|
await verticalScreen();
|
||||||
|
toggleFullScreen(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPositionListener(VoidCallback listener) =>
|
||||||
|
_positionListeners.add(listener);
|
||||||
|
void removePositionListener(VoidCallback listener) =>
|
||||||
|
_positionListeners.remove(listener);
|
||||||
|
void addStatusLister(Function(PlayerStatus status) listener) {
|
||||||
|
_statusListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeStatusLister(Function(PlayerStatus status) listener) =>
|
||||||
|
_statusListeners.remove(listener);
|
||||||
|
|
||||||
/// 截屏
|
/// 截屏
|
||||||
Future screenshot() async {
|
Future screenshot() async {
|
||||||
final Uint8List? screenshot =
|
final Uint8List? screenshot =
|
||||||
|
|||||||
@ -159,67 +159,6 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
widget.controller.brightness.value = value;
|
widget.controller.brightness.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> triggerFullScreen() async {
|
|
||||||
PlPlayerController _ = widget.controller;
|
|
||||||
mode = FullScreenModeCode.fromCode(
|
|
||||||
setting.get(SettingBoxKey.fullScreenMode, defaultValue: 0))!;
|
|
||||||
|
|
||||||
if (!_.isFullScreen.value) {
|
|
||||||
/// 按照视频宽高比决定全屏方向
|
|
||||||
switch (mode) {
|
|
||||||
case FullScreenMode.auto:
|
|
||||||
if (_.direction.value == 'horizontal') {
|
|
||||||
/// 进入全屏
|
|
||||||
await enterFullScreen();
|
|
||||||
// 横屏
|
|
||||||
await landScape();
|
|
||||||
} else {
|
|
||||||
// 竖屏
|
|
||||||
await verticalScreen();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FullScreenMode.vertical:
|
|
||||||
|
|
||||||
/// 进入全屏
|
|
||||||
await enterFullScreen();
|
|
||||||
// 横屏
|
|
||||||
await verticalScreen();
|
|
||||||
break;
|
|
||||||
case FullScreenMode.horizontal:
|
|
||||||
|
|
||||||
/// 进入全屏
|
|
||||||
await enterFullScreen();
|
|
||||||
// 横屏
|
|
||||||
await landScape();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_.toggleFullScreen(true);
|
|
||||||
var result = await showDialog(
|
|
||||||
context: Get.context!,
|
|
||||||
useSafeArea: false,
|
|
||||||
builder: (context) => Dialog.fullscreen(
|
|
||||||
backgroundColor: Colors.black,
|
|
||||||
child: PLVideoPlayer(
|
|
||||||
controller: _,
|
|
||||||
headerControl: _.headerControl,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (result == null) {
|
|
||||||
// 退出全屏
|
|
||||||
exitFullScreen();
|
|
||||||
await verticalScreen();
|
|
||||||
_.toggleFullScreen(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Get.back();
|
|
||||||
exitFullScreen();
|
|
||||||
await verticalScreen();
|
|
||||||
_.toggleFullScreen(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
animationController.dispose();
|
animationController.dispose();
|
||||||
@ -559,13 +498,13 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
if (dy > _distance && dy > threshold) {
|
if (dy > _distance && dy > threshold) {
|
||||||
if (_.isFullScreen.value) {
|
if (_.isFullScreen.value) {
|
||||||
// 下滑退出全屏
|
// 下滑退出全屏
|
||||||
await triggerFullScreen();
|
await widget.controller.triggerFullScreen(status: false);
|
||||||
}
|
}
|
||||||
_distance = 0.0;
|
_distance = 0.0;
|
||||||
} else if (dy < _distance && dy < -threshold) {
|
} else if (dy < _distance && dy < -threshold) {
|
||||||
if (!_.isFullScreen.value) {
|
if (!_.isFullScreen.value) {
|
||||||
// 上滑进入全屏
|
// 上滑进入全屏
|
||||||
await triggerFullScreen();
|
await widget.controller.triggerFullScreen();
|
||||||
}
|
}
|
||||||
_distance = 0.0;
|
_distance = 0.0;
|
||||||
}
|
}
|
||||||
@ -606,7 +545,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
child: BottomControl(
|
child: BottomControl(
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
triggerFullScreen: triggerFullScreen),
|
triggerFullScreen: widget.controller.triggerFullScreen),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -97,6 +97,8 @@ class SettingBoxKey {
|
|||||||
static const String enableHA = 'enableHA';
|
static const String enableHA = 'enableHA';
|
||||||
static const String enableOnlineTotal = 'enableOnlineTotal';
|
static const String enableOnlineTotal = 'enableOnlineTotal';
|
||||||
static const String enableAutoBrightness = 'enableAutoBrightness';
|
static const String enableAutoBrightness = 'enableAutoBrightness';
|
||||||
|
static const String enableAutoEnter = 'enableAutoEnter';
|
||||||
|
static const String enableAutoExit = 'enableAutoExit';
|
||||||
|
|
||||||
/// 隐私
|
/// 隐私
|
||||||
static const String blackMidsList = 'blackMidsList';
|
static const String blackMidsList = 'blackMidsList';
|
||||||
|
|||||||
Reference in New Issue
Block a user