3.B:vendor opencore-amr + AMRCodec Swift wrapper,打通 AMR↔WAV 编解码
为支撑 H5 的 prepareaudio / mediaTypeAudio 录音上传 + 远端语音播放
(docs/H5-Native-Contract.md §3.1 [4][5] + §3.2 [9])接入 AMR-NB
编解码能力。AMR-NB 是跨端(iOS / Android / 旧版本客户端)契约硬约束,
不可换 AAC / Opus。
## 接入路径
直接 vendor daoqi msext 现成的 fat .a(已上线多年),不打 xcframework /
不重编源码:
- Vendor/OpenCoreAMR/v0.1.x/libopencore-amrnb.a:daoqi 同款 5-slice fat
库(含 2026-06-20 lipo -segalign 8 修过的对齐版本)
- Vendor/OpenCoreAMR/v0.1.x/{interf_dec,interf_enc}.h:amrnb 公开头
- Vendor/OpenCoreAMR/README.md:来源、版本、修复历史、为何不打 xcframework
- ylgamehall/Source/Audio/AMRFileCodec/{amrFileCodec.h,amrFileCodec.mm}:
daoqi 同款 wrapper(文件级 WAV↔AMR 处理)
- ylgamehall/Source/Audio/AMRCodec.swift:Swift 薄 wrapper(wavToAmr /
amrToWav 两个纯函数 + AMRCodec.Error)
理由见 Vendor/OpenCoreAMR/README.md「为何不打 xcframework / 不重编源码」
一节,本质是 opencore-amr 整个 iOS 生态没有"现代主流"分发形态,社区无
官方 SPM / xcframework 维护,强行打反而引入新风险。
## 关键技术点:extern "C" 修复 ObjC++ name mangling
amrFileCodec.h 在原项目里没有 extern "C" 包裹函数声明,daoqi 能跑是
因为调用方 VoiceConverter.mm 也是 ObjC++,双方按相同 C++ name mangling
链接能对上。
新外壳从 Swift 通过 bridging-header 调用,Swift 按 C 函数解析,期望符号
_EncodeWAVEFileToAMRFile / _DecodeWAVEFileToWAVEFile(C 链接);但
.mm 编译时默认 C++ name mangling,符号变成 __Z25Encode...,导致链接器
报 Undefined symbol。
修复:在 amrFileCodec.h 的函数声明外加 #ifdef __cplusplus / extern "C"
包裹。这是标准 C/C++ 头文件兼容写法,对 daoqi 老路径无影响(ObjC++
调用方仍能链接 C-linkage 函数)。
## .gitignore:白名单 Vendor 下的 .a
发现历史遗留问题:原 .gitignore *.a 通配规则把 libWeChatSDK.a 也排除
了,意味着别人 clone 此仓库后链接失败。本次顺带修复:
!Vendor/**/*.a
让 Vendor 下的 .a 显式纳入跟踪。本提交同时把 libWeChatSDK.a(历史
缺失)+ libopencore-amrnb.a(本次新增)一并加入 git 跟踪。
## 工程改动
pbxproj 改动由用户在 Xcode UI 完成(4 项 Build Settings:Add .a 到
Frameworks group / Header Search Paths +2 / Library Search Paths +1;
EXCLUDED_ARCHS arm64-simulator 因真机调试场景暂未配,需要时再加)。
## 验证
BuildProject 通过,0 错误,符号链接正确。XcodeRefreshCodeIssuesInFile
对 AMRCodec.swift 0 诊断。
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
1A2955002FEA48CD009E703E /* libWeChatSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A2954F92FEA0B59009E703E /* libWeChatSDK.a */; };
|
||||
1A2955012FEA48D9009E703E /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A2954FA2FEA0BA8009E703E /* libz.tbd */; };
|
||||
1A2955022FEA48E4009E703E /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A2954FB2FEA0BB9009E703E /* libsqlite3.tbd */; };
|
||||
1A2955102FEAF514009E703E /* libopencore-amrnb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A29550F2FEAF514009E703E /* libopencore-amrnb.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -32,6 +33,7 @@
|
||||
1A2954FB2FEA0BB9009E703E /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||
1A2954FC2FEA0BCE009E703E /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
1A2954FE2FEA0BD8009E703E /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
1A29550F2FEAF514009E703E /* libopencore-amrnb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libopencore-amrnb.a"; path = "Vendor/OpenCoreAMR/v0.1.x/libopencore-amrnb.a"; sourceTree = "<group>"; };
|
||||
1A714BD22FE8047A00913338 /* ylgamehall.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ylgamehall.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -70,6 +72,7 @@
|
||||
1A2954EF2FE9BA6E009E703E /* CoreTelephony.framework in Frameworks */,
|
||||
1A2954E32FE99C53009E703E /* AMapFoundationKit.framework in Frameworks */,
|
||||
1A2954DA2FE97D61009E703E /* Qiniu in Frameworks */,
|
||||
1A2955102FEAF514009E703E /* libopencore-amrnb.a in Frameworks */,
|
||||
1A2954ED2FE9BA49009E703E /* SystemConfiguration.framework in Frameworks */,
|
||||
1A2954FD2FEA0BCE009E703E /* Security.framework in Frameworks */,
|
||||
1A2954F12FE9BA7C009E703E /* ExternalAccessory.framework in Frameworks */,
|
||||
@@ -82,6 +85,7 @@
|
||||
1A2954DB2FE99B2F009E703E /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A29550F2FEAF514009E703E /* libopencore-amrnb.a */,
|
||||
1A2954FE2FEA0BD8009E703E /* CFNetwork.framework */,
|
||||
1A2954FC2FEA0BCE009E703E /* Security.framework */,
|
||||
1A2954FB2FEA0BB9009E703E /* libsqlite3.tbd */,
|
||||
@@ -212,7 +216,11 @@
|
||||
"$(PROJECT_DIR)/Vendor/AMap",
|
||||
);
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2",
|
||||
"$(PROJECT_DIR)/Vendor/OpenCoreAMR/v0.1.x",
|
||||
"$(PROJECT_DIR)/ylgamehall/Source/Audio/AMRFileCodec",
|
||||
);
|
||||
INFOPLIST_FILE = ylgamehall/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
@@ -227,6 +235,7 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2",
|
||||
"$(PROJECT_DIR)/Vendor/OpenCoreAMR/v0.1.x",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
@@ -256,7 +265,11 @@
|
||||
"$(PROJECT_DIR)/Vendor/AMap",
|
||||
);
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2",
|
||||
"$(PROJECT_DIR)/Vendor/OpenCoreAMR/v0.1.x",
|
||||
"$(PROJECT_DIR)/ylgamehall/Source/Audio/AMRFileCodec",
|
||||
);
|
||||
INFOPLIST_FILE = ylgamehall/Info.plist;
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||
@@ -271,6 +284,7 @@
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Vendor/WechatSDK/v1.8.2",
|
||||
"$(PROJECT_DIR)/Vendor/OpenCoreAMR/v0.1.x",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
|
||||
Reference in New Issue
Block a user