import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:app/config/config.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; import '../viewmodel/tch_room_vm.dart'; import 'student_item.dart'; class ContentView extends StatefulWidget { const ContentView({super.key}); @override State createState() => _ContentViewState(); } class _ContentViewState extends State { //声网数据 RtcEngine? _engine; @override void initState() { super.initState(); _initRtc(); } @override void dispose() { super.dispose(); WakelockPlus.disable(); _dispose(); } void _initRtc() async { final vm = context.read(); _engine = createAgoraRtcEngine(); //初始化 RtcEngine,设置频道场景为 channelProfileLiveBroadcasting(直播场景) await _engine!.initialize( RtcEngineContext( appId: Config.swAppId, channelProfile: ChannelProfileType.channelProfileCommunication, ), ); // 启用视频模块 await _engine!.enableVideo(); // 开启本地预览 await _engine!.startPreview(); final status = await _engine!.getConnectionState(); WakelockPlus.enable(); if (status == ConnectionStateType.connectionStateDisconnected) { //加入频道 await _engine!.joinChannel( token: vm.rtcToken!.token, channelId: vm.rtcToken!.channel, uid: vm.rtcToken!.uid, options: ChannelMediaOptions( // 自动订阅所有视频流 autoSubscribeVideo: true, // 自动订阅所有音频流 autoSubscribeAudio: true, // 发布摄像头采集的视频 publishCameraTrack: true, // 发布麦克风采集的音频 publishMicrophoneTrack: true, // 设置用户角色为 clientRoleBroadcaster(主播)或 clientRoleAudience(观众) clientRoleType: ClientRoleType.clientRoleBroadcaster, ), ); } } //销毁 Future _dispose() async { if (_engine != null) { await _engine!.leaveChannel(); await _engine!.release(); } } @override Widget build(BuildContext context) { return Consumer( builder: (context, vm, _) { if (vm.students.isEmpty) { return Align( child: Text( '学生还没入场', style: TextStyle(color: Colors.white), ), ); } //选中的学生 final activeStudent = vm.students.firstWhere((t) => t.userId == vm.activeSId); //其他学生 final otherStudents = vm.students.where((t) => t.userId != vm.activeSId).toList() ..sort((a, b) => b.handup.compareTo(a.handup)); return Padding( padding: const EdgeInsets.all(10), child: Row( spacing: 15, children: [ Expanded( child: Stack( children: [ StudentItem( user: activeStudent, engine: _engine, ), Positioned( top: 0, left: 0, child: Container( width: 150, color: Colors.black, child: AspectRatio( aspectRatio: 1 / 1.2, child: AgoraVideoView( controller: VideoViewController( rtcEngine: _engine!, canvas: const VideoCanvas(uid: 0), ), ), ), ), ), ], ), ), SizedBox( width: 300, child: ListView.separated( itemBuilder: (_, index) { var item = otherStudents.elementAt(index); return SizedBox( height: 250, child: StudentItem( user: item, engine: _engine, ), ); }, separatorBuilder: (_, __) => SizedBox(height: 15), itemCount: otherStudents.length, ), ), ], ), ); }, ); } }