import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/controlsOverlay_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/videoLogDetail/videoLogDetail_state.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart'; import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail.dart'; import 'package:star_lock/tools/dateTool.dart'; import 'package:video_player/video_player.dart'; import '../../../../app_settings/app_colors.dart'; import '../../../../tools/titleAppBar.dart'; import 'videoLogDetail_logic.dart'; class VideoLogDetailPage extends StatefulWidget { const VideoLogDetailPage({Key? key}) : super(key: key); @override State createState() => _VideoLogDetailPageState(); } class _VideoLogDetailPageState extends State { final VideoLogDetailLogic logic = Get.put(VideoLogDetailLogic()); final VideoLogDetailState state = Get.find().state; @override void initState() { super.initState(); state.videoController = VideoPlayerController.networkUrl( Uri.parse(state.recordData.value.videoUrl!), videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), ); state.videoController.addListener(() { setState(() {}); }); state.videoController.setLooping(false); state.videoController.initialize(); } void _initializeVideoPlayer(String videoUrl) async { if (state.videoController != null) { await state.videoController.dispose(); // 释放旧资源 } state.videoController = VideoPlayerController.networkUrl( Uri.parse(videoUrl), videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true), ); // 初始化完成后通知框架重新构建界面 await state.videoController.initialize(); state.videoController.addListener(() { setState(() {}); }); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: TitleAppBar( barTitle: '视频播放'.tr, haveBack: true, backgroundColor: AppColors.mainColor, ), body: state.videoController.value.isInitialized ? Column( children: [ Container( height: 500.h, decoration: BoxDecoration(color: Colors.black), child: AspectRatio( aspectRatio: 16 / 9, child: Stack( alignment: Alignment.bottomCenter, children: [ FittedBox( child: SizedBox( width: state.videoController.value.size.width, height: state.videoController.value.size.height, child: VideoPlayer(state.videoController), ), fit: BoxFit.cover, ), ControlsOverlay( controller: state.videoController, recordData: state.recordData.value, ), if (state.videoController.value.isPlaying || state.videoController.value.isBuffering) Container() else VideoProgressIndicator( state.videoController, colors: VideoProgressColors( playedColor: AppColors.mainColor), allowScrubbing: true, ), ], ), ), ), _buildOther(), ], ) : Center( child: CircularProgressIndicator(), ), ); } double itemW = (1.sw - 15.w * 4) / 3; double itemH = (1.sw - 15.w * 4) / 3 + 40.h; Widget videoItem(RecordListData recordData) { return GestureDetector( onTap: () { if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) { state.recordData.value = recordData; _initializeVideoPlayer(recordData.videoUrl!); setState(() {}); } else if (recordData.imagesUrl != null && recordData.imagesUrl!.isNotEmpty) { Navigator.push( context, MaterialPageRoute( builder: (context) => FullScreenImagePage( imageUrl: recordData.imagesUrl!, ), ), ); } }, child: SizedBox( width: itemW, height: itemH, child: Column( children: [ Container( width: itemW, height: itemW, margin: const EdgeInsets.all(0), color: Colors.white, child: ClipRRect( borderRadius: BorderRadius.circular(10.w), child: _buildImageOrVideoItem(recordData), ), ), ], ), ), ); } _buildImageOrVideoItem(RecordListData recordData) { if (recordData.videoUrl != null && recordData.videoUrl!.isNotEmpty) { return _buildVideoItem(recordData); } else { return _buildImageItem(recordData); } } _buildVideoItem(RecordListData recordData) { return VideoThumbnail(videoUrl: recordData.videoUrl!); } _buildImageItem(RecordListData recordData) { return Image.network( recordData.imagesUrl!, fit: BoxFit.cover, ); } String formatString(time) { String shortName = time.toString().substring(2, 7); return shortName; } @override void dispose() { super.dispose(); state.videoController.dispose(); } _buildOther() { return Expanded( child: ListView.builder( itemCount: state.videoLogList.length, itemBuilder: (BuildContext c, int index) { CloudStorageData item = state.videoLogList[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(left: 20.w, top: 15.w, bottom: 15.w), child: Row( children: [ Text(item.date ?? '', style: TextStyle(fontSize: 20.sp)), ], ), ), mainListView(index, item), ], ); }, ), ); } Widget mainListView(int index, CloudStorageData itemData) { return GridView.builder( itemCount: itemData.recordList!.length, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( //横轴元素个数 crossAxisCount: 3, ), itemBuilder: (BuildContext context, int index) { return _buildItem(itemData.recordList![index]); }, ); } _buildItem(itemData) { return videoItem(itemData); } }