Browse Source

feat(video_call): 添加视频通话远端视频显示功能

- 集成 agora_rtc_engine 依赖库
- 添加 RTCManager 实例用于管理实时通信
- 实现 _buildBackground 方法用于构建背景显示
- 在视频通话接通时显示远端用户视频流
- 当 remoteUid 为空时从 RTCManager 获取远端用户列表
- 保持原有头像显示逻辑作为默认背景
- 使用 Obx 监听响应式变量确保实时更新
master
Jolie 3 months ago
parent
commit
dc81135c45
1 changed files with 75 additions and 19 deletions
  1. 94
      lib/widget/message/video_call_overlay_widget.dart

94
lib/widget/message/video_call_overlay_widget.dart

@ -1,8 +1,10 @@
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/controller/message/call_controller.dart';
import 'package:dating_touchme_app/extension/ex_widget.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/pages/message/video_call_page.dart';
import 'package:dating_touchme_app/rtc/rtc_manager.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
@ -30,6 +32,7 @@ class _VideoCallOverlayWidgetState extends State<VideoCallOverlayWidget> {
Offset _position = Offset.zero;
bool _isDragging = false;
final CallController _callController = CallController.instance;
final RTCManager _rtcManager = RTCManager.instance;
@override
void initState() {
@ -59,6 +62,76 @@ class _VideoCallOverlayWidgetState extends State<VideoCallOverlayWidget> {
});
}
///
Widget _buildBackground() {
return Obx(() {
// Obx 访
final callSession = _callController.currentCall.value;
final isVideoCall = callSession != null && callSession.callType == CallType.video;
final isConnected = callSession != null && _callController.callDurationSeconds.value > 0;
final remoteUid = _callController.remoteUid.value;
final remoteUsers = _rtcManager.remoteUsersNotifier.value;
//
if (isVideoCall && isConnected && remoteUid != null) {
final engine = _rtcManager.engine;
if (engine != null) {
final remoteVideoViewController = VideoViewController(
rtcEngine: engine,
canvas: VideoCanvas(uid: remoteUid),
);
return SizedBox(
width: 100.w,
height: 100.w,
child: AgoraVideoView(
controller: remoteVideoViewController,
),
);
}
}
// remoteUid RTCManager
if (isVideoCall && isConnected && remoteUid == null && remoteUsers.isNotEmpty) {
final firstRemoteUid = remoteUsers.first;
final engine = _rtcManager.engine;
if (engine != null) {
_callController.remoteUid.value = firstRemoteUid;
final remoteVideoViewController = VideoViewController(
rtcEngine: engine,
canvas: VideoCanvas(uid: firstRemoteUid),
);
return SizedBox(
width: 100.w,
height: 100.w,
child: AgoraVideoView(
controller: remoteVideoViewController,
),
);
}
}
//
return Container(
width: 100.w,
height: 100.w,
color: Colors.black,
child: widget.targetAvatarUrl != null && widget.targetAvatarUrl!.isNotEmpty
? CachedNetworkImage(
imageUrl: widget.targetAvatarUrl!,
fit: BoxFit.cover,
errorWidget: (context, url, error) => Image.asset(
Assets.imagesUserAvatar,
fit: BoxFit.cover,
),
)
: Image.asset(
Assets.imagesUserAvatar,
fit: BoxFit.cover,
),
);
});
}
///
String _formatDuration(int seconds) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
@ -123,25 +196,8 @@ class _VideoCallOverlayWidgetState extends State<VideoCallOverlayWidget> {
borderRadius: BorderRadius.circular(8.w),
child: Stack(
children: [
//
Container(
width: 100.w,
height: 100.w,
color: Colors.black,
child: widget.targetAvatarUrl != null && widget.targetAvatarUrl!.isNotEmpty
? CachedNetworkImage(
imageUrl: widget.targetAvatarUrl!,
fit: BoxFit.cover,
errorWidget: (context, url, error) => Image.asset(
Assets.imagesUserAvatar,
fit: BoxFit.cover,
),
)
: Image.asset(
Assets.imagesUserAvatar,
fit: BoxFit.cover,
),
),
//
_buildBackground(),
//
Container(
color: Colors.black.withOpacity(0.4),

Loading…
Cancel
Save