You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Multiplatform调用AVAudioRecorder触发空指针异常排查

Kotlin Multiplatform iOS端AVAudioRecorder初始化NPE问题解决

问题场景

在Kotlin Multiplatform开发跨平台音频录制PoC时,iOS端通过Kotlin/Native封装原生AVAudioRecorder逻辑,调用构造方法时触发NullPointerException,但Swift原生实现相同逻辑却能正常工作。

触发异常的初始代码

iOS端Kotlin实现代码:

val settings = mapOf(
    "AVFormatIDKey" to kAudioFormatAppleIMA4,
    "AVSampleRateKey" to 44100.0,
    "AVNumberOfChannelsKey" to 2,
    "AVEncoderBitRateKey" to 12800,
    "AVLinearPCMBitDepthKey" to 16,
    "AVLinearPCMIsBigEndianKey" to false,
    "AVLinearPCMIsFloatKey" to false,
) as Map<Any?, *>
val url = NSURL(fileURLWithPath = outputFile)
// 打印配置与URL信息
println(settings)
println("File is: ($url)")
memScoped {
    try {
        val error: ObjCObjectVar<NSError?> = alloc()
        recorder = AVAudioRecorder(url, settings, error.ptr)
        recorder?.meteringEnabled = true
        recorder?.prepareToRecord()
        println(error)
    } catch (e: Exception) {
        println(e.toString())
        e.printStackTrace()
    }
}

输出的配置与URL详情:

{AVFormatIDKey=1768775988, AVSampleRateKey=44100.0, AVNumberOfChannelsKey=2, AVEncoderBitRateKey=12800, AVLinearPCMBitDepthKey=16, AVLinearPCMIsBigEndianKey=false, AVLinearPCMIsFloatKey=false}
File is: (file:/Users/gazer/Library/Developer/CoreSimulator/Devices/33505695-6067-4B93-81D3-087DF397396F/data/Containers/Data/Application/A931840F-93B9-4936-AFBD-BD834BD80AF5/Documents/recording.m4a -- file:///)

outputFile由iOS原生Swift生成:

let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

// outputFile == audioFilename.absoluteString

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

异常栈信息:

at 2   shared                              0x10b760779        kfun:kotlin.RuntimeException#<init>(){} + 73 (/opt/buildAgent/work/acafc8c59a79cc1/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:32:28)
at 3   shared                              0x10b7609b9        kfun:kotlin.NullPointerException#<init>(){} + 73 (/opt/buildAgent/work/acafc8c59a79cc1/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:43:28)
at 4   shared                              0x10b7862d4        ThrowNullPointerException + 132 (/opt/buildAgent/work/acafc8c59a79cc1/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt:15:11)
at 5   shared                              0x10b6d3aae        kfun:ar.com.p39.powernotes.recorder.IOSAudioRecordThread#startRecording(){} + 2910 

对比验证:Swift原生正常工作代码

用Swift实现相同逻辑并将实例传入Kotlin时可正常录制:

let settings: [String: Any] = [
    AVFormatIDKey: kAudioFormatLinearPCM,
    AVSampleRateKey: 44100.0,
    AVNumberOfChannelsKey: 2,
    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
var url = URL(string: outputFile)
do {
    recorder = try AVAudioRecorder(url: url!, settings: settings)
    recorder?.isMeteringEnabled = true
    recorder?.prepareToRecord()
    recorder?.record()
catch {
    debugPrint("ERror")
}

解决方案

问题根源在于音频配置参数不兼容,将配置改为PCM格式后异常消失,修改后的Kotlin配置如下:

val settings = mapOf(
    "AVFormatIDKey" to kAudioFormatLinearPCM,
    "AVSampleRateKey" to 1600.0,
    "AVNumberOfChannelsKey" to 1,
    "AVLinearPCMBitDepthKey" to 8,
    "AVLinearPCMIsBigEndianKey" to false,
    "AVLinearPCMIsFloatKey" to false,
)

内容的提问来源于stack exchange,提问作者Ricardo Markiewicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:06:15