以下classic 代码片段无法从Bunny CDN获取视频

@override
void initState() {
  super.initState();
  controller = VideoPlayerController.networkUrl(Uri.parse(widget.video),
                          httpHeaders: {"AccessKey": CDN_READ_ONLY_TOKEN});
  controller.initialize();
}

我得到以下错误:

E/ExoPlayerImplInternal(14202): Playback error
E/ExoPlayerImplInternal(14202):   com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:644)
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:616)
E/ExoPlayerImplInternal(14202):       at android.os.Handler.dispatchMessage(Handler.java:103)
E/ExoPlayerImplInternal(14202):       at android.os.Looper.loop(Looper.java:224)
E/ExoPlayerImplInternal(14202):       at android.os.HandlerThread.run(HandlerThread.java:67)
E/ExoPlayerImplInternal(14202):   Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 401
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:413)
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:263)
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:84)
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1005)
E/ExoPlayerImplInternal(14202):       at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
E/ExoPlayerImplInternal(14202):       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal(14202):       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal(14202):       at java.lang.Thread.run(Thread.java:919)

然而,我认为问题出在访问密钥上:

  • 这款应用在iOS上运行完美
  • 来自应用程序中任何其他位置的正常GET请求具有正确的标头,可以按预期工作.

在判断了GitHub等的潜在解决方案之后,我try 修改AndroidManifest.xml文件并添加以下行

<uses-permission android:name="android.permission.INTERNET"/>
<application android:usesCleartextTraffic="true"/>

我还try 将AccessKey直接集成到URL中,如下所示:

https://storage.bunnycdn.com/XXX-YYY/video-acbce1cce090476a95b03cd485a1e54d.mp4?AccessKey=XXX

该链接直接在浏览器中打开视频,在iOS上也有效,但在Android上失败,并出现相同的错误.

最后,我在GitHub上发现了这个关于自签名SSL证书的帖子,但我不确定这是不是问题所在,因为该错误只抱怨授权,而不是服务器的证书.

https://github.com/flutter/flutter/issues/75995

然而,我添加了以下NETWORK_SECURITY_CONFIG,这并没有解决问题

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">storage.bunnycdn.com</domain>
        <trust-anchors>
            <!-- Trust all certificates -->
            <certificates src="user" />
            <certificates src="system" />
        </trust-anchors>
    </domain-config>
</network-security-config>

以前有其他人处理过类似的事情吗?

推荐答案

不能直接从存储区拉取.你应该建立一个拉区,并通过那里访问链接.最重要的是,您将不需要accessKey

Flutter相关问答推荐

具有可变高度小部件的SingleChildScrollView内的列

如何使用Firebase Firestore来获取外部集合中的文档子集合中的文档

BlocBuilder仅生成一次,并在后续发出时停止重建

悬停时打开Flutter 下拉按钮

在Flutter 中每次点击按钮时都很难调用自定义函数

来自FirebaseAuth的错误DisplayName和邮箱在Flutter应用程序中给出错误

如何使文本表格域在抖动中变圆?

我如何在Android 13中通过Flutter应用程序打开文件(不是图像、视频或音频)?

GridView 渲染项目之间有微小的间隙

在 Dart 中按土耳其语字母顺序对字符串进行排序

Flutter记录返回类型问题

Flutter Riverpod 对提供者状态的变化做出react

reactive_flutter_BLE - 应用找到设备但无法连接(并读取 BLE 数据)

Flutter - 如何将按钮对齐到行的右侧

如何在手势检测器中获得涟漪效应

使用 onPressed 切换到另一个屏幕无法正常工作

如何在 tabBar 中的选项卡之间制作垂直线?

在 Flutter 中,如何使用文本字段和方形图像进行行布局

如何在没有上下文的情况下使用国际Flutter ?

Flutter Bloc Todo 示例 - 收听存储库中的单个 todo