iPhoneのマイクから録音し、.caf
ファイルに記録するiOSアプリケーション(Swift 3とXcode 8.2.1を使用)を構築したいとします。AVAudioFile initはシミュレータでは動作しますが、デバイスでクラッシュします
まず、私は私のプロジェクトののInfo.plistファイルに次の行を追加しました:その後
<key>NSMicrophoneUsageDescription</key>
<string>Some description to explain why access is required</string>
、私はAVAudioEngine
を設定し、インストールの簡単なUIViewController
を作成しましたRecord
とStop
ボタンをタップするとオーディオタップが削除されます。
ViewController.swift
import UIKit
import AVFoundation
class ViewController: UIViewController {
var engine = AVAudioEngine()
var file: AVAudioFile?
var player = AVAudioPlayerNode()
override func viewDidLoad() {
super.viewDidLoad()
guard let url = urlFor(filename: "test.caf") else { return }
do {
file = try AVAudioFile(forWriting: url, settings: engine.inputNode!.inputFormat(forBus: 0).settings, commonFormat: engine.inputNode!.inputFormat(forBus: 0).commonFormat, interleaved: false)
} catch {
print("Error: \(error)")
}
engine.attach(player)
engine.connect(player, to: engine.mainMixerNode, format: engine.mainMixerNode.outputFormat(forBus: 0))
do {
try engine.start()
} catch {
print("Error: \(error)")
}
}
@IBAction func record(sender: AnyObject) {
engine.inputNode?.installTap(onBus: 0, bufferSize: 1024, format: engine.mainMixerNode.outputFormat(forBus: 0)) { (buffer, time) -> Void in
do {
try self.file?.write(from: buffer)
} catch {
print("Error: \(error)")
}
}
}
@IBAction func stop(sender: AnyObject) {
engine.inputNode?.removeTap(onBus: 0)
// Print the url of the saved file
let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
print(urls[urls.endIndex - 1])
}
func urlFor(filename: String) -> URL? {
// Get url of saved file
if let dir = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true).first {
let path = dir.appending(filename)
return URL(fileURLWithPath: path)
}
return nil
}
}
アプリは、シミュレータ上で正常に動作します:私は、私の声を録音し、私の声が正しく記録された記録されたファイルやテストのURLをつかむことができます。しかし、アプリをiOS 10.2.1のiPhone 6sでテストしたデバイスで起動するとすぐにクラッシュします。コンソールは私に次のログを提供します:
2017-02-08 17:09:14.330151 AudioEngineSimpleApp[7100:2659416] Audio files cannot be non-interleaved. Ignoring setting AVLinearPCMIsNonInterleaved YES.
2017-02-08 17:09:14.333715 AudioEngineSimpleApp[7100:2659416] [central] 54: ERROR: [0x1b7440c40] >avae> AVAudioFile.mm:160: AVAudioFileImpl: error -54
2017-02-08 17:09:14.333796 AudioEngineSimpleApp[7100:2659416] [central] 54: ERROR: [0x1b7440c40] >avae> AVAudioFile.mm:122: ReadMagicCookie: error -50
2017-02-08 17:09:14.334369 AudioEngineSimpleApp[7100:2659416] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -50'
この問題は、スタックオーバーフローのスレッドAVAudioPlayer working on Simulator but not on Real Deviceに関連しているようだが、私は私の問題を解決するために、自分自身のコードにその応答を実装する方法を見つけ出すことはできません。