在浏览器里直接播放 S3 视频:presigned URL 播放指南

작성자: OnlinePlayer Team
guides3presigned-urlurl-videostreaming
在浏览器里直接播放 S3 视频:presigned URL 播放指南

在浏览器里直接播放 S3 视频:presigned URL 播放指南

你把一个渲染好的视频上传到了 Amazon S3 存储桶——或者某个兼容 S3 的存储,比如 Cloudflare R2、Backblaze B2、MinIO、Wasabi。存储桶是私有的,本就该如此。现在你只想把这个视频看一眼,或者发给同事一个一点就能播的链接,而不必让对方去装 AWS CLI、也不用在控制台里翻来翻去。

有一种干净的做法,既不用下载文件、也不用把存储桶设成公开:用一个 presigned URL,丢进一个浏览器原生的播放器里。本文会讲清楚 presigned URL 到底是什么、怎么从它出发在浏览器里直接播放 S3 视频,以及那条唯一决定它能不能播的铁律——格式。

presigned URL 到底是什么

presigned URL 是在不放松存储桶权限的前提下,播放私有 S3 内容的那把钥匙。它就是一个指向某个对象的普通 HTTPS 链接,只不过在查询字符串里嵌入了一个临时的、经过密码学签名的令牌。这个签名实际上是在说:「谁拿着这个链接,谁就能读这个特定对象,直到它过期为止。」

有两个特性让它非常适合视频播放:

  • 有时效。 过期时间由你设定——几分钟、几小时、几天都行。过了点,链接就失效了。你不是在创建永久的公开访问,而是在发一张临时通行证。
  • 限定对象。 它只授予对那一个对象的访问权,而不是整个存储桶。你其他的文件依旧私有。

