如何在 AVAudioRecorder 中控制 Opus 比特率
How to control Opus bitrate in AVAudioRecorder
我试图在 AVAudioRecorder 中设置 Opus (kAudioFormatOpus) 的比特率,但它不起作用。比特率始终在 20kb/s 左右。
let recordSettings =
[AVEncoderBitRateKey: 32000,
AVFormatIDKey: kAudioFormatOpus,
AVSampleRateKey: 16000.0] as [String: Any]
let recordingFormat = AVAudioFormat(settings: recordSettings)!
let recorder = try! AVAudioRecorder(url: url, format: recordingFormat)
recorder.record()
我做错了什么吗?
事实证明,在这种情况下初始化 AVAudioRecorder 的正确方法应该是:
let recordSettings =
[AVEncoderBitRateKey: 32000,
AVFormatIDKey: kAudioFormatOpus,
AVSampleRateKey: 16000.0] as [String: Any]
let recorder = try! AVAudioRecorder(url: url, settings: recordSettings)
recorder.record()
不要尝试先初始化AVAudioFormat,然后将其传递给AVAudioRecorder。
而是直接使用设置调用 init:
AVAudioRecorder(url: url, settings: recordSettings)
@IBOutlet var recordButton: UIButton!
var recorder: AVAudioRecorder!
var player: AVAudioPlayer!
@IBAction func recordBtnACtn(_ sender: Any){
if player != nil && player.isPlaying {
print("stopping")
player.stop()
}
if recorder == nil {
print("recording. recorder nil")
recordButton.setTitle("Pause", for: .normal)
recordWithPermission(true)
return
}
if recorder != nil && recorder.isRecording {
print("pausing")
recorder.pause()
recordButton.setTitle("Continue", for: .normal)
} else {
print("recording")
recordButton.setTitle("Pause", for: .normal)
recordWithPermission(false)
}
}
func recordWithPermission(_ setup: Bool) {
print("\(#function)")
AVAudioSession.sharedInstance().requestRecordPermission {
[unowned self] granted in
if granted {
DispatchQueue.main.async {
print("Permission to record granted")
self.setSessionPlayAndRecord()
if setup {
self.setupRecorder()
}
self.recorder.record()
self.meterTimer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(self.updateAudioMeter(_:)),
userInfo: nil,
repeats: true)
}
}else{
print("Permission to record not granted")
}
}
if AVAudioSession.sharedInstance().recordPermission() == .denied {
print("permission denied")
}
}
func setupRecorder() {
print("\(#function)")
let format = DateFormatter()
format.dateFormat="yyyy-MM-dd-HH-mm-ss"
let currentFileName = "recording-\(format.string(from: Date())).m4a"
print(currentFileName)
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
self.soundFileURL = documentsDirectory.appendingPathComponent(currentFileName)
print("writing to soundfile url: '\(soundFileURL!)'")
if FileManager.default.fileExists(atPath: soundFileURL.absoluteString) {
// probably won't happen. want to do something about it?
print("soundfile \(soundFileURL.absoluteString) exists")
}
let recordSettings: [String: Any] = [
AVFormatIDKey: kAudioFormatAppleLossless,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVEncoderBitRateKey: 32000,
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100.0
]
do {
recorder = try AVAudioRecorder(url: soundFileURL, settings: recordSettings)
recorder.delegate = self
recorder.isMeteringEnabled = true
recorder.prepareToRecord() // creates/overwrites the file at soundFileURL
} catch {
recorder = nil
print(error.localizedDescription)
}
}
我试图在 AVAudioRecorder 中设置 Opus (kAudioFormatOpus) 的比特率,但它不起作用。比特率始终在 20kb/s 左右。
let recordSettings =
[AVEncoderBitRateKey: 32000,
AVFormatIDKey: kAudioFormatOpus,
AVSampleRateKey: 16000.0] as [String: Any]
let recordingFormat = AVAudioFormat(settings: recordSettings)!
let recorder = try! AVAudioRecorder(url: url, format: recordingFormat)
recorder.record()
我做错了什么吗?
事实证明,在这种情况下初始化 AVAudioRecorder 的正确方法应该是:
let recordSettings =
[AVEncoderBitRateKey: 32000,
AVFormatIDKey: kAudioFormatOpus,
AVSampleRateKey: 16000.0] as [String: Any]
let recorder = try! AVAudioRecorder(url: url, settings: recordSettings)
recorder.record()
不要尝试先初始化AVAudioFormat,然后将其传递给AVAudioRecorder。 而是直接使用设置调用 init:
AVAudioRecorder(url: url, settings: recordSettings)
@IBOutlet var recordButton: UIButton!
var recorder: AVAudioRecorder!
var player: AVAudioPlayer!
@IBAction func recordBtnACtn(_ sender: Any){
if player != nil && player.isPlaying {
print("stopping")
player.stop()
}
if recorder == nil {
print("recording. recorder nil")
recordButton.setTitle("Pause", for: .normal)
recordWithPermission(true)
return
}
if recorder != nil && recorder.isRecording {
print("pausing")
recorder.pause()
recordButton.setTitle("Continue", for: .normal)
} else {
print("recording")
recordButton.setTitle("Pause", for: .normal)
recordWithPermission(false)
}
}
func recordWithPermission(_ setup: Bool) {
print("\(#function)")
AVAudioSession.sharedInstance().requestRecordPermission {
[unowned self] granted in
if granted {
DispatchQueue.main.async {
print("Permission to record granted")
self.setSessionPlayAndRecord()
if setup {
self.setupRecorder()
}
self.recorder.record()
self.meterTimer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(self.updateAudioMeter(_:)),
userInfo: nil,
repeats: true)
}
}else{
print("Permission to record not granted")
}
}
if AVAudioSession.sharedInstance().recordPermission() == .denied {
print("permission denied")
}
}
func setupRecorder() {
print("\(#function)")
let format = DateFormatter()
format.dateFormat="yyyy-MM-dd-HH-mm-ss"
let currentFileName = "recording-\(format.string(from: Date())).m4a"
print(currentFileName)
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
self.soundFileURL = documentsDirectory.appendingPathComponent(currentFileName)
print("writing to soundfile url: '\(soundFileURL!)'")
if FileManager.default.fileExists(atPath: soundFileURL.absoluteString) {
// probably won't happen. want to do something about it?
print("soundfile \(soundFileURL.absoluteString) exists")
}
let recordSettings: [String: Any] = [
AVFormatIDKey: kAudioFormatAppleLossless,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVEncoderBitRateKey: 32000,
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100.0
]
do {
recorder = try AVAudioRecorder(url: soundFileURL, settings: recordSettings)
recorder.delegate = self
recorder.isMeteringEnabled = true
recorder.prepareToRecord() // creates/overwrites the file at soundFileURL
} catch {
recorder = nil
print(error.localizedDescription)
}
}