Files
swiftGrammar/AIGrammar/lib/TTSManager.swift
2024-08-30 17:46:21 +08:00

101 lines
3.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// TTSManager.swift
// AIGrammar
//
// Created by oscar on 2024/8/29.
//
import Foundation
import AVFAudio
class TTSManager: NSObject, QCloudTTSEngineDelegate {
static let shared = TTSManager() //
private var synthesizer: QCloudTTSEngine?
private var audioPlayer: AVAudioPlayer?
private var onSuccess: (() -> Void)?
private var onFailure: ((String) -> Void)?
// 使
private let dailyLimit = 100
private let userDefaults = UserDefaults.standard
private override init() {
super.init()
setupSynthesizer()
}
private func setupSynthesizer() {
synthesizer = QCloudTTSEngine.getShareInstance() as? QCloudTTSEngine
synthesizer?.engineInit(.TTS_MODE_ONLINE, delegate: self)
synthesizer?.setOnlineAuthParam(1300230265, secretId: "AKIDmcetGuREGiDOBeIJVm4Kd1ZOUqFdD1CQ", secretKey: "UwhP3XrJfrx8IQUfpMvRznYTK5lM4rhR", token: nil)
}
func synthesizeAndPlay(text: String, isVIP: Bool, onSuccess: @escaping () -> Void, onFailure: @escaping (String) -> Void) {
if !isVIP {
let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let currentDateString = dateFormatter.string(from: currentDate)
let lastDateString = userDefaults.string(forKey: "LastCallDate") ?? ""
var callCount = userDefaults.integer(forKey: "CallCount")
if currentDateString != lastDateString {
//
callCount = 0
userDefaults.set(currentDateString, forKey: "LastCallDate")
}
logger.info("nonVIP check limit, cnt: \(callCount), limit: \(dailyLimit)")
if callCount >= dailyLimit {
onFailure("Daily limit reached. Please try again tomorrow.")
return
} else {
//
callCount += 1
userDefaults.set(callCount, forKey: "CallCount")
}
}
guard let synthesizer = synthesizer else {
onFailure("Synthesizer is not initialized.")
return
}
self.onSuccess = onSuccess
self.onFailure = onFailure
let error = synthesizer.synthesize(text, utteranceId: "test")
if let error = error {
onFailure("Synthesis error: \(error)")
}
}
// MARK: - QCloudTTSEngineDelegate
func onSynthesizeData(_ data: Data?, utteranceId: String?, text: String?, engineType: Int, requestId: String?, respJson: String?) {
guard let data = data else {
onFailure?("Synthesis failed with no data.")
return
}
do {
audioPlayer = try AVAudioPlayer(data: data)
audioPlayer?.prepareToPlay()
audioPlayer?.play()
onSuccess?()
} catch {
onFailure?("Failed to play synthesized audio: \(error)")
}
}
func onError(_ error: TtsError?, utteranceId: String?, text: String?) {
if let error = error {
onFailure?("Synthesis error: \(error)")
}
}
func onOfflineAuthInfo(_ OfflineAuthInfo: QCloudOfflineAuthInfo) {
// 线
}
}