| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- import 'dart:io';
- import 'package:better_player_plus/better_player_plus.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:go_router/go_router.dart';
- import 'package:news_app/ui/video/video_detail_page.dart';
- import 'package:news_app/ui/video/video_recommend_list_page.dart';
- import '../../constant/config.dart';
- import '../../gen/assets.gen.dart';
- import '../../model/video_new_model.dart';
- import '../../util/device_util.dart';
- import '../../util/log.util.dart';
- import '../../util/share_util.dart';
- import '../../widget/auth_gesture_detector.dart';
- import '../../widget/load_image.dart';
- import '../../widget/my_txt.dart';
- class VideoPlayItemWidget extends ConsumerStatefulWidget {
- final VideoNewModel item;
- final bool isActive;
- const VideoPlayItemWidget({
- super.key,
- required this.item,
- required this.isActive,
- });
- @override
- ConsumerState<VideoPlayItemWidget> createState() => _VideoItemWidgetState();
- }
- class _VideoItemWidgetState extends ConsumerState<VideoPlayItemWidget> {
- late BetterPlayerController _controller;
- bool _isPlaying = false;
- bool _isWeChatInstalled = false;
- Future<void> _checkWeChatInstallation() async {
- if (Platform.isAndroid) {
- final installed = await isWeChatInstalledOnlyAndroid();
- setState(() => _isWeChatInstalled = installed);
- } else if (Platform.isIOS) {
- final installed = await fluwx.isWeChatInstalled;
- setState(() => _isWeChatInstalled = installed);
- }
- }
- Future<void> shareAction(VideoNewModel data) async {
- showModalBottomSheet(
- context: context,
- builder:
- (context) => SafeArea(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- SizedBox(height: 10.h),
- Container(
- width: double.infinity,
- height: 80.h,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(10.r),
- topRight: Radius.circular(10.r),
- ),
- color: Colors.white,
- ),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- if (_isWeChatInstalled)
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareWeiXinUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_wxhy',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "微信好友",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- if (_isWeChatInstalled)
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareWeiXinPYUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_pyq',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "朋友圈",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- GestureDetector(
- onTap: () {
- Navigator.pop(context);
- shareUrl(
- title: data.shareDesc ?? "",
- url: data.shareUrl ?? "",
- );
- },
- child: Container(
- width: 100.w,
- height: 80.h,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- LoadAssetImage(
- 'share_xtfx',
- width: 40.w,
- height: 40.h,
- ),
- SizedBox(height: 10.h),
- myTxt(
- text: "系统分享",
- color: Colors.black,
- fontSize: 12.sp,
- fontWeight: FontWeight.bold,
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- );
- }
- @override
- void initState() {
- super.initState();
- consoleLog("VideoPlayItemWidget: initState for video ${widget.item.contentId}, url: ${widget.item.url}, isActive: ${widget.isActive}");
- _checkWeChatInstallation();
- _controller = BetterPlayerController(
- BetterPlayerConfiguration(
- autoPlay: false,
- looping: true,
- aspectRatio: 16 / 9,
- fit: BoxFit.fitWidth,
- controlsConfiguration: const BetterPlayerControlsConfiguration(
- showControls: false,
- ),
- ),
- betterPlayerDataSource: BetterPlayerDataSource(
- BetterPlayerDataSourceType.network,
- widget.item.url ?? "",
- ),
- );
- _controller.addEventsListener(_handlePlayerEvent);
- // 如果初始化时就是激活状态,立即播放
- if (widget.isActive && mounted) {
- consoleLog("VideoPlayItemWidget: isActive is true, starting playback");
- _controller.play();
- }
- }
- void _handlePlayerEvent(BetterPlayerEvent event) {
- if (!mounted) return;
- consoleLog("VideoPlayItemWidget: BetterPlayerEvent: ${event.betterPlayerEventType} for video ${widget.item.contentId}");
- if (event.betterPlayerEventType == BetterPlayerEventType.play ||
- event.betterPlayerEventType == BetterPlayerEventType.pause ||
- event.betterPlayerEventType == BetterPlayerEventType.finished) {
- final isPlaying = _controller.isPlaying() ?? false;
- if (mounted && isPlaying != _isPlaying) {
- setState(() {
- _isPlaying = isPlaying;
- });
- }
- }
- }
- @override
- void didUpdateWidget(covariant VideoPlayItemWidget oldWidget) {
- super.didUpdateWidget(oldWidget);
- if (!mounted) return;
- consoleLog("VideoPlayItemWidget: didUpdateWidget, oldActive: ${oldWidget.isActive}, newActive: ${widget.isActive}");
- if (widget.isActive && !oldWidget.isActive) {
- consoleLog("VideoPlayItemWidget: Activating video ${widget.item.contentId}");
- _controller.play();
- } else if (!widget.isActive && oldWidget.isActive) {
- consoleLog("VideoPlayItemWidget: Deactivating video ${widget.item.contentId}");
- _controller.pause();
- }
- }
- @override
- void dispose() {
- _controller.removeEventsListener(_handlePlayerEvent);
- _controller.dispose();
- super.dispose();
- }
- void _togglePlay() {
- if (!mounted) return;
- if (_isPlaying) {
- _controller.pause();
- } else {
- _controller.play();
- }
- }
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTap: _togglePlay,
- child: Stack(
- fit: StackFit.expand,
- children: [
- ColoredBox(
- color: Colors.black,
- child: BetterPlayer(controller: _controller),
- ),
- if (!_isPlaying)
- Center(
- child: Image.asset(
- Assets.images.playIcon.path,
- width: 60.w,
- height: 60.w,
- ),
- ),
- Positioned(
- right: 10.h,
- bottom: 100.h,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- AuthGestureDetector(
- onTap: () {
- ref
- .read(recommendListProvider.notifier)
- .fetchVideoLike(
- videoId: widget.item.contentId,
- current: widget.item.isLiked ?? false,
- );
- },
- child: Icon(
- Icons.favorite,
- color:
- widget.item.isLiked == true ? Colors.red : Colors.white,
- size: 25.sp,
- ),
- ),
- myTxt(
- text:
- widget.item.likeCount == null
- ? ""
- : widget.item.likeCount.toString(),
- color: Colors.white,
- fontSize: 12.sp,
- ),
- SizedBox(height: 15.h),
- AuthGestureDetector(
- onTap: () {
- context.push(
- "/video/detail",
- extra: VideoParam(
- id: widget.item.contentId ?? "",
- videoUrl: widget.item.url,
- ),
- );
- },
- child: Icon(Icons.message, color: Colors.white, size: 25.sp),
- ),
- myTxt(
- text:
- widget.item.commentCount == null
- ? "0"
- : widget.item.commentCount.toString(),
- color: Colors.white,
- fontSize: 12.sp,
- ),
- SizedBox(height: 15.h),
- AuthGestureDetector(
- onTap: () {
- ref
- .read(recommendListProvider.notifier)
- .fetchVideoFavorite(
- videoId: widget.item.contentId,
- current: widget.item.isFavorite ?? false,
- );
- },
- child: Icon(
- Icons.star,
- color:
- widget.item.isFavorite == true
- ? Colors.red
- : Colors.white,
- size: 25.sp,
- ),
- ),
- myTxt(
- text:
- widget.item.favoriteCount == null
- ? "0"
- : widget.item.favoriteCount.toString(),
- color: Colors.white,
- fontSize: 12.sp,
- ),
- SizedBox(height: 15.h),
- GestureDetector(
- onTap: () {
- // shareUrl(
- // title: widget.item.shareDesc ?? "",
- // url: widget.item.shareUrl ?? "",
- // );
- shareAction(widget.item);
- if (uuid.isNotEmpty) {
- ref
- .read(recommendListProvider.notifier)
- .fetchVideoShare(contentId: widget.item.contentId);
- }
- },
- child: Icon(
- Icons.screen_share,
- color: Colors.white,
- size: 25.sp,
- ),
- ),
- myTxt(
- text:
- widget.item.shareCount == null
- ? "0"
- : widget.item.shareCount.toString(),
- color: Colors.white,
- fontSize: 12.sp,
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
- }
|