feat: 全屏播放

This commit is contained in:
guozhigq
2023-08-02 23:42:36 +08:00
parent d512bc0bfd
commit ffd1f0a24a
12 changed files with 197 additions and 60 deletions

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
@ -53,6 +54,9 @@ class PlPlayerController {
final Rx<bool> _showBrightnessStatus = false.obs;
final Rx<bool> _doubleSpeedStatus = false.obs;
final Rx<bool> _controlsLock = false.obs;
final Rx<bool> _isFullScreen = false.obs;
final Rx<String> _direction = 'horizontal'.obs;
Rx<bool> videoFitChanged = false.obs;
final Rx<BoxFit> _videoFit = Rx(BoxFit.fill);
@ -82,6 +86,8 @@ class PlPlayerController {
BoxFit.scaleDown
];
PreferredSizeWidget? headerControl;
/// 数据加载监听
Stream<DataStatus> get onDataStatusChanged => dataStatus.status.stream;
@ -160,6 +166,12 @@ class PlPlayerController {
/// 屏幕锁 为true时关闭控制栏
Rx<bool> get controlsLock => _controlsLock;
/// 全屏状态
Rx<bool> get isFullScreen => _isFullScreen;
/// 全屏方向
Rx<String> get direction => _direction;
PlPlayerController({
// 直播间 传false 关闭控制栏
this.controlsEnabled = true,
@ -197,6 +209,9 @@ class PlPlayerController {
double? width,
double? height,
Duration? duration,
// 方向
String? direction,
// 全屏模式
}) async {
try {
_autoPlay = autoplay;
@ -207,6 +222,8 @@ class PlPlayerController {
_playbackSpeed.value = speed;
// 初始化数据加载状态
dataStatus.status.value = DataStatus.loading;
// 初始化全屏方向
_direction.value = direction ?? 'horizontal';
if (_videoPlayerController != null &&
_videoPlayerController!.state.playing) {
@ -624,6 +641,10 @@ class PlPlayerController {
showControls.value = !val;
}
void toggleFullScreen(bool val) {
_isFullScreen.value = val;
}
/// 截屏
Future screenshot() async {
final Uint8List? screenshot =

View File

@ -8,3 +8,5 @@ export './models/data_status.dart';
export './widgets/common_btn.dart';
export './models/play_speed.dart';
export './widgets/app_bar_ani.dart';
export './utils/fullscreen.dart';
export './utils.dart';

View File

@ -0,0 +1,9 @@
// 全屏模式
enum FullScreenMode {
// 根据内容自适应
auto,
// 始终竖屏
vertical,
// 始终横屏
horizontal
}

View File

@ -0,0 +1,40 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:auto_orientation/auto_orientation.dart';
import 'package:flutter/services.dart';
//横屏
/// 低版本xcode不支持auto_orientation
Future<void> landScape() async {
if (Platform.isAndroid || Platform.isIOS) {
await AutoOrientation.landscapeAutoMode(forceSensor: true);
}
}
//竖屏
Future<void> verticalScreen() async {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
}
Future<void> enterFullScreen() async {
await SystemChrome.setEnabledSystemUIMode(
SystemUiMode.immersiveSticky,
);
}
//退出全屏显示
Future<void> exitFullScreen() async {
late SystemUiMode mode;
if ((Platform.isAndroid &&
(await DeviceInfoPlugin().androidInfo).version.sdkInt >= 29) ||
!Platform.isAndroid) {
mode = SystemUiMode.edgeToEdge;
} else {
mode = SystemUiMode.manual;
}
await SystemChrome.setEnabledSystemUIMode(mode,
overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
}

View File

@ -75,6 +75,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
animationController = AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
videoController = widget.controller.videoController!;
widget.controller.headerControl = widget.headerControl;
Future.microtask(() async {
try {
@ -149,6 +150,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
@override
Widget build(BuildContext context) {
print('🌹🌹🌹🌹🌹33333');
final _ = widget.controller;
Color colorTheme = Theme.of(context).colorScheme.primary;
TextStyle subTitleStyle = const TextStyle(
@ -387,6 +389,7 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
// 双击左边区域 👈
onDoubleTapSeekBackward();
} else if (tapPosition < sectionWidth * 2) {
print('🌹🌹🌹🌹🌹333356555553');
if (_.playerStatus.status.value == PlayerStatus.playing) {
_.togglePlay();
} else {
@ -443,15 +446,16 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
Obx(
() => Column(
children: [
ClipRect(
clipBehavior: Clip.hardEdge,
child: AppBarAni(
controller: animationController,
visible: !_.controlsLock.value && _.showControls.value,
position: 'top',
child: widget.headerControl!,
if (widget.headerControl != null)
ClipRect(
clipBehavior: Clip.hardEdge,
child: AppBarAni(
controller: animationController,
visible: !_.controlsLock.value && _.showControls.value,
position: 'top',
child: widget.headerControl!,
),
),
),
const Spacer(),
ClipRect(
clipBehavior: Clip.hardEdge,

View File

@ -5,8 +5,6 @@ import 'package:get/get.dart';
import 'package:pilipala/plugin/pl_player/index.dart';
import 'package:pilipala/plugin/pl_player/widgets/play_pause_btn.dart';
import '../utils.dart';
class BottomControl extends StatelessWidget implements PreferredSizeWidget {
final PlPlayerController? controller;
const BottomControl({this.controller, Key? key}) : super(key: key);
@ -138,14 +136,52 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget {
// ),
// const SizedBox(width: 4),
// 全屏
ComBtn(
icon: const Icon(
FontAwesomeIcons.expand,
size: 15,
color: Colors.white,
),
fuc: () => {},
),
Obx(() => ComBtn(
icon: Icon(
_.isFullScreen.value
? FontAwesomeIcons.a
: FontAwesomeIcons.expand,
size: 15,
color: Colors.white,
),
fuc: () async {
if (!_.isFullScreen.value) {
/// 按照视频宽高比决定全屏方向
if (_.direction.value == 'horizontal') {
/// 进入全屏
await enterFullScreen();
// 横屏
await landScape();
} else {
// 竖屏
await verticalScreen();
}
_.toggleFullScreen(true);
var result = await showDialog(
context: Get.context!,
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);
}
},
)),
],
),
],