killapp/Assets/Plugins/iOS/FFmpegKitIOS.mm
“虞渠成” 6e385e2bab refactor(iOS/视频页): 清理无用调试日志并修复类型转换问题
1. 移除VideoPageCtrl中多余的Debug.Log调试输出
2. 为iOS平台的FFmpegKit信号忽略调用添加正确的枚举强转
2026-09-08 15:08:24 +08:00

66 lines
2.6 KiB
Plaintext

//
// FFmpegKitIOS.mm
// iOS 端 .264 -> .mp4 转码桥(extern "C"),供 C# 经 [DllImport("__Internal")] 调用。
//
// 原理: 调用 native ffmpeg-kit(ffmpegkit.framework)的 executeWithArguments,用 libx264
// 重编码重新生成干净的 SPS/PPS + 时间戳,修复设备(OPPO/MTK 等)产出裸流坏 PPS 导致的
// 解码卡死("non-existing PPS 0 referenced")。
//
// 依赖: 需将 ffmpeg-kit iOS full-gpl 的 .xcframework(含 ffmpegkit.framework)放进
// Assets/Plugins/iOS/FFmpegKit/(Unity 会在构建 Xcode 工程时自动链接)。
// 版本需与本项目 Android 端一致: dev.ffmpegkit-maintained:ffmpeg-kit-full-gpl:6.0.3
// (FFmpeg n6.1.6,含 libx264)。缺少该 framework 时本文件编译期即报错找不到头文件,属预期。
//
#import <ffmpegkit/FFmpegKit.h>
#import <ffmpegkit/FFmpegKitConfig.h>
#import <Foundation/Foundation.h>
#import <signal.h>
static BOOL ffmpegKitConfigured = NO;
// 一次性配置:忽略 Unity/IL2CPP 运行时可能被 ffmpeg-kit 信号处理干扰的信号
static void FFmpegKitConfigureOnce(void) {
if (ffmpegKitConfigured) return;
ffmpegKitConfigured = YES;
// 强转成 ffmpeg-kit 的 Signal 枚举(数值与 <signal.h> 系统信号常量一致)
[FFmpegKitConfig ignoreSignal:(Signal)SIGXCPU];
[FFmpegKitConfig ignoreSignal:(Signal)SIGPIPE];
}
extern "C" {
/// 执行 ffmpeg 转码。
/// @param argv 参数数组(C# string[] 会作为 UTF-8 char** 传入)
/// @param argc 参数个数
/// @return 0=成功;否则为 ffmpeg 退出码;-1=参数或内部错误
int FFmpegKitExecuteWithArguments(char **argv, int argc) {
@autoreleasepool {
FFmpegKitConfigureOnce();
if (argv == NULL || argc <= 0) {
NSLog(@"[FFmpegKitIOS] bad args argv=%p argc=%d", argv, argc);
return -1;
}
NSMutableArray *arguments = [NSMutableArray arrayWithCapacity:(NSUInteger)argc];
for (int i = 0; i < argc; i++) {
if (argv[i] == NULL) continue;
[arguments addObject:[NSString stringWithUTF8String:argv[i]]];
}
NSLog(@"[FFmpegKitIOS] execute: %@", [arguments componentsJoinedByString:@" "]);
FFmpegSession *session = [FFmpegKit executeWithArguments:arguments];
ReturnCode *returnCode = [session getReturnCode];
if ([ReturnCode isSuccess:returnCode]) {
return 0;
}
if (returnCode == nil) {
NSLog(@"[FFmpegKitIOS] returnCode nil, treat as failure.");
return -1;
}
return (int)[returnCode getValue];
}
}
}