Flutter使用video_player与Chewie无法加载自签名HTTPS视频的问题咨询
自签名HTTPS视频在Flutter video_player + Chewie场景下的加载解决方案
你遇到的ExoPlayer Source error本质原因是:video_player插件在Android端默认基于原生ExoPlayer实现,证书校验逻辑完全遵循系统级的可信根证书列表规则,自签名证书不在系统信任范围内,因此请求会被直接拒绝;iOS端则是被ATS传输安全策略拦截。这两个平台的插件本身没有在Dart层暴露自定义证书校验的配置入口,需要从平台侧做定向配置解决。Chewie作为video_player的上层UI封装,本身不处理网络请求和证书校验逻辑,只要VideoPlayerController能正常完成视频加载,Chewie侧不需要做任何额外修改。
推荐方案:定向信任自签名证书(生产环境适用)
这种方案不会全局放宽安全策略,仅针对你的云端资源域名开放自签名证书的信任,安全性最高,不需要改造插件源码。
Android端配置
- 导出服务端自签名证书的DER格式文件,重命名为纯小写无特殊字符的文件名(比如
cloud_cert.der),放到android/app/src/main/res/raw/目录下(没有raw文件夹就自己新建) - 在
android/app/src/main/res/xml/目录下新建network_security_config.xml,填入定向域名信任规则:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <!-- 替换成你实际的云端资源域名 --> <domain includeSubdomains="true">your-cloud-domain.com</domain> <trust-anchors> <!-- 替换成你刚才放的证书文件名,不带后缀 --> <certificates src="@raw/cloud_cert"/> </trust-anchors> </domain-config> </network-security-config> - 打开
android/app/src/main/AndroidManifest.xml,在<application>标签内引用上面写的网络安全配置:
ExoPlayer会自动读取系统网络安全配置完成证书校验,不需要额外修改插件代码。注意配置完成后必须重新构建APP,热重载不生效。<application android:networkSecurityConfig="@xml/network_security_config" <!-- 其他原有配置保持不变 --> >
iOS端配置
- 把你的DER格式自签名证书拖进Xcode项目的Bundle目录,确保证书目标和APP Target绑定
- 在
Info.plist中添加仅针对目标域名的ATS例外规则,不要全局放开ATS限制:
同时实现<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <!-- 替换成你实际的云端资源域名 --> <key>your-cloud-domain.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSIncludesSubdomains</key> <true/> <key>NSRequiresCertificateTransparency</key> <false/> </dict> </dict> </dict>AVAssetResourceLoaderDelegate的证书校验逻辑,比对服务端返回的证书和Bundle内打包的自签名证书一致时放行请求,完成后重启APP即可正常加载。
临时调试方案(不建议生产使用)
如果仅做本地调试,暂时不想打包证书进APP:
- 可以fork当前使用的
video_player插件,在Android端把ExoPlayer默认的HTTP请求栈替换为配置了跳过所有证书校验TrustManager的OkHttp实例 - iOS端可以临时全局放开ATS限制,但要注意这个配置会让你的APP所有HTTPS请求都跳过证书校验,存在极高的中间人攻击风险,绝对不能提交到生产环境的代码分支
替代无侵入方案
如果不想修改任何平台原生配置,可以在Dart层通过自定义HTTP客户端,带自签名校验逻辑拉取完整的视频流到APP的临时目录,再通过VideoPlayerController.file()加载本地临时文件完成播放。缺点是这种方式不支持流媒体边下边播的快速进度拖拽,大视频文件会占用额外的临时存储空间,适合小体积的短视频场景。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

