64 lines
2.1 KiB
Swift
64 lines
2.1 KiB
Swift
import AVFoundation
|
|
import Foundation
|
|
|
|
/// 手表端录音:AVAudioRecorder 写 AAC .m4a,存在手表 Documents 里,停后交给 WatchSessionManager 传到 iPhone。
|
|
@MainActor
|
|
final class WatchRecorder: ObservableObject {
|
|
@Published var isRecording = false
|
|
@Published var elapsed: TimeInterval = 0
|
|
|
|
private var recorder: AVAudioRecorder?
|
|
private var timer: Timer?
|
|
private var startDate: Date?
|
|
private(set) var currentFileURL: URL?
|
|
|
|
func requestPermission() async -> Bool {
|
|
await withCheckedContinuation { continuation in
|
|
AVAudioSession.sharedInstance().requestRecordPermission { granted in
|
|
continuation.resume(returning: granted)
|
|
}
|
|
}
|
|
}
|
|
|
|
func start() throws {
|
|
let session = AVAudioSession.sharedInstance()
|
|
try session.setCategory(.record, mode: .default)
|
|
try session.setActive(true)
|
|
|
|
let fileName = "watch-note-\(Int(Date().timeIntervalSince1970)).m4a"
|
|
let docs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
|
let url = docs.appendingPathComponent(fileName)
|
|
currentFileURL = url
|
|
|
|
let settings: [String: Any] = [
|
|
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
|
|
AVSampleRateKey: 44_100,
|
|
AVNumberOfChannelsKey: 1,
|
|
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
|
|
]
|
|
recorder = try AVAudioRecorder(url: url, settings: settings)
|
|
recorder?.record()
|
|
|
|
isRecording = true
|
|
startDate = Date()
|
|
elapsed = 0
|
|
timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: true) { [weak self] _ in
|
|
Task { @MainActor in
|
|
guard let self, let start = self.startDate else { return }
|
|
self.elapsed = Date().timeIntervalSince(start)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 停止录音,返回录音文件 URL(nil 表示没录成)
|
|
func stop() -> URL? {
|
|
timer?.invalidate()
|
|
timer = nil
|
|
recorder?.stop()
|
|
recorder = nil
|
|
isRecording = false
|
|
try? AVAudioSession.sharedInstance().setActive(false)
|
|
return currentFileURL
|
|
}
|
|
}
|