1.全员观看http接口以及socket回调

2.用户开闭麦接口
3.用户开闭摄像头接口
4.视频-右上角观看自己
5.视频-大屏远端观看别人
This commit is contained in:
fuenmao 2024-12-02 14:59:14 +08:00
parent e1e6550e31
commit 3a3f9cb665
5 changed files with 185 additions and 89 deletions

View File

@ -67,4 +67,26 @@ abstract class RetrofitClient {
@Field("roomNum") String roomNum,
@Field("userId") String userId,
);
///
@GET("/room/show-user")
Future<BaseStructureResult<String>> getTvAnchor(
@Query("roomNum") String roomNum,
);
///
@GET("/room/oper-micr")
Future<BaseStructureResult<String>> setMicr(
@Query("roomNum") String roomNum,
@Query("enableMicr") bool enableMicr,
@Query("uid") String uid,
);
///
@GET("/room/oper-camera")
Future<BaseStructureResult<String>> setCamera(
@Query("roomNum") String roomNum,
@Query("enableCamera") bool enableCamera,
@Query("uid") String uid,
);
}

View File

@ -6,6 +6,7 @@ import 'package:get/get.dart';
import 'package:signalr_core/signalr_core.dart';
import 'package:wgshare/common/store/user_store.dart';
import 'package:wgshare/utils/count_microphone_volume.dart';
import 'package:wgshare/utils/storage.dart';
import '../../common/config/request_config.dart';
import '../../common/mixins/request_tool_mixin.dart';
import '../../common/models/common/base_structure_result.dart';
@ -135,14 +136,27 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
BaseStructureResult res = await getClient().applySpeak(state.roomNumber.value);
}
///
Future<void> doHttpSetMicr() async {
BaseStructureResult res = await getClient().setMicr(state.roomNumber.value, state.isOpenMicrophone.value, UserStore.to.userInfoEntity.value!.uid);
}
///
Future<void> doHttpSetCamer() async {
BaseStructureResult res = await getClient().setCamera(state.roomNumber.value, state.isOpenCamera.value, UserStore.to.userInfoEntity.value!.uid);
}
///
Future<void> doHttpCancelSpeak() async {
BaseStructureResult res = await getClient().cancelSpeak(state.meetingRoomInfo.value!.id, state.meetingRoomInfo.value!.roomNum, UserStore.to.userInfoEntity.value!.uid);
setClientRole("观众");
setMicrophoneOpen(false);
setCameraOpen(false);
changePageState(0);
}
///
void setMicrophoneOpen(bool isOpen){
Future<void> setMicrophoneOpen(bool isOpen) async{
state.isOpenMicrophone.value = isOpen;
for(var i = 0; i < state.cacheUsers.value.length; i++){
if(state.cacheUsers.value[i].uid == UserStore.to.userInfoEntity.value!.uid){
@ -150,21 +164,42 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
}
}
state.users.value = state.cacheUsers.value;
if(isOpen == true){
setClientRole("主播");
}else{
setClientRole("观众");
}
setEnableLocalAudio(isOpen);
doHttpSetMicr();
}
///
void setCameraOpen(bool isOpen){
state.isOpenCamera.value = isOpen;
setEnableLocalVideo(isOpen);
if(state.isOpenMicrophone.value == false){
setMicrophoneOpen(isOpen);
}
if(isOpen == true){
setEnableLocalVideo(isOpen);
setClientRole("主播");
changePageState(1);
doHttpGetTvAnchor();
}else{
setClientRole("观众");
changePageState(0);
}
doHttpSetCamer();
}
///
Future<void> doHttpGetTvAnchor() async {
BaseStructureResult res = await getClient().getTvAnchor(state.roomNumber.value);
if(res.data!.toString().length != 9){
state.remoteUid.value = res.data!;
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);
}*/
}
}
@ -230,6 +265,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
state.isSpeak.value = true;
state.isOpenMicrophone.value = true;
setClientRole("主播");
setEnableLocalAudio(true);
doHttpSetMicr();
}
}else{
debugPrint("wgs输出===Socket-停止发言:${e?[0]}--${e?[1]}");
@ -244,6 +281,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
state.isSpeak.value = false;
state.isOpenMicrophone.value = false;
setClientRole("观众");
setEnableLocalAudio(false);
doHttpSetMicr();
}
}
update();
@ -317,6 +356,18 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
state.isOpenMicrophone.value = false;
}
});
///
state.hubConnection.value?.on("ShowUser", (e){
// var jsonStr = const Utf8Decoder().convert(json.encode(e).runes.toList());
var jsonStr = json.encode(e);
List list = json.decode(jsonStr);
/*if(list[0].toString().length != 9){
state.remoteUid.value = list[0].toString();
}*/
doHttpGetTvAnchor();
debugPrint("wgs输出===Socket-设置新的全员观看视频主播:${list[0]}");
});
}
///
@ -365,7 +416,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
//
await state.rctEngine.value?.enableAudioVolumeIndication(interval: 200, smooth: 3, reportVad: true);
//
await state.rctEngine.value?.enableAudio();
setEnableLocalAudio(true);
joinMeetingToRtc();
@ -503,9 +554,19 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
await state.rctEngine.value?.setEnableSpeakerphone(mode == 1 ? false : true);
}
///
///
Future<void> setEnableLocalAudio(bool enabled) async {
if(enabled == true){
//
await state.rctEngine.value?.enableAudio();
}else{
//
await state.rctEngine.value?.disableAudio();
}
}
///
Future<void> setEnableLocalVideo(bool enabled) async {
state.isOpenCamera.value = enabled;
if(enabled == true){
//
await state.rctEngine.value?.enableVideo();

View File

@ -59,6 +59,8 @@ class MeetingMainState {
late RxDouble microphoneVolume = 0.0.obs;
///
late RxBool isOpenCamera = false.obs;
/// ID
late RxString remoteUid = "".obs;
///
late RxList<MeetingRoomMsg> meetingRoomMsgs = RxList([]);

View File

@ -177,7 +177,12 @@ class MeetingMainPage extends StatelessWidget {
Visibility(
visible: state.pageState.value == 1,
child: null != state.rctEngine.value
? MeetingMainVideoComponent(rtcEngine: state.rctEngine.value!, channelId: state.roomNumber.value,isOpenCamera: state.isOpenCamera.value)
? MeetingMainVideoComponent(
rtcEngine: state.rctEngine.value!,
channelId: state.roomNumber.value,
isOpenCamera: state.isOpenCamera.value,
remoteUid: state.remoteUid.value,
)
: Container()
),

View File

@ -9,10 +9,16 @@ import 'meeting_main_video_logic.dart';
import 'meeting_main_video_state.dart';
class MeetingMainVideoComponent extends StatelessWidget {
MeetingMainVideoComponent({super.key, required this.rtcEngine, required this.channelId, required this.isOpenCamera});
MeetingMainVideoComponent(
{super.key,
required this.rtcEngine,
required this.channelId,
required this.isOpenCamera,
required this.remoteUid});
final RtcEngine rtcEngine;
final String channelId;
final String remoteUid;
final bool isOpenCamera;
final MeetingMainVideoLogic logic = Get.put(MeetingMainVideoLogic());
@ -38,82 +44,81 @@ class MeetingMainVideoComponent extends StatelessWidget {
debugPrint('wgs输出===$index');
},
children: <Widget>[
Container(
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",
),
Stack(
alignment: Alignment.center,
children: [
remoteUid != ""
? AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: rtcEngine,
canvas: VideoCanvas(uid: int.tryParse(remoteUid)),
connection: RtcConnection(channelId: channelId),
),
)),
Positioned(
bottom: 110,
child: Image.asset(
'assets/images/meeting_main_hang_up.png',
width: 50.w,
height: 50.h,
)
: const CircularProgressIndicator(),
Positioned(
bottom: 110,
child: Image.asset(
'assets/images/meeting_main_hang_up.png',
width: 50.w,
height: 50.h,
),
),
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),
)
],
),
),
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),
)
],
),
),
),
///
Positioned(
),
///
Visibility(
visible: isOpenCamera,
child: Positioned(
top: 58,
right: 12,
right: 13,
child: Stack(
children: [
Visibility(
visible: isOpenCamera,
child: SizedBox(
width: 120.w,
height: 150.h,
SizedBox(
width: 120,
height: 150,
child: Center(
child: isOpenCamera
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: rtcEngine,
canvas: VideoCanvas(uid: int.parse(UserStore.to.userInfoEntity.value!.uid)),
),
)
controller: VideoViewController(
rtcEngine: rtcEngine,
canvas: const VideoCanvas(uid: 0),
),
)
: const CircularProgressIndicator(),
),
),
),
Positioned(
left: 4,
bottom: 4,
@ -127,20 +132,22 @@ class MeetingMainVideoComponent extends StatelessWidget {
Container(
height: 15,
margin: const EdgeInsets.only(left: 4),
padding: const EdgeInsets.only(left: 4, right: 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(
/*Image.asset(
'assets/images/meeting_main_microphone_open.png',
width: 13.w,
height: 14.h,
),
SizedBox(width: 4.w),
SizedBox(width: 4.w),*/
Text(
'晓晓',
UserStore
.to.userInfoEntity.value!.userName,
style: TextStyle(
fontSize: 10.sp,
color: ColorUtil.Color_185_184_184),
@ -153,15 +160,14 @@ class MeetingMainVideoComponent extends StatelessWidget {
)
],
),
)
],
),
),
)
],
),
Container(
color: ColorUtil.Color_57_57_57,
child: GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.8,
crossAxisSpacing: 0),
@ -178,8 +184,7 @@ class MeetingMainVideoComponent extends StatelessWidget {
"https://tse1-mm.cn.bing.net/th/id/OIP-C.hdhK40Dw3yN_2mjNQNqFCgAAAA?w=186&h=186&c=7&r=0&o=5&pid=1.7",
),
),
)
),
)),
Positioned(
left: 4,
bottom: 4,
@ -193,7 +198,8 @@ class MeetingMainVideoComponent extends StatelessWidget {
Container(
height: 15,
margin: const EdgeInsets.only(left: 4),
padding: const EdgeInsets.only(left: 4, right: 4),
padding:
const EdgeInsets.only(left: 4, right: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: ColorUtil.Color_0_0_0_96),