Files
youle_app_ios_v2/ylgamehall/Source/Bridge/Handlers/RemoteAudioHandler.swift
T
joywayerandClaude Opus 4.7 0602b9d4b6 Phase 3.A:srcIsloop 本地音频 + 3.B/3.C/3.D handler stub
3.A 本地音频完整落地(与 msext NewRootVC initJSdata 等价):

  Source/Audio/AudioPlayer.swift(@MainActor 状态机):
    - playOnce(url) 单次按钮音;buttonPlayers 数组保活池避免多次点击
      互相打断(duration + 0.5s 后清理)
    - loopBackground(url, type:) 循环背景音;numberOfLoops = -1 +
      backgroundType 记录用于同名停止
    - stopBackground(type:) 同名校验后才停止(msext 同款语义)

  Source/Bridge/Handlers/LocalAudioHandler.swift:
    - 注册 srcIsloop handler(@MainActor enum)
    - 入参 src + isloop,按 0/1/-1 分支调 AudioPlayer.shared 对应方法
    - audioFileURL 路径:{Caches}/{gamedir}/{gamestart}/assets/wav/{src}
      与 msext NewRootVC 路径约定 1:1(H5 zip 内 assets/wav 子目录)
    - audioFileURL 标 nonisolated 因 SandboxPaths 是 nonisolated 静态
    - cb 字面 "Response from srcIsloop" 严格保持

  Source/Bridge/Handlers/RemoteAudioHandler.swift(3.B/3.C/3.D stub):
    - prepareaudio + mediaTypeAudio 仅 cb 维持契约,无真实业务
    - 待 Phase 3.B(opencore-amr .a 接入)+ 3.C(七牛 SPM + token)+
      3.D(远端播放)完整后升级
    - 按 CLAUDE.md 原则 A:H5 调啥就得有人接,即使是 stub

WebContainerViewController.registerBridgeHandlers 接入:
  - LocalAudioHandler.register(完整实现)
  - RemoteAudioHandler.register(stub)

Plan §5 Phase 3.1 勾选;3.2 真机验证留待 H5 提供音频文件后做。

Verification-Checklist.md 新增 Phase 3 章节:
  - H. 本地音频(E.14-E.16 srcIsloop 三个 isloop 值)
  - I. prepareaudio / mediaTypeAudio stub(E.17 E.18)

BuildProject 通过

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-22 19:11:34 +08:00

41 lines
1.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// RemoteAudioHandler.swift
// ylgamehall
//
// H5 → Native handler stubprepareaudio / mediaTypeAudio
// 契约:docs/H5-Native-Contract.md §3.1 4][5 + §3.2 [7][8][9]
//
// Phase 3.A 阶段为 stub(仅 cb 维持契约,让 H5 启动不报 "no handler");
// Phase 3.B AMR 转码 + Phase 3.C 录音上传 + Phase 3.D mediaTypeAudio 真实播放
// 完整接入后升级为真实现。
//
// 按 CLAUDE.md 原则 A 第一准则:H5 调啥就得有人接,即使没真实业务也要注册。
//
import Foundation
public enum RemoteAudioHandler {
public static func register(on bridge: any BridgeProtocol) {
// 【4】prepareaudio — 启动麦克风录音
// 入参忽略;cb: "Response from prepareaudio"
// 完整实现(Phase 3.C):权限检查 + AVAudioRecorder + WAV→AMR + 七牛上传 +
// 反向 callback getaudiourl({audiourl, time}) + 子游戏额外 recordSuccess
// stub 仅 cb 维持契约
bridge.register("prepareaudio") { _, callback in
callback?(.string("Response from prepareaudio"))
}
// 【5】mediaTypeAudio — 远程语音回放
// 入参 audiourl: stringuser: string
// cb: "Response from mediaTypeAudio"
// 完整实现(Phase 3.D):voicePlaying 总开关短路 + 下载 AMR + AMR→WAV +
// AVAudioPlayer 播放 + 反向 callback gameui_play_voice(user) /
// gameui_stop_voice(user)
// stub 仅 cb 维持契约(不下载、不播放)
bridge.register("mediaTypeAudio") { _, callback in
callback?(.string("Response from mediaTypeAudio"))
}
}
}