Flutter使用video_player加载视频遇ExoPlayer UnknownHostException问题
Flutter视频加载失败:ExoPlayer UnknownHostException 排查与解决
问题核心
视频可正常上传至后端,但加载时触发ExoPlayer的UnknownHostException(no network)错误,添加android:usesCleartextTraffic="true"后仍未解决,控制器初始化后isInitialized始终为false。
排查与解决步骤
1. 先确认视频URL的有效性
直接打印拼接后的完整URL,复制到浏览器或用curl命令测试,确认视频能正常访问:
print('视频加载地址: http://example.com${video.file}');
- 重点检查
video.file是否以/开头,比如如果后端存储路径是/media/video.mp4,拼接后应该是http://example.com/media/video.mp4,缺斜杠会导致无效地址。
2. 验证设备/模拟器的网络连通性
- 如果是本地后端服务,Android模拟器不能直接用
localhost,要替换成10.0.2.2(对应主机的localhost); - 用
adb shell ping example.com测试模拟器是否能解析后端域名,或者用WebView加载该URL,确认网络通路正常。
3. 完善Android网络配置
确保AndroidManifest.xml里的配置齐全:
<!-- 必须添加网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <application ... android:usesCleartextTraffic="true"> <!-- 允许明文HTTP -->
如果是Android 10+,还可以添加网络安全配置文件res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>
然后在AndroidManifest.xml的application标签里引用:
android:networkSecurityConfig="@xml/network_security_config"
4. 修正控制器初始化的异步逻辑
原代码的异步处理存在问题,要么await未正确捕获错误,要么print时机过早(初始化未完成就打印状态)。以下是修正后的代码:
final String fullVideoUrl = 'http://example.com${video.file}'; final VideoPlayerController videoController = VideoPlayerController.networkUrl(Uri.parse(fullVideoUrl)); try { // 等待初始化完成 await videoController.initialize(); setState(() { _hasVideo = true; }); // 初始化完成后再检查状态 if (videoController.value.isInitialized) { print('视频时长: ${videoController.value.duration}'); if (videoController.value.duration.inMinutes <= 45) { _setPostVideoFile(pickedVideo); } } else { print('视频控制器初始化未完成'); _onError('初始化未完成'); } } catch (error) { print('视频加载错误: $error'); _onError(error); }
注意:在页面销毁时一定要释放控制器,避免内存泄漏:
@override void dispose() { videoController.dispose(); super.dispose(); }
额外提示
- 如果是测试环境,可暂时关闭模拟器的代理设置,避免代理导致的网络不通;
- 检查后端服务器是否有防火墙或跨域限制,确保Flutter客户端的IP能访问视频资源。
内容的提问来源于stack exchange,提问作者Ananth
相关产品推荐
相关产品推荐

