语音平台最近一直在开发一个语音系统,整个项目设计其实是参考的来来语音
具有的功能也非常的复杂,主要的功能当然是聊天系统了。
这里就重点讲述一下聊天系统的开发实现步骤吧
首先,系统是基于腾讯云的IM语音开放的SDK开发的
用到的插件:
rtc_room_engine: 腾讯语音房间
因为腾讯方面SDK都是使用的provider,我这边也直接使用的provider进行的设计
首先是创建一个房间的管理对象room_provider
涉及数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| class RoomProvider with ChangeNotifier{ /// 是否是房主 bool get owner => _roomInfo?.ownerId == SpUtil.getUserId();
/// 是否是管理员 bool _admin = false; bool get admin => _admin;
// 关闭声音 bool _closeMicrophone = false; bool get closeMicrophone => _closeMicrophone;
/// 房间信息 TUIRoomInfo? _roomInfo; TUIRoomInfo? get roomInfo => _roomInfo;
/// 房间信息 RoomEntity? _roomData; RoomEntity? get roomData => _roomData;
/// 当前用户信息 TUIUserInfo? _userInfo; TUIUserInfo? get userInfo => _userInfo;
/// 房主信息 TUIUserInfo? _roomOwner; TUIUserInfo? get roomOwner => _roomOwner;
/// 座位信息 List<TUISeatInfo> _seatList = []; List<TUISeatInfo> get seatList => _seatList;
/// 当前用户的座位信息 RoomSeatGiftEntity? _userSeat; RoomSeatGiftEntity? get userSeat => _userSeat;
/// 座位用户信息 List<RoomSeatGiftEntity?> _seatUserList = []; List<RoomSeatGiftEntity?> get seatUserList => _seatUserList;
/// 所有用户信息 List<UserEntity> _userList = []; List<UserEntity> get userList => _userList;
num _usersTotal = 0; num get usersTotal => _usersTotal;
/// 消息 List<MessageInfo> _messageList = []; List<MessageInfo> get messageList => _messageList;
/// 是否被禁言 bool _isMessageDisable = false; bool get isMessageDisable => _isMessageDisable;
/// 滚动试图 late AutoScrollController autoController = AutoScrollController( viewportBoundaryGetter: () => Rect.fromLTRB(0, 0, 0, MediaQuery.of(Get.context!).padding.bottom), axis: Axis.vertical, );
/// 礼物特效队列 List<Map> _giftSvgaList = []; List<Map> get giftSvgaList => _giftSvgaList; Map? _giftSvga = null; Map? get giftSvga => _giftSvga;
}
|
涉及的API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| /// 主持人创建房间 Future<bool> createRoom(String name, int roomTypeId)
// 销毁房间接口,销毁房间必须由房间所有者发起,销毁房间之后房间不可进入。 Future<TUIActionCallback> destroyRoom()
/// 进入房间接口。 Future<bool> enterRoom(String roomId, bool ifowner, {bool? offRoute})
/// WebSocket事件 void _onWebSocketMessageReceive(WebSocketMessageInfo messageInfo)
/// 离开房间接口,用户在执行 enterRoom 之后可通过 exitRoom 离开房间。 Future<bool> exitRoom() async
/// 上麦 Future<String?> takeSeat(index) async
/// 打开本地麦克风。 Future<bool> openVoice() async
/// 获取房间信息 Future<RoomEntity?> getRoomData()
/// 发送文本消息。 Future<TUIActionCallback> sendTextMessage(MessageInfo info)
|
消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| enum MessageType { /// 进入房间 enter(0),
/// 公告 announcement(1),
/// 礼物 gift(2),
/// 用户发的消息 user(3),
/// 声明 statement(4),
/// @TA ta(5);
const MessageType(this.type);
final int type;
int getType() { return type; } }
|
WebSocket消息类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| enum WebSocketMessageType { /// 热度变化 hot(0),
/// 座位变化 seat(1),
/// 人数变化 people(2),
/// 清屏 clean(3),
/// 房间信息修改 updateRoom(4),
/// 管理员修改 admin(5),
/// 礼物 gift(6),
/// 上麦 takeSeat(10),
/// 下麦 leaveSeat(11),
/// 禁麦 microphone(12),
/// 踢出 out(13),
/// 禁言用户 disableMessage(14),
/// 心跳事件 beat(15);
const WebSocketMessageType(this.type); final int type;
static WebSocketMessageType initByInt(int number) => WebSocketMessageType.values .firstWhere((activity) => activity.type == number);
int getInt() => type; }
|