跳到正文
AWS for Games · 游戏技术与运营· 一手来源· Benjamin Meyer·· 2026-08-04AI 评分54

使用 Amazon GameLift Streams 构建移动端串流体验

Building a mobile streaming experience with Amazon GameLift Streams

正文 · AI 翻译

移动游戏串流意味着玩家无需通过应用商店下载应用,即可在任何手机或平板上通过浏览器链接直接进入游戏。在本系列的第一部分中,我们使用Amazon GameLift Streams React Starter 示例构建了一个针对桌面优化的串流前端。借助该方案,玩家可以在桌面浏览器中通过键盘和鼠标输入来串流游戏内容。那么移动端呢?

游戏串流取消了玩家在任何设备上的传统下载和安装步骤。在移动设备上,这意味着玩家可以直接通过浏览器链接进入游戏,而无需经过应用商店。然而,与桌面端相比,为移动端构建串流前端会带来另一组不同的挑战:触摸输入取代了键盘和鼠标,某些游戏类型可能需要强制锁定为横屏方向,且移动设备上的平台 API 行为与其桌面端对应 API 不同。

在本文中,我们将介绍构建专用移动前端的关键考量,该前端在解决上述挑战的同时,复用第一部分中现有的后端基础设施和 AWS 云开发工具包(AWS CDK) 部署模式。

考虑构建专用的移动端前端

当你最初考虑面向移动设备用户时,响应式设计实践是一条强有力的路线。媒体查询、布局框架和浏览器内置属性可以简化这一流程。

然而,对于游戏串流,这种方法很快就会失效。桌面端前端是围绕键盘和鼠标输入、窗口模式以及桌面浏览器 API 构建的。这些概念无法直接移植到移动设备上。你需要叠加在串流画面上的基于触摸的虚拟控件,以及强制横屏方向。你还需要针对某些移动平台未实现的 API 寻找替代方案。

一种方法是创建一个独立的项目(mobile-frontend/),连接到相同的后端 API。这样可以让两个前端各自保持专注。桌面版继续针对其输入模型进行优化,移动版则可以就触控、方向和全屏模式做出明确的设计决策,而无需通过条件分支使桌面代码变得复杂。

如何使用渐进式 Web 应用让浏览器消失

在移动端需要解决的第一个问题是浏览器用户界面(UI)。地址栏、导航按钮和状态栏会占用你的流媒体所需的屏幕空间。以独立模式运行的渐进式 Web 应用(PWA)可以移除所有这些元素,而无需提交到应用商店。

首先,创建一个 Web 应用清单(manifest),指定浏览器在安装后应如何运行:

{
  "display": "standalone",
  "orientation": "landscape",
  "background_color": "#000000",
  "theme_color": "#000000"
}

设置 display: standalone 会在用户将你的应用添加到主屏幕时移除浏览器界面。orientation: landscape 字段在 Android 上锁定显示方向。使用黑色背景和主题色,以便系统界面在加载期间与你的流媒体内容融为一体。对于 iOS 有一个重要的注意事项:截至本文撰写时,Safari 完全忽略清单中的 orientation 字段。你无法在 iOS 上以编程方式锁定屏幕方向。取而代之的是,检测设备处于竖屏模式时显示一个提示,要求玩家旋转设备。你可以使用 CSS 变换来旋转视口,但这会破坏触摸事件与流媒体游戏内容之间的坐标映射。玩家的点击会落在错误的位置。你还需要一个 Service Worker 来满足 PWA 安装要求。由于流媒体应用没有离线使用场景,请保持其最小化:一个不缓存任何内容的直通处理,运行 skipWaiting() 和 clients.claim(),意味着 Web 应用在离线时可以优雅地降级。下图是移动端前端作为已安装的 PWA 在 iPad 上运行的示例,它隐藏了浏览器界面,提供完全沉浸式的流媒体体验:A screenshot of a mobile web app running as a PWA on an iPad

图 1:以已安装 PWA 形式在 iPad 上运行的移动端前端

iOS 的变通方案

iOS Safari 对基于浏览器的游戏串流提出了独特的考量。移动 Safari 在某些桌面浏览器广泛支持的 Web API 上的行为有所不同。以下是在这些限制条件下可行的实用方法:

