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

如何用AudioKit的MIDIPlayer播放MIDI文件?报错-10852求解

解决AudioKit MIDIPlayer播放MIDI文件时的AVAE错误-10852

问题重现

使用AudioKit的MIDIPlayer播放MIDI文件,编写了如下SwiftUI代码:

import SwiftUI
import AudioKit

struct ContentView: View {
    @StateObject var midi = MIDIWrapper()
    
    var body: some View {
        Button(action: {midi.play()}, label: {Text("play")})     
    }
}

class MIDIWrapper: ObservableObject {
    
    let engine = AudioEngine()
    var instrument = AppleSampler()
    let player: MIDIPlayer
    
    init() {
        engine.output = instrument
        
        try? engine.start()
        
        player = MIDIPlayer(audioEngine: engine.avEngine, filename: "cdec.mid")
    }
    
    func play() -> () {
        player.play()
    }  
}

在iPhone 13上运行时出现以下错误:

AVAEInternal.h:109   [AVAudioSequencer.mm:121:-[AVAudioSequencer(AVAudioSequencer_Player) startAndReturnError:]: (impl->Start()): error -10852
MIDIPlayer.swift:play():121:Could not start the sequencer (MIDIPlayer.swift:play():121)

解决方法

1. 配置正确的音频会话

iOS要求音频应用必须提前配置AVAudioSession,获取音频权限并设置合适的播放类别。在MIDIWrapper初始化中添加会话配置:

import SwiftUI
import AudioKit
import AVFoundation // 需导入AVFoundation

class MIDIWrapper: ObservableObject {
    
    let engine = AudioEngine()
    var instrument = AppleSampler()
    let player: MIDIPlayer
    
    init() {
        // 配置音频会话
        do {
            let session = AVAudioSession.sharedInstance()
            try session.setCategory(.playback, mode: .default)
            try session.activate()
        } catch {
            print("音频会话配置失败: \(error)")
        }
        
        engine.output = instrument
        
        // 捕获AudioEngine启动错误
        do {
            try engine.start()
        } catch {
            print("AudioEngine启动失败: \(error)")
        }
        
        player = MIDIPlayer(audioEngine: engine.avEngine, filename: "cdec.mid")
    }
    
    func play() {
        player.play()
    }  
}

2. 验证MIDI文件的项目配置

  • 确认cdec.mid已添加到Xcode项目的目标中:选中文件,查看右侧检查器的Target Membership,确保勾选当前应用目标。
  • 检查文件名拼写完全一致:iOS区分文件名大小写,代码中的"cdec.mid"必须和实际文件名完全匹配。

3. 确保MIDIPlayer加载完成后再调用播放

MIDI文件加载需要时间,可通过异步加载或状态检查避免未初始化完成就调用play:

class MIDIWrapper: ObservableObject {
    
    let engine = AudioEngine()
    var instrument = AppleSampler()
    var player: MIDIPlayer?
    
    init() {
        // 配置音频会话...
        
        engine.output = instrument
        
        do {
            try engine.start()
            // 异步加载MIDI文件
            DispatchQueue.global().async { [weak self] in
                guard let self = self else { return }
                self.player = MIDIPlayer(audioEngine: self.engine.avEngine, filename: "cdec.mid")
                self.player?.load() // 显式触发加载
            }
        } catch {
            print("AudioEngine启动失败: \(error)")
        }
    }
    
    func play() {
        guard let player = player else {
            print("MIDIPlayer未完成初始化")
            return
        }
        player.play()
    }  
}

4. 替换静默错误捕获为显式异常处理

原代码中try? engine.start()会忽略错误,改为do-catch可以获取具体失败原因,帮助排查问题:

do {
    try engine.start()
} catch {
    print("AudioEngine启动失败详情: \(error.localizedDescription)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:42:41