123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- //
- // KMTTSManager.swift
- // PDF Reader Pro
- //
- // Created by liujiajie on 2023/12/12.
- //
- @objc(KMTTSManagerDelegate)
- protocol KMTTSManagerDelegate: AnyObject {
- @objc optional func ttsMananger(_ tts: KMTTSManager, willSpeak selection: CPDFSelection)
- @objc optional func ttsManangerDidFinishSpeech(_ tts: KMTTSManager) -> Bool
- @objc optional func ttsManangerdidErrorSpeech(_ tts: KMTTSManager, message: String)
- }
- let KMTTS_SETTING_SPEECHSPEED_KEY = "TTS_Setting_SpeechSpeed_Key"
- let KMTTS_SETTING_ISCONTINUE_KEY = "TTS_Setting_IsContinue_Key"
- let KMTTS_SETTING_LANGUAGE_KEY = "TTS_Setting_Language_Key"
- import Foundation
- class KMTTSManager: NSObject, NSSpeechSynthesizerDelegate{
- var delegate: KMTTSManagerDelegate?
- var rate: Float {
- get{
- return self.speechSynthesizer.rate
- }
- set{
- self.speechSynthesizer.rate = newValue
- UserDefaults.standard.setValue(newValue, forKey: KMTTS_SETTING_SPEECHSPEED_KEY)
- UserDefaults.standard.synchronize()
- }
- }
- var isContinue = false {
- willSet {
-
- }
- didSet {
- UserDefaults.standard.setValue(isContinue, forKey: KMTTS_SETTING_ISCONTINUE_KEY)
- UserDefaults.standard.synchronize()
- }
- }
- func isSpeaking() -> Bool {
- return self.speechSynthesizer.isSpeaking
- }
- var isPaused = false
- var speechSynthesizer: NSSpeechSynthesizer!
- var speechPDFPage: CPDFPage?
- var speechPDFSelection: CPDFSelection?
-
- static let defalutManager = KMTTSManager()
-
- override init() {
- super.init()
- let array = NSSpeechSynthesizer.availableVoices
- var voice: NSSpeechSynthesizer.VoiceName = array.first ?? NSSpeechSynthesizer.VoiceName(rawValue: "")
-
- if (UserDefaults.standard.object(forKey: KMTTS_SETTING_LANGUAGE_KEY) != nil){
- voice = UserDefaults.standard.object(forKey: KMTTS_SETTING_LANGUAGE_KEY) as! NSSpeechSynthesizer.VoiceName
- }
-
- self.speechSynthesizer = NSSpeechSynthesizer(voice: voice)
- self.speechSynthesizer.delegate = self
- self.speechSynthesizer.usesFeedbackWindow = true
- var rate: Float = 175
- if let savedRate = UserDefaults.standard.object(forKey: KMTTS_SETTING_SPEECHSPEED_KEY) as? Float {
- rate = savedRate
- }
- self.speechSynthesizer.rate = rate
-
- var isContinue = false
- if let savedContinue = UserDefaults.standard.object(forKey: KMTTS_SETTING_ISCONTINUE_KEY) as? Bool {
- isContinue = savedContinue
- }
- self.isContinue = isContinue
- }
-
- func voice() -> NSSpeechSynthesizer.VoiceName {
- return self.speechSynthesizer.voice() ?? NSSpeechSynthesizer.VoiceName(rawValue: "")
- }
- func setVoice(voice: NSSpeechSynthesizer.VoiceName) {
- self.speechSynthesizer.setVoice(voice)
- UserDefaults.standard.setValue(voice, forKey: KMTTS_SETTING_LANGUAGE_KEY)
- UserDefaults.standard.synchronize()
- }
-
- //MARK: Public
- func startSpeakingPDFPage(_ page: CPDFPage) -> Bool {
- guard let string = page.string else { return false }
- guard string.count > 0 else { return false }
- isPaused = false
- if speechSynthesizer.isSpeaking {
- speechSynthesizer.stopSpeaking(at: .immediateBoundary)
- }
- speechPDFPage = page
- speechPDFSelection = nil
- return speechSynthesizer.startSpeaking(string)
- }
- func startSpeakingPDFSelection(_ selection: CPDFSelection) -> Bool {
- guard let string = selection.string() else { return false }
- guard string.count > 0 else { return false }
- isPaused = false
- if speechSynthesizer.isSpeaking {
- speechSynthesizer.stopSpeaking(at: .immediateBoundary)
- }
- speechPDFPage = nil
- speechPDFSelection = selection
- return speechSynthesizer.startSpeaking(string)
- }
- func stopSpeaking() {
- if speechSynthesizer.isSpeaking || isPaused {
- isPaused = false
- speechSynthesizer.stopSpeaking(at: .immediateBoundary)
- }
- }
- func pauseSpeaking() {
- if speechSynthesizer.isSpeaking {
- isPaused = true
- speechSynthesizer.pauseSpeaking(at: .immediateBoundary)
- }
- }
- func continueSpeaking() {
- isPaused = false
- speechSynthesizer.continueSpeaking()
- }
- func availableVoices() -> [NSSpeechSynthesizer.VoiceName] {
- return NSSpeechSynthesizer.availableVoices
- }
- func attributesForVoice(_ voice: NSSpeechSynthesizer.VoiceName) -> [NSSpeechSynthesizer.VoiceAttributeKey : Any] {
- return NSSpeechSynthesizer.attributes(forVoice: voice)
- }
- func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) {
- isPaused = false
- let _ = delegate?.ttsManangerDidFinishSpeech?(self)
- }
- func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) {
- var selection: CPDFSelection?
- if let page = speechPDFPage {
- if characterRange.length > 0 {
- selection = page.selection(for: characterRange)
- }
- } else if let pdfSelection = speechPDFSelection {
- selection = pdfSelection
- }
- if let data = selection {
- delegate?.ttsMananger?(self, willSpeak: data)
- }
- }
- func speechSynthesizer(_ sender: NSSpeechSynthesizer, didEncounterErrorAt characterIndex: Int, of string: String, message: String) {
- delegate?.ttsManangerdidErrorSpeech?(self, message: message)
- }
- func speechSynthesizer(_ sender: NSSpeechSynthesizer, didEncounterSyncMessage message: String) {
- delegate?.ttsManangerdidErrorSpeech?(self, message: message)
- }
- }
|