在不使用全屏 API 的情况下实现全屏

在桌面端,你调用 Element.requestFullscreen(),浏览器会处理其余部分。在 iOS 上,对 video 元素调用 fullscreen 会导致 Safari 切换到其自带的视频播放器。该播放器完全脱离了浏览器上下文。在这种情况下,你无法在其上方渲染任何 HTML 覆盖层,这对游戏串流来说是个问题,因为你需要在视频上层叠加触控控件、UI 元素和状态指示器。取而代之的是,无条件地将 position: fixed; inset: 0 应用于 body 元素。这会在你的应用加载的那一刻就填满整个视口,同时保持你的 HTML 层完整以用于覆盖层。结合 PWA 独立模式使用时,没有浏览器 UI 与之竞争,你的串流将占据每一个像素。要在现代 iPhone 上将内容延伸到刘海屏后方,请在你的 viewport meta 标签中添加 viewport-fit: cover。这会告诉 Safari 让你的内容流入安全区域缩进。如有需要,你可以使用 CSS env(safe-area-inset-*) 值进行管理。

解锁音频播放

iOS 会阻止音频自动播放,直到用户执行手势操作。如果尝试在没有先前点击的情况下以编程方式播放音频,浏览器会静默忽略该请求。解决方案是在用户点击"开始流"的同一事件处理程序中调用 audioElement.play()。这一次点击既启动了流,又满足了浏览器的自动播放策略。这里有一个微妙之处:在点击发生时,SDK 可能尚未附加其音频轨道。为处理此问题,还需在音频元素上监听 loadedmetadata 事件,并在该事件触发时再次调用 play()。这样可以捕获音频轨道在初始手势之后才到达的情况。GameLift Streams SDK 要求你在其构造函数中传入独立的 <video> 和 <audio> 元素。保持视频元素静音,让音频通过其专用元素播放。这种分离使得基于手势的解锁成为可能,因为你可以独立于视频来解锁音频元素。

正确检测 iPad

如今,现代 iPad 将 navigator.platform 报告为 MacIntel 而非 iPad。这使得仅通过用户代理无法将它们与 Mac 区分开来。检测 iPad 的一种方法是检查 navigator.platform === 'MacIntel' 和 navigator.maxTouchPoints > 1. 的组合。Mac 笔记本电脑报告零个或一个触摸点,而 iPad 报告的更多。检测之后,应用相同的 iOS 变通方案:PWA 独立模式提示、基于手势的音频解锁以及基于 CSS 的全屏。

添加虚拟手柄控制

如果没有物理手柄,你的玩家需要屏幕上的控制按钮来与串流游戏进行交互。Amazon GameLift Streams Web SDK 接受符合 W3C Gamepad 接口 的自定义手柄对象,这意味着你可以构建一个虚拟手柄,SDK 会将其与物理手柄同等对待。以下截图展示了一个手柄覆盖层的示例:A virtual gamepad overlay showing an analog stick and face buttons, rendered semi-transparently over the game stream

图 2:虚拟手柄控制器覆盖层

要实现此功能:

    1. 创建一个实现 Gamepad 接口的类。它需要 axes(一个包含四个值的数组,用于双摇杆)、buttons(一个包含 17 个按钮对象的数组,对应标准手柄布局),以及一个 connected 属性。使用 200 或更高的索引,以避免与占用索引 0 到 3 的物理控制器发生冲突。
    1. 在流连接后将其注册到 SDK。在 WebRTC 连接建立且输入已附加后,调用 addGamepad():
      sdkRef.current.addGamepad(gamepadRef.current);
  1. 在每次输入变化时调用 processGamepads()。每当触摸事件更新了摇杆轴或按钮状态时,运行 processGamepads() 将当前状态传输到流实例。SDK 不会自动轮询你的手柄,因此你必须在状态发生变化时通知它。

该方法与 SDK 配置中的 autoGamepad: true 共存,后者会自动检测并转发物理蓝牙或 USB 控制器。连接了物理手柄的玩家可以在虚拟控制之外或代替虚拟控制使用它,无需任何额外代码。

复用后端基础设施