你可以用 AWS SDK、CLI(aws s3 presign s3://your-bucket/video.mp4 --expires-in 3600)或你所用服务商的对应工具生成它。生成结果是一条很长的、以签名参数结尾的 URL。一个浏览器原生的播放器要拉取并播放这个对象,需要的就只是这条 URL——浏览器里不需要 AWS 凭证,也不需要公开存储桶。

为什么浏览器能直接播它

下面这点是让整件事毫不费力的关键:对浏览器来说,presigned URL 不过是一条通过 HTTPS 返回视频字节的 URL。而现代浏览器本身就是视频播放器。Chrome、Edge、Safari、Firefox 都能原生解码 H.264 和 AAC,还带硬件加速,并能直接播放 MP4、WebM 和 HLS 流。

所以,只要 presigned URL 背后的对象是浏览器原生支持的格式,就没有任何东西需要转换、转码或下载。你把 URL 交给播放器,播放器向 S3 请求字节,浏览器的视频引擎就把它们播出来。文件始终留在你的存储桶里,只有视频流抵达你的标签页。这正是我们在 URL 直链播放指南 里深入讲过的同一种直链播放模式——S3 的 presigned URL 不过是它一个表现良好的来源而已。

关键在于,中间没有任何东西被重新上传到某个转换服务。presigned URL 指向的是你自己的 S3 对象;播放器只是从那里读取。你的视频不会被复制到某个第三方主机上去观看。

如何从 presigned URL 播放 S3 视频

  1. 生成 presigned URL。 用 AWS CLI、SDK,或你所用的兼容 S3 服务商的工具。设一个合理的过期时间——长到够看完,短到足够安全。(例如:aws s3 presign s3://my-bucket/clip.mp4 --expires-in 3600。)
  2. 打开播放器。 进入在线视频播放器
  3. 粘贴 URL。 把完整的 presigned URL——连同签名参数一起——粘进 URL 输入框。
  4. 播放。 只要对象是浏览器原生格式,它就会立刻在原文件上串流播放,无需下载。

要分享的话,把同一个 presigned URL 和播放器链接发给同事即可;他们粘贴就能看,自己那边完全不需要 AWS 访问权限。当 URL 过期时,链接就单纯地停止工作了——访问权限会自行收回。

还有一个不大但确实存在、值得做对的小坑:生成 URL 时,确认对象存储时的 Content-Type 是正确的(比如 video/mp4)。如果 S3 把你的 MP4 当成 application/octet-streambinary/octet-stream 来返回,一些浏览器会搞不清自己收到的到底是什么。上传时设好正确的 content type,就能保证内联播放顺畅。

S3 直链串流 vs. 其他做法

做法 下载对象 把存储桶设为公开 presigned URL + 浏览器播放器
开始观看的时间 整个文件下载完之后 即时 原生格式下即时
存储桶保持私有? ——暴露给全世界 ——限定范围、临时访问
本地残留副本? 有,留在磁盘上 ——原地串流
重新上传到某主机? 不适用 不适用 ——直接读取你的 S3 对象
不用 AWS 也能分享? 发文件(巨大) 发链接(但是公开的) 发链接(私有、会过期)

presigned URL 正好命中那个甜蜜点:即时播放、存储桶私有、访问会过期、什么都不下载、什么都不重新托管。

诚实的边界:仅限原生格式

得说精确点,因为这正是「任何 S3 视频都能串流」这类宣传容易过度承诺的地方。

直链播放意味着是浏览器在解码这条流。这对浏览器原生支持的格式有效:

  • MP4 / H.264(AAC 音频): 哪儿都能播。S3 托管视频最靠谱的选择。
  • WebM(VP8/VP9): 支持面很广。
  • HLS(.m3u8): 在受支持的地方能播——如果你在存储桶里打包了自适应流,会很方便。
  • MP4 里的 HEVC / H.265: 在较新且有硬件支持的 Chrome、Edge、Safari 上可用;在别处就没那么普遍了。

不会播放浏览器无法解码的格式。如果你的 S3 对象是 MKV 容器,或用了某种冷门编码,浏览器就没有任何东西能把它渲染出来,而且这套流程里也没有哪个服务器在背后悄悄替你转码。这是有意为之的:这里的价值在于直接读取你的私有对象、原封不动地播放它,而不是把它丢进一个转换工厂里跑一遍。

所以,如果你需要看一个非原生的 S3 对象,诚实的路子是:把它下载到自己的机器上,用一个能解码该格式的本地播放器播放。(如果你宁愿在浏览器里本地解码、也不想装桌面软件,页面内的播放器和 URL 播放指南 能以完整的格式支持处理本地文件——那是一种独立于串流远端 URL 的模式。)更好的做法是,对于你打算用来串流的视频,一开始就在存储桶里存一份 MP4/H.264 版本;它哪儿都能播,毫无摩擦。

再补两条实用提醒。第一,原画质串流需要一条真正给力的网络连接——一个满码率的 4K 对象在弱网下会卡顿;这是播放源文件、而非播放降采样代理文件所要付的代价。第二,留意你的过期时间:如果链接在看到一半时失效了,对象并没有消失,过期的是那个令牌——用一个更长的时间窗重新生成 URL 即可。

常见问题

我必须把 S3 存储桶设成公开吗? 不必。presigned URL 授予的是临时的、限定对象的读取访问权,与此同时你的存储桶保持私有。这正是用它的全部理由。

我的视频会被上传到某个第三方服务器吗? 不会。presigned URL 指向的是你自己的 S3 对象;播放器从那里读取,并在你的浏览器里播放。没有任何东西被重新上传到某个转换主机。

我的 MKV 文件为什么无法从 URL 播放? 浏览器不原生支持 MKV 容器,而这套流程里也没有任何幕后转码。把它下载下来本地播放,或者改在存储桶里存一份 MP4 版本。

我的 MP4 无法内联播放——哪里出问题了? 最常见的原因是对象的 Content-Type 不对。确认它是以 video/mp4 返回的(上传时设好),而不是某种通用的二进制类型。

这对 R2、B2、MinIO、Wasabi 也适用吗? 适用。任何能签发 presigned(已签名)URL 的兼容 S3 存储,工作方式都一样——播放器需要的只是一条能返回视频字节的 URL。

URL 过期之后会怎样? 链接停止工作——访问权限会自动收回。重新生成一个新的 presigned URL 就能再次观看。

结语

presigned URL 加上一个浏览器原生的播放器,是观看 S3 视频最干净的方式:在原文件上即时播放、存储桶保持私有、访问按你设定的时间过期,整个过程中没有任何东西被下载或重新托管——前提是这个对象是浏览器能解码的格式。其余情况,要么下载下来本地播放,要么一开始就在存储桶里存一份 MP4。这就是那条诚实的边界,而对 S3 视频来说,绕着它来设计是件很容易的事。

打开播放器,粘贴你的 S3 链接