You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2022.3.11f1播放AWS S3预签名URL视频报错求助

Unity 2022 VideoPlayer播放S3签名URL报错解决方法

问题场景

用Unity的VideoPlayer播放AWS S3预签名URL时,触发以下错误:

AVFoundationVideoMedia error while reading 'url' Context: AVFoundationVideoMedia::OpenForRead found no video tracks
Error details:

VideoPlayer cannot play url: 'url' Cannot read file.

Unity 2021.3.8f1中正常运行,升级到2022.3.11f1后出现问题,要求流式播放,不能先下载再播放。已知Unity 2022版本的VideoPlayer对URL后缀有校验要求,但S3预签名URL格式为https://~?X-Amz-Expires=600&X-Amz-Security-Token=~,不带.mp4后缀。

获取S3预签名URL的代码如下:

public async Task<string> GetObjectUrl(AWSCredentials credentials, string keyName)
{
    using (var client = new AmazonS3Client(credentials, RegionEndpoint.APNortheast2))
    {
        try
        {
            GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
            {
                BucketName = BUCKET_NAME,
                Key = keyName,
                Expires = DateTime.Now.AddMinutes(10)
            };

            return client.GetPreSignedURL(request);
        }
        catch (AmazonS3Exception e)
        {
            // 如果桶或对象不存在
            Debug.Log($"Error: '{e.Message}'");
            return null;
        }
    }
}

解决方法

方法1:给预签名URL添加锚点后缀

在S3返回的预签名URL末尾拼接#.mp4,锚点后的内容不会发送到S3服务器,不影响签名验证,但能让Unity的AVFoundation后端识别为MP4格式。修改代码如下:

var signedUrl = client.GetPreSignedURL(request);
// 拼接锚点后缀,让VideoPlayer识别文件类型
return $"{signedUrl}#.mp4";

方法2:强制指定响应的Content-Type

在生成预签名URL时,添加ResponseContentType参数,让S3返回的响应头包含video/mp4,Unity会根据这个头识别视频类型,不用依赖URL后缀:

GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
    BucketName = BUCKET_NAME,
    Key = keyName,
    Expires = DateTime.Now.AddMinutes(10),
    // 强制返回video/mp4类型
    ResponseContentType = "video/mp4"
};

也可以直接在S3控制台修改视频对象的元数据,将Content-Type设置为video/mp4,这是更规范的做法。

方法3:添加响应头指定文件名后缀

通过ResponseHeaderOverrides设置Content-Disposition,让URL附带正确的文件名后缀,同时不改变S3上的实际对象:

GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
    BucketName = BUCKET_NAME,
    Key = keyName,
    Expires = DateTime.Now.AddMinutes(10),
    ResponseHeaderOverrides = new ResponseHeaderOverrides
    {
        // 若keyName本身带.mp4,直接用Path.GetFileName(keyName)即可
        ContentDisposition = $"attachment; filename=\"{Path.GetFileNameWithoutExtension(keyName)}.mp4\""
    }
};

验证顺序

优先尝试方法2(配置Content-Type),这是符合HTTP规范的解决方案;如果无效,再试方法1(锚点后缀),代码改动最小;方法3适合需要浏览器下载时显示正确文件名的场景。

内容的提问来源于stack exchange,提问作者MayQuartet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:43:17