如何从 iPhone 麦克风 return 当前分贝水平
How to return current decibel level from iPhone mic
我正在尝试 return 来自 iPhone 麦克风的当前分贝级别。我在下面拼凑了这段代码,但无法弄清楚为什么它不起作用。我的期望是,现在它会持续将当前峰值功率打印到控制台。
所以我的 questions/issues 是:
- “peakPowerForchannel”return 是当前电平还是整个音频会话的最大值?
- 看来我的按钮从来没有转到停止录制模式,每次按下时都只是打印“录制开始”。
- 我不明白为什么分贝级别根本不打印。
感谢您的帮助!
import SwiftUI
import AVFoundation
import Foundation
import Combine
class AudioRecorder: ObservableObject {
let objectWillChange = PassthroughSubject<AudioRecorder, Never>()
var audioRecorder: AVAudioRecorder!
var decibelLevelTimer = Timer()
var recording = false {
didSet {
objectWillChange.send(self)
}
}
func startRecording() {
let recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
} catch {
print("Failed to set up recording session")
}
let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.record()
recording = true
audioRecorder.isMeteringEnabled = true
self.decibelLevelTimer = Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true) { timer in
self.audioRecorder.updateMeters()
print(self.audioRecorder.peakPower(forChannel: 0))
}
} catch {
print("Could not start recording")
}
}
}
extension Date
{
func toString( dateFormat format : String ) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: self)
}
}
struct ContentView: View {
@ObservedObject var audioRecorder: AudioRecorder
var body: some View {
VStack {
if audioRecorder.recording == false {
Button(action: {print("Start recording")}) {
Image(systemName: "circle.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipped()
.foregroundColor(.red)
.padding(.bottom, 40)
}
} else {
Button(action: {print("Stop recording)")}) {
Image(systemName: "stop.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipped()
.foregroundColor(.red)
.padding(.bottom, 40)
}
}
}
}
}
关于峰值功率,文档是这样说的:
The audio channel’s current peak power.
(基本上就是现在的window)
您需要在 Button 的操作中实际调用 startRecording()
(现在,您所做的只是打印):
Button(action: {
audioRecorder.startRecording()
}) {
同样,您需要为另一个按钮创建并调用 stopRecording
操作:
func stopRecording() {
audioRecorder.stop()
recording = false
decibelLevelTimer.invalidate()
}
//....
Button(action: {
audioRecorder.stopRecording()
}) {
此外,如果您仍然没有输入,请确保您的麦克风权限设置正确:https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos
经过这些更改,您的代码对我有用。
我正在尝试 return 来自 iPhone 麦克风的当前分贝级别。我在下面拼凑了这段代码,但无法弄清楚为什么它不起作用。我的期望是,现在它会持续将当前峰值功率打印到控制台。
所以我的 questions/issues 是:
- “peakPowerForchannel”return 是当前电平还是整个音频会话的最大值?
- 看来我的按钮从来没有转到停止录制模式,每次按下时都只是打印“录制开始”。
- 我不明白为什么分贝级别根本不打印。
感谢您的帮助!
import SwiftUI
import AVFoundation
import Foundation
import Combine
class AudioRecorder: ObservableObject {
let objectWillChange = PassthroughSubject<AudioRecorder, Never>()
var audioRecorder: AVAudioRecorder!
var decibelLevelTimer = Timer()
var recording = false {
didSet {
objectWillChange.send(self)
}
}
func startRecording() {
let recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
} catch {
print("Failed to set up recording session")
}
let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.record()
recording = true
audioRecorder.isMeteringEnabled = true
self.decibelLevelTimer = Timer.scheduledTimer(withTimeInterval: 0.02, repeats: true) { timer in
self.audioRecorder.updateMeters()
print(self.audioRecorder.peakPower(forChannel: 0))
}
} catch {
print("Could not start recording")
}
}
}
extension Date
{
func toString( dateFormat format : String ) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: self)
}
}
struct ContentView: View {
@ObservedObject var audioRecorder: AudioRecorder
var body: some View {
VStack {
if audioRecorder.recording == false {
Button(action: {print("Start recording")}) {
Image(systemName: "circle.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipped()
.foregroundColor(.red)
.padding(.bottom, 40)
}
} else {
Button(action: {print("Stop recording)")}) {
Image(systemName: "stop.fill")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipped()
.foregroundColor(.red)
.padding(.bottom, 40)
}
}
}
}
}
关于峰值功率,文档是这样说的:
The audio channel’s current peak power.
(基本上就是现在的window)
您需要在 Button 的操作中实际调用 startRecording()
(现在,您所做的只是打印):
Button(action: {
audioRecorder.startRecording()
}) {
同样,您需要为另一个按钮创建并调用 stopRecording
操作:
func stopRecording() {
audioRecorder.stop()
recording = false
decibelLevelTimer.invalidate()
}
//....
Button(action: {
audioRecorder.stopRecording()
}) {
此外,如果您仍然没有输入,请确保您的麦克风权限设置正确:https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos
经过这些更改,您的代码对我有用。