Flutter接入Agora实现视频通话时摄像头无法打开、画面黑屏求助
故障修复方案
核心问题1:缺失AgoraClient初始化调用
你当前代码仅实例化了AgoraClient对象,未执行官方要求的initialize()初始化方法,SDK没有完成引擎启动、权限申请、频道加入的全流程,导致摄像头没有被拉起、视频帧无法渲染,是黑屏的主要原因。
核心问题2:硬编码延迟不可靠
你使用固定2秒延迟结束加载状态,没有关联Agora初始化的实际进度,经常出现SDK还未完成初始化就渲染视频视图的情况,必然导致黑屏。
其他排查点
- 确认AndroidManifest.xml中已正确添加全量权限,不要遗漏高版本Android适配项:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
- 确认你的App ID开启了视频服务,如果开启了证书校验模式,要保证生成token时传入的UID和Agora初始化时的UID一致,你当前未显式传UID用的默认值0,生成token时也要对应传0。
- iOS设备需额外确认Info.plist中已添加摄像头、麦克风的权限使用描述。
修复后完整代码
import 'dart:convert'; import 'package:agora_uikit/agora_uikit.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:http/http.dart' as http; class VideoCall extends StatefulWidget { const VideoCall({Key? key}) : super(key: key); @override State<VideoCall> createState() => _VideoCallState(); } class _VideoCallState extends State<VideoCall> { late final AgoraClient _client; bool _loading = true; @override void initState() { super.initState(); _initAgora(); } Future<void> _initAgora() async { // 先主动申请权限,避免SDK权限申请失败 await [Permission.camera, Permission.microphone].request(); // 获取Token const link = "https://agora-node-tokenserver.kumaresanjackie.repl.co/access_token?channelName=demoproject"; final response = await http.get(Uri.parse(link)); final data = jsonDecode(response.body); final token = data["token"]; // 初始化AgoraClient配置 _client = AgoraClient( agoraConnectionData: AgoraConnectionData( appId: "4b463a1f8d3448928f4450c9be2db3ba", channelName: 'demoproject', tempToken: token, ), ); // 等待SDK初始化完成再结束加载状态 await _client.initialize(); if (mounted) { setState(() => _loading = false); } } @override void dispose() { // 页面销毁时释放资源,避免摄像头被占用导致下次启动失败 _client.release(); super.dispose(); } @override Widget build(BuildContext context) { return _loading ? const Center(child: CircularProgressIndicator()) : Scaffold( body: SafeArea( child: Stack( children: [ AgoraVideoViewer(client: _client), AgoraVideoButtons(client: _client), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者user10993979
相关产品推荐
相关产品推荐

