Files
huangguo_android/lib/hj_page/video/video_player_alert.dart
T
2026-09-15 15:44:13 +07:00

127 lines
3.6 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/assets_tool/images.dart';
import 'package:hgdj/hj_page/video/video_full_page.dart';
import 'package:hgdj/hj_page/video/view/video_menu_view.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/hj_utils/video_view_type.dart';
import 'package:hgdj/tools_base/event_bus/event_bus_util.dart';
import 'package:hgdj/tools_base/event_bus/events.dart';
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
import 'package:video_player/video_player.dart';
import '../../tools_base/widget/net_image_widget.dart';
class VideoPlayerAlert extends StatefulWidget {
final String? movieUrl;
final String? imgCover;
const VideoPlayerAlert(this.movieUrl, {this.imgCover, super.key});
@override
State<VideoPlayerAlert> createState() => _VideoPlayerAlertState();
}
class _VideoPlayerAlertState extends State<VideoPlayerAlert> {
VideoPlayerController? videoCtr;
StreamSubscription? pauseSub;
@override
void initState() {
super.initState();
// 耳机/蓝牙断开、来电中断时暂停,防止外放泄露
pauseSub = eventBus.on<PauseVideoEvent>((_) => videoCtr?.pause());
WidgetsBinding.instance.addPostFrameCallback((_) => _initStatus());
}
void _initStatus({bool isRetry = false}) async {
videoCtr = PlayerFactory.network(widget.movieUrl);
try {
await videoCtr?.initialize();
if (isRetry)
confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地
if (mounted) {
videoCtr?.play();
setState(() {});
}
} catch (e) {
videoCtr?.dispose();
// 首次芯片解码/渲染报错:仅内存切 platformView 重试,成功后才落本地
if (isDecoderError(e) && switchToPlatformView()) {
_initStatus(isRetry: true);
}
}
}
@override
void dispose() {
pauseSub?.cancel();
videoCtr?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Dialog(
insetPadding: EdgeInsets.zero,
backgroundColor: Colors.transparent,
child: SafeArea(
child: Stack(
fit: StackFit.expand,
children: [
_buildContent(),
Positioned(
left: 0,
top: 0,
child: InkWell(
enableFeedback: false,
onTap: Get.back,
child: Container(
padding: EdgeInsets.only(left: 16, top: 6),
child: Image.asset('back_circle.png'.commonImgPath,
width: 24, height: 24),
),
),
),
],
),
),
);
}
Widget _buildContent() {
// 未初始化完成:展示封面 + loading
if (videoCtr?.value.isInitialized != true) {
return Stack(
alignment: Alignment.center,
children: [
if (widget.imgCover?.isNotEmpty == true)
NetworkImageLoader(imageUrl: widget.imgCover ?? ""),
LoadingCenterWidget(),
],
);
}
return Stack(
fit: StackFit.expand,
children: [
Container(
alignment: Alignment.center,
width: screen.screenWidth,
child: AspectRatio(
aspectRatio: videoCtr!.value.aspectRatio,
child: VideoPlayer(videoCtr!),
),
),
VideoMenuView(
playCtr: videoCtr!,
isFull: true,
onFullScreen: () =>
Get.to(() => VideoFullPage(playCtr: videoCtr!, isAutoV: false)),
),
],
);
}
}