HarmonyOS 7 新特性(二十九)|游戏伴随服务:悬浮协作与质量降级

HarmonyOS 7(API 26)Beta2 的 Graphics Accelerate Kit 新增游戏伴随服务相关能力,可为游戏陪玩类应用提供伴随悬浮控件、游戏状态感知、音频采集与传输、游戏画面采集等基础能力。接入资格、权限和接口以当前官方指南为准。
陪练、战术指导、语音协作和直播助手希望在游戏运行时提供轻量能力,但如果每个应用自行实现悬浮窗、采集与状态轮询,很容易出现抢焦点、过度耗电和隐私提示不清。游戏伴随服务提供系统化基础能力,应用仍需负责会话、授权、质量自适应与异常退出。
本文设计一条“创建陪伴会话—感知游戏状态—按需采集—弱网降级—安全结束”的工程链路。
一、先定义陪伴会话
悬浮控件只是入口,真正的业务对象是会话。它记录目标游戏、参与者、授权范围、状态与质量档位。
type BuddySessionState = 'IDLE' | 'CONNECTING' | 'ACTIVE' | 'PAUSED' | 'ENDING' | 'ENDED'
interface BuddySession {
sessionId: string
gameBundleName: string
state: BuddySessionState
permissions: Array<'MIC' | 'GAME_AUDIO' | 'SCREEN'>
quality: 'audio-only' | 'low' | 'standard'
startedAt?: number
}
页面、悬浮控件和服务端都读取同一会话状态,避免各自创建重复任务。
二、权限按能力逐项申请
用户只使用语音陪练时,不应顺便申请画面采集。麦克风、游戏音频和画面分别说明用途,并允许会话中途关闭。拒绝画面权限后仍可保留文本或语音能力。
interface ConsentPlan {
required: string[]
optional: string[]
}
function planConsent(mode: 'voice' | 'coach-view' | 'stream'): ConsentPlan {
if (mode === 'voice') return { required: ['MIC'], optional: [] }
if (mode === 'coach-view') return { required: ['MIC'], optional: ['SCREEN'] }
return { required: ['MIC', 'SCREEN'], optional: ['GAME_AUDIO'] }
}
系统授权通过不等于业务同意永久有效,每次新会话仍需显示当前采集状态。
三、游戏状态驱动资源生命周期
API 变更资料提供前台、后台、终止以及伴随应用终止等状态。游戏进入后台时暂停高负载画面采集,保留必要信令;游戏终止后结束会话;伴随应用异常退出时服务端进行超时回收。
type GameStatus = 'FOREGROUND' | 'BACKGROUND' | 'TERMINATED' | 'BUDDY_TERMINATED'
function reduceSession(session: BuddySession, status: GameStatus): BuddySession {
if (status === 'FOREGROUND') return { ...session, state: 'ACTIVE' }
if (status === 'BACKGROUND') return { ...session, state: 'PAUSED' }
return { ...session, state: 'ENDING' }
}
不要使用高频轮询猜测状态,应以系统事件为事实源。

四、悬浮控件保持最小交互
悬浮层只保留静音、恢复主界面、网络状态和结束会话等核心操作。复杂设置回到主页面。拖动时避让系统区域,分屏、横屏和刘海设备都要验证。
敏感状态使用明确图标和文字,不能只靠颜色。画面或音频正在采集时始终可见,用户可一键停止。
五、采集管线与 UI 解耦
Game status event
-> Session Controller
-> Capture Policy
-> Audio / Screen Producer
-> Bounded Queue
-> Encoder
-> Transport
-> Remote Coach
UI 销毁不能停止仍有效的会话,悬浮控件关闭也不代表业务结束;只有会话控制器能改变采集所有权。
六、用有界队列防止内存上涨
网络变差时编码速度可能高于上传速度。队列必须设容量,优先丢弃旧视频帧,音频则使用抖动缓冲与质量降级。
class DroppingFrameQueue<T> {
private values: T[] = []
constructor(private capacity: number) {}
push(frame: T) {
if (this.values.length >= this.capacity) this.values.shift()
this.values.push(frame)
}
take(): T | undefined { return this.values.shift() }
}
采集回调不能等待网络发送,否则会反向阻塞游戏。
七、质量自适应优先保护游戏体验
伴随服务是辅助能力,不能抢占游戏的关键资源。检测到高温、丢包、编码积压或游戏帧时间恶化时,按“降低画面帧率—降低分辨率—关闭画面只留音频—暂停会话”逐级降级。
function chooseQuality(m: Metrics): BuddySession['quality'] {
if (m.temperatureLevel >= 5 || m.queueDepth > 20) return 'audio-only'
if (m.lossRate > 0.08 || m.gameFrameP90 > 25) return 'low'
return 'standard'
}
升级质量使用更长稳定窗口,防止网络波动造成档位抖动。
八、连接与消息必须幂等
会话创建、静音、质量切换和结束都携带递增版本。弱网重连后先同步快照,再补增量。结束指令只执行一次,迟到的“恢复”不能重新打开采集。
interface BuddyCommand {
sessionId: string
commandId: string
version: number
type: 'MUTE' | 'UNMUTE' | 'QUALITY' | 'END'
payload?: unknown
}
function accept(lastVersion: number, command: BuddyCommand): boolean {
return command.version > lastVersion
}
九、隐私和安全边界
画面可能包含聊天、通知和账号信息,应采用系统允许的采集范围,并提供暂停、遮挡或敏感页面禁采策略。服务端鉴权绑定会话和参与者,分享链接有时效且不可猜测。
日志不记录原始语音、画面或聊天内容。调试包与生产包使用不同后端与密钥。
十、异常退出与恢复
游戏崩溃、伴随应用被杀、网络中断或对方离开时,会话进入明确终态。下次启动读取未完成记录,询问用户是否恢复;若服务端已结束,则清理本地资源,不自动重新采集。
describe('buddy session reducer', () => {
it('ends when the game terminates', () => {
expect(reduceSession(activeSession, 'TERMINATED').state).toBe('ENDING')
})
})
十一、上线清单
- 会话是唯一事实源,悬浮窗不拥有采集任务;
- 麦克风、游戏音频、画面逐项授权;
- 游戏前后台与终止状态驱动资源释放;
- 采集、编码和网络之间使用有界队列;
- 高温、弱网和游戏卡顿会逐级降级;
- 控制消息带版本、幂等并拒绝迟到指令;
- 采集状态持续可见且可一键停止;
- 崩溃和重启不会自动恢复敏感采集。

结语
游戏伴随服务不是一个悬浮按钮,而是一条与游戏资源竞争的实时媒体链路。把会话、授权、状态感知和质量降级设计成统一控制面,才能在提供陪练与协作价值的同时,把游戏流畅度和用户隐私放在第一位。
官方参考
- Graphics Accelerate Kit API 变更:https://developer.huawei.com/consumer/cn/doc/harmonyos-releases/js-apidiff-graphicsacceleratekit-7002
- Graphics Accelerate Kit:https://developer.huawei.com/consumer/cn/sdk/graphics-accelerate-kit/
更多推荐



所有评论(0)