312 lines
13 KiB
Dart
312 lines
13 KiB
Dart
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:liquid_progress_indicator_v2/liquid_progress_indicator.dart';
|
||
import 'package:wgshare/common/store/user_store.dart';
|
||
|
||
import '../../../common/models/meeting_room_user.dart';
|
||
import '../../../utils/color_util.dart';
|
||
import '../../../view/view_svg_path.dart';
|
||
import 'meeting_main_video_logic.dart';
|
||
import 'meeting_main_video_state.dart';
|
||
|
||
class MeetingMainVideoComponent extends StatefulWidget {
|
||
const MeetingMainVideoComponent({super.key,
|
||
required this.rtcEngine,
|
||
required this.channelId,
|
||
required this.isOpenCamera,
|
||
required this.remoteUid,
|
||
required this.onHangUpTap,
|
||
required this.users});
|
||
|
||
final RtcEngine rtcEngine;
|
||
final String channelId;
|
||
final String remoteUid;
|
||
final bool isOpenCamera;
|
||
final List<MeetingRoomUser> users;
|
||
final Function onHangUpTap;
|
||
|
||
@override
|
||
State<MeetingMainVideoComponent> createState() => _MeetingMainVideoComponentState();
|
||
}
|
||
|
||
class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> with AutomaticKeepAliveClientMixin {
|
||
|
||
final MeetingMainVideoLogic logic = Get.put(MeetingMainVideoLogic());
|
||
final MeetingMainVideoState state = Get.find<MeetingMainVideoLogic>().state;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Stack(
|
||
alignment: Alignment.center,
|
||
children: [
|
||
PageView(
|
||
scrollDirection: Axis.horizontal,
|
||
reverse: false,
|
||
controller: PageController(
|
||
initialPage: 0,
|
||
viewportFraction: 1,
|
||
keepPage: true,
|
||
),
|
||
physics: const BouncingScrollPhysics(),
|
||
pageSnapping: true,
|
||
onPageChanged: (index) {
|
||
// 监听事件
|
||
debugPrint('wgs输出===:$index');
|
||
},
|
||
children: <Widget>[
|
||
Stack(
|
||
alignment: Alignment.center,
|
||
children: [
|
||
widget.remoteUid != ""
|
||
? AgoraVideoView(
|
||
controller: VideoViewController.remote(
|
||
rtcEngine: widget.rtcEngine,
|
||
canvas: VideoCanvas(uid: int.tryParse(widget.remoteUid)),
|
||
connection: RtcConnection(channelId: widget.channelId),
|
||
),
|
||
)
|
||
: const CircularProgressIndicator(),
|
||
Positioned(
|
||
bottom: 110,
|
||
child: GestureDetector(
|
||
child: Image.asset(
|
||
'assets/images/meeting_main_hang_up.png',
|
||
width: 50.w,
|
||
height: 50.h,
|
||
),
|
||
onTap: () {
|
||
widget.onHangUpTap();
|
||
},
|
||
),
|
||
),
|
||
Positioned(
|
||
top: 16,
|
||
right: 16,
|
||
child: Container(
|
||
height: 30,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(8),
|
||
color: ColorUtil.Color_0_0_0_96),
|
||
padding: const EdgeInsets.only(left: 12, right: 12),
|
||
child: Row(
|
||
children: [
|
||
Text(
|
||
'正在讲话:',
|
||
style: TextStyle(
|
||
fontSize: 10.sp,
|
||
color: ColorUtil.Color_185_184_184),
|
||
),
|
||
Image.asset(
|
||
'assets/images/meeting_main_speak2.png',
|
||
width: 20.w,
|
||
height: 20.h,
|
||
),
|
||
Text(
|
||
'晓晓',
|
||
style: TextStyle(
|
||
fontSize: 10.sp,
|
||
color: ColorUtil.Color_185_184_184),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
),
|
||
|
||
/// 右上角小窗
|
||
/*Visibility(
|
||
visible: widget.isOpenCamera,
|
||
child: Positioned(
|
||
top: 58,
|
||
right: 13,
|
||
child: Stack(
|
||
children: [
|
||
SizedBox(
|
||
width: 120,
|
||
height: 150,
|
||
child: Center(
|
||
child: widget.isOpenCamera
|
||
? AgoraVideoView(
|
||
controller: VideoViewController(
|
||
rtcEngine: widget.rtcEngine,
|
||
canvas: const VideoCanvas(uid: 0),
|
||
),
|
||
)
|
||
: const CircularProgressIndicator(),
|
||
),
|
||
),
|
||
Positioned(
|
||
left: 4,
|
||
bottom: 4,
|
||
child: Row(
|
||
children: [
|
||
Image.asset(
|
||
'assets/images/meeting_main_own.png',
|
||
width: 20.w,
|
||
height: 15.h,
|
||
),
|
||
Container(
|
||
height: 15,
|
||
margin: const EdgeInsets.only(left: 4),
|
||
padding:
|
||
const EdgeInsets.only(left: 4, right: 4),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(2),
|
||
color: ColorUtil.Color_0_0_0_96),
|
||
child: Row(
|
||
children: [
|
||
*//*Image.asset(
|
||
'assets/images/meeting_main_microphone_open.png',
|
||
width: 13.w,
|
||
height: 14.h,
|
||
),
|
||
SizedBox(width: 4.w),*//*
|
||
Text(
|
||
UserStore
|
||
.to.userInfoEntity.value!.userName,
|
||
style: TextStyle(
|
||
fontSize: 10.sp,
|
||
color: ColorUtil.Color_185_184_184),
|
||
)
|
||
],
|
||
),
|
||
)
|
||
],
|
||
),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
)*/
|
||
],
|
||
),
|
||
Container(
|
||
color: ColorUtil.Color_57_57_57,
|
||
child: GridView.builder(
|
||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||
crossAxisCount: 2,
|
||
childAspectRatio: 0.8,
|
||
crossAxisSpacing: 0),
|
||
itemCount: widget.users.length,
|
||
itemBuilder: (BuildContext ctx, index) {
|
||
return Stack(
|
||
children: [
|
||
widget.users[index].uid ==
|
||
UserStore.to.userInfoEntity.value!.uid
|
||
? AgoraVideoView(
|
||
controller: VideoViewController(
|
||
rtcEngine: widget.rtcEngine,
|
||
canvas: const VideoCanvas(uid: 0),
|
||
),
|
||
)
|
||
: AgoraVideoView(
|
||
controller: VideoViewController.remote(
|
||
rtcEngine: widget.rtcEngine,
|
||
canvas: VideoCanvas(
|
||
uid: int.tryParse(widget.users[index].uid)),
|
||
connection:
|
||
RtcConnection(channelId: widget.channelId),
|
||
),
|
||
),
|
||
Positioned(
|
||
left: 4,
|
||
bottom: 4,
|
||
child: Row(
|
||
children: [
|
||
Image.asset(
|
||
'assets/images/meeting_main_own.png',
|
||
width: 24.w,
|
||
height: 24 .h,
|
||
),
|
||
Container(
|
||
height: 20,
|
||
margin: const EdgeInsets.only(left: 4),
|
||
padding:
|
||
const EdgeInsets.only(left: 4, right: 4),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(2),
|
||
color: ColorUtil.Color_0_0_0_96),
|
||
child: widget.users[index].enableMicr == true
|
||
? Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
SizedBox(
|
||
width: 20.w,
|
||
height: 20.h,
|
||
child: LiquidCustomProgressIndicator(
|
||
value: widget.users[index].volume ?? 0.0,
|
||
valueColor: const AlwaysStoppedAnimation(ColorUtil.Color_2_177_136),
|
||
backgroundColor: ColorUtil.Color_255_255_255,
|
||
direction: Axis.vertical,
|
||
shapePath: ViewSvgPath.getMicrpphonePath()
|
||
),
|
||
),
|
||
Text(
|
||
widget.users[index].userName,
|
||
style: TextStyle(
|
||
fontSize: 12.sp,
|
||
color: ColorUtil.Color_255_255_255),
|
||
)
|
||
],
|
||
)
|
||
: Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
Image.asset(
|
||
'assets/images/meeting_main_microphone_open.png',
|
||
width: 20.w,
|
||
height: 20.h,
|
||
),
|
||
Text(
|
||
widget.users[index].userName,
|
||
style: TextStyle(
|
||
fontSize: 12.sp,
|
||
color: ColorUtil.Color_255_255_255),
|
||
)
|
||
],
|
||
),
|
||
)
|
||
],
|
||
),
|
||
)
|
||
],
|
||
);
|
||
}),
|
||
),
|
||
],
|
||
),
|
||
Positioned(
|
||
bottom: 16,
|
||
child: Row(
|
||
children: [
|
||
Container(
|
||
width: 8.w,
|
||
height: 8.h,
|
||
margin: const EdgeInsets.only(right: 6),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(8),
|
||
color: ColorUtil.Color_255_255_255),
|
||
),
|
||
Container(
|
||
width: 8.w,
|
||
height: 8.h,
|
||
margin: const EdgeInsets.only(left: 6),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(8),
|
||
color: ColorUtil.Color_108_108_108),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
@override
|
||
bool get wantKeepAlive => true;
|
||
}
|
||
|