From ded1698f634e256760744aa441f7ca0397673849 Mon Sep 17 00:00:00 2001 From: fuenmao <980740792@qq.com> Date: Wed, 4 Dec 2024 14:24:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=BB=93=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wgshare/lib/common/api/retrofit_client.dart | 8 ++ .../lib/pages/metting/meeting_main_logic.dart | 74 +++++++++++-------- .../lib/pages/metting/meeting_main_state.dart | 2 + .../lib/pages/metting/meeting_main_view.dart | 18 ++++- .../share/meeting_main_share_view.dart | 23 +++--- .../video/meeting_main_video_view.dart | 12 +-- 6 files changed, 89 insertions(+), 48 deletions(-) diff --git a/wgshare/lib/common/api/retrofit_client.dart b/wgshare/lib/common/api/retrofit_client.dart index d06f6f2..60f8f3d 100644 --- a/wgshare/lib/common/api/retrofit_client.dart +++ b/wgshare/lib/common/api/retrofit_client.dart @@ -74,6 +74,14 @@ abstract class RetrofitClient { @Query("roomNum") String roomNum, ); + /// 设置当前全员观看视频主播 + @POST("/room/show-user") + Future setTvAnchor( + @Query("roomNum") String roomNum, + @Query("uid") String uid, + @Query("uname") String uname, + ); + /// 用户开闭麦 @GET("/room/oper-micr") Future> setMicr( diff --git a/wgshare/lib/pages/metting/meeting_main_logic.dart b/wgshare/lib/pages/metting/meeting_main_logic.dart index 6dd7c02..5a63067 100644 --- a/wgshare/lib/pages/metting/meeting_main_logic.dart +++ b/wgshare/lib/pages/metting/meeting_main_logic.dart @@ -135,25 +135,26 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ /// 申请发言 Future doHttpApplySpeak() async { - BaseStructureResult res = await getClient().applySpeak(state.roomNumber.value); + await getClient().applySpeak(state.roomNumber.value); } /// 用户开闭麦 Future doHttpSetMicr() async { - BaseStructureResult res = await getClient().setMicr(state.roomNumber.value, state.isOpenMicrophone.value, UserStore.to.userInfoEntity.value!.uid); + await getClient().setMicr(state.roomNumber.value, state.isOpenMicrophone.value, UserStore.to.userInfoEntity.value!.uid); } /// 用户开闭摄像头 Future doHttpSetCamer() async { - BaseStructureResult res = await getClient().setCamera(state.roomNumber.value, state.isOpenCamera.value, UserStore.to.userInfoEntity.value!.uid); + await getClient().setCamera(state.roomNumber.value, state.isOpenCamera.value, UserStore.to.userInfoEntity.value!.uid); } /// 结束发言 Future doHttpCancelSpeak() async { - BaseStructureResult res = await getClient().cancelSpeak(state.meetingRoomInfo.value!.id, state.meetingRoomInfo.value!.roomNum, UserStore.to.userInfoEntity.value!.uid); + await getClient().cancelSpeak(state.meetingRoomInfo.value!.id, state.meetingRoomInfo.value!.roomNum, UserStore.to.userInfoEntity.value!.uid); setClientRole("观众"); setMicrophoneOpen(false); setCameraOpen(false); + setScreenShareOpen(false); changePageState(0); } @@ -200,33 +201,48 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{ /// 获取当前全员观看视频主播 Future doHttpGetTvAnchor() async { BaseStructureResult res = await getClient().getTvAnchor(state.roomNumber.value); - /*var s = 2; - if(res.data!.toString().length != 9){ - if(s == 2){ - state.remoteUid.value = "18"; - setEnableVideo(); - changePageState(1); - - state.isOpenCamera.value = true; - setEnableVideo(); - setClientRole("主播"); - changePageState(1); - - *//*var isSaveLive = false; - for(MeetingRoomUser mru in state.cacheUsers.value){ - if(mru.uid == state.remoteUid.value){ - isSaveLive = true; - } - } - if(isSaveLive == true){ - changePageState(1); - }*//* - }*/ state.remoteUid.value = res.data!.toString(); if(res.data!.toString().length != 9){ - Future.delayed(const Duration(milliseconds: 1000), () { - changePageState(1); - }); + if(state.remoteUid.value != UserStore.to.userInfoEntity.value!.uid) { + Future.delayed(const Duration(milliseconds: 1000), () { + changePageState(1); + }); + } + }else{ + if(state.remoteUid.value != UserStore.to.userInfoEntity.value!.screenShareId){ + Future.delayed(const Duration(milliseconds: 1000), () { + changePageState(2); + }); + } + } + } + + /// 设置屏幕共享是否打开 + Future setScreenShareOpen(bool isOpen) async { + state.isOpenShare.value = isOpen; + if(isOpen == true){ + await getClient().setTvAnchor( + state.roomNumber.value, + UserStore.to.userInfoEntity.value!.screenShareId, + UserStore.to.userInfoEntity.value!.userName + ); + await state.rctEngine.value?.startScreenCapture(const ScreenCaptureParameters2(captureAudio: true, captureVideo: true)); + await state.rctEngine.value?.joinChannelEx( + token: state.meetingToken.value, + connection: RtcConnection(channelId: state.roomNumber.value, localUid: int.tryParse(UserStore.to.userInfoEntity.value!.screenShareId)), + options: const ChannelMediaOptions( + publishScreenCaptureAudio: true, + publishScreenCaptureVideo: true, + clientRoleType: ClientRoleType.clientRoleBroadcaster, + )); + }else{ + await state.rctEngine.value?.stopScreenCapture(); + await state.rctEngine.value?.leaveChannelEx( + connection: RtcConnection(channelId: state.roomNumber.value, localUid: int.tryParse(UserStore.to.userInfoEntity.value!.screenShareId)), + options: const LeaveChannelOptions( + stopMicrophoneRecording: false, + stopAllEffect: false + )); } } diff --git a/wgshare/lib/pages/metting/meeting_main_state.dart b/wgshare/lib/pages/metting/meeting_main_state.dart index 72d4a19..ab45e62 100644 --- a/wgshare/lib/pages/metting/meeting_main_state.dart +++ b/wgshare/lib/pages/metting/meeting_main_state.dart @@ -61,6 +61,8 @@ class MeetingMainState { late RxBool isOpenCamera = false.obs; /// 当前视频主播ID late RxString remoteUid = "".obs; + /// 是否启动屏幕共享摄像头 + late RxBool isOpenShare = false.obs; /// 聊天数据 late RxList meetingRoomMsgs = RxList([]); diff --git a/wgshare/lib/pages/metting/meeting_main_view.dart b/wgshare/lib/pages/metting/meeting_main_view.dart index aba1e68..a4defd4 100644 --- a/wgshare/lib/pages/metting/meeting_main_view.dart +++ b/wgshare/lib/pages/metting/meeting_main_view.dart @@ -201,7 +201,13 @@ class MeetingMainPage extends StatelessWidget { // 共享屏幕 Visibility( visible: state.pageState.value == 2, - child: MeetingMainShareComponent() + child: null != state.rctEngine.value + ? MeetingMainShareComponent( + rtcEngine: state.rctEngine.value!, + channelId: state.roomNumber.value, + remoteUid: state.remoteUid.value, + ) + : Container() ), GestureDetector( @@ -357,7 +363,7 @@ class MeetingMainPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - 'assets/images/meeting_main_share_default.png', + state.isSpeak.value == true ? state.isOpenShare.value == true ? 'assets/images/meeting_main_share_open.png' : 'assets/images/meeting_main_share_default.png' : 'assets/images/meeting_main_share_close.png', width: 22.w, height: 22.h, ), @@ -371,7 +377,13 @@ class MeetingMainPage extends StatelessWidget { ], ), onTap: (){ - ToastUtils.getErrFluttertoast(context: context, msg: '开启共享...'); + if(state.isSpeak.value == true){ + if(state.isOpenShare.value == true){ + logic.setScreenShareOpen(false); + }else{ + logic.setScreenShareOpen(true); + } + } }, ), diff --git a/wgshare/lib/pages/metting/share/meeting_main_share_view.dart b/wgshare/lib/pages/metting/share/meeting_main_share_view.dart index af073c4..0b1afed 100644 --- a/wgshare/lib/pages/metting/share/meeting_main_share_view.dart +++ b/wgshare/lib/pages/metting/share/meeting_main_share_view.dart @@ -1,3 +1,4 @@ +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'; @@ -7,7 +8,11 @@ import 'meeting_main_share_logic.dart'; import 'meeting_main_share_state.dart'; class MeetingMainShareComponent extends StatelessWidget { - MeetingMainShareComponent({Key? key}) : super(key: key); + MeetingMainShareComponent({super.key, required this.rtcEngine, required this.channelId, required this.remoteUid}); + + final RtcEngine rtcEngine; + final String channelId; + final String remoteUid; final MeetingMainShareLogic logic = Get.put(MeetingMainShareLogic()); final MeetingMainShareState state = Get.find().state; @@ -18,15 +23,13 @@ class MeetingMainShareComponent extends StatelessWidget { child: Stack( alignment: Alignment.center, children: [ - Container( - decoration: BoxDecoration( - image: DecorationImage( - fit: BoxFit.fill, - image: NetworkImage( - "https://tse4-mm.cn.bing.net/th/id/OIP-C.acWMNnQ04Ks6Bh2b9Zq8XwHaKF?rs=1&pid=ImgDetMain", - ), - ), - )), + AgoraVideoView( + controller: VideoViewController.remote( + rtcEngine: rtcEngine, + canvas: VideoCanvas(uid: int.tryParse(remoteUid)), + connection: RtcConnection(channelId: channelId), + ), + ), Positioned( bottom: 110, child: Image.asset( diff --git a/wgshare/lib/pages/metting/video/meeting_main_video_view.dart b/wgshare/lib/pages/metting/video/meeting_main_video_view.dart index f1c1251..e47ceb4 100644 --- a/wgshare/lib/pages/metting/video/meeting_main_video_view.dart +++ b/wgshare/lib/pages/metting/video/meeting_main_video_view.dart @@ -20,12 +20,12 @@ class MeetingMainVideoComponent extends StatefulWidget { required this.onHangUpTap, required this.users}); - RtcEngine rtcEngine; - String channelId; - String remoteUid; - bool isOpenCamera; - List users; - Function onHangUpTap; + final RtcEngine rtcEngine; + final String channelId; + final String remoteUid; + final bool isOpenCamera; + final List users; + final Function onHangUpTap; @override State createState() => _MeetingMainVideoComponentState();