在第一篇文章中,我们已经有一个 CDK 堆栈,用于部署桌面前端和一个管理流媒体会话的 API,其中包括一个 Amazon Simple Storage Service(Amazon S3)存储桶、一个 Amazon CloudFront 分发以及一个 AWS WAF WebACL。为了避免重复该堆栈,我们使用 buildAssetPath 属性对其进行参数化,该属性指向您想要部署的任意前端构建目录:

// Desktop frontend
new AmazonGameliftStreamsReactStarterFrontendStack(app,
  'AmazonGameliftStreamsReactStarterFrontendStack', {
  buildAssetPath: './amazon-gamelift-streams-react-starter-frontend/build',
  env: { account, region: 'us-east-1' }, // WAF requires us-east-1
});

// Mobile frontend
new AmazonGameliftStreamsReactStarterFrontendStack(app,
  'AmazonGameliftStreamsReactStarterMobileFrontendStack', {
  buildAssetPath: './mobile-frontend/build',
  env: { account, region: 'us-east-1' }, // WAF requires us-east-1
});

每次实例化都会创建具有相同安全态势的独立资源:地理限制、速率限制和 IP 信誉规则。两者都必须部署到 us-east-1,因为 Amazon CloudFront 分发服务的 AWS WAF WebACL 只能存在于该区域。

先决条件

在部署移动前端之前,您需要:

  • 一个具有部署 CDK 堆栈权限的 AWS 账户
  • 来自第一部分的 API 堆栈已部署(Amazon Cognito用户池和 API Gateway 端点)
  • 已安装 Node.js v18 或更高版本及 npm
  • 已安装 AWS CDK CLI(npm install -g aws-cdk)
  • 已使用目标账户的凭据配置 AWS CLI
  • 已从入门页面下载 Amazon GameLift Streams Web SDK

部署移动前端

以下步骤假设您已按照第一部分中的说明部署了 API 堆栈并配置了 Amazon Cognito。

  1. 将 Amazon GameLift Streams Web SDK 文件复制到 mobile-frontend/src/gamelift-streams-websdk/
  2. 在 mobile-frontend/src/App.tsx 中更新 Amplify 配置,填入 API 堆栈输出中的 Amazon Cognito 用户池 ID、客户端 ID 和 API 端点
  3. 在 mobile-frontend/ 目录中运行 npm install && npm run build
  4. 运行 cdk deploy AmazonGameliftStreamsReactStarterMobileFrontendStack

您的移动前端连接到与桌面版本相同的 Amazon Cognito 用户池和 Amazon API Gateway 端点。无需额外的后端资源。

您现在应该拥有一个如图所示的移动流媒体应用程序:

A screenshot of the complete mobile streaming experience running on an iPad. The game stream fills the viewport with letterboxing to maintain aspect ratio, while virtual joysticks and face buttons overlay the bottom corners for touch input.

图 3:移动流媒体应用程序

清理资源

为避免持续产生费用,在不再需要时删除移动前端堆栈:

cdk destroy AmazonGameliftStreamsReactStarterMobileFrontendStack

这将删除由该堆栈创建的 Amazon CloudFront 分发、Amazon S3 存储桶和 AWS WAF WebACL。如果您还想删除桌面前端和 API,请运行 cdk destroy --all。

如果您使用 AWS 管理控制台 而非 CDK 删除堆栈,则必须先删除 Amazon CloudFront 分发(位于 us-east-1),才能移除 WAF WebACL。

Amazon GameLift Streams 容量在分配时会产生费用。在不使用时,请将流组中的常驻容量和按需容量均设置为零。有关详细信息,请参阅 Amazon GameLift Streams 定价页面。

结论

将游戏串流交付到移动设备会带来超越响应式设计的方案特定挑战。通过构建一个带有虚拟手柄控制的专用移动前端 PWA,你可以提供以触控为先的体验,该体验可在任何带有浏览器的手机或平板电脑上运行,且无需提交应用商店。同样的模式可延伸至其他支持浏览器的设备,例如智能电视或机顶盒,这些设备的输入方式和显示限制与桌面端不同,但串流后端保持不变。

移动端前端实现可在 Amazon GameLift Streams React Starter 示例仓库 的 mobile-frontend/ 目录下找到。克隆该仓库,按照 README 中的部署步骤操作,即可开始将游戏内容流式传输到移动设备。

来源:AWS for Games · 游戏技术与运营 · aws.amazon.com