Puede crear su propio binario swift y utilizarlo en Automator. Aquí está el código de ejemplo:
import Foundation
import AVFoundation
class Synth: NSObject, AVSpeechSynthesizerDelegate {
let synthesizer = AVSpeechSynthesizer()
init(text: String) {
super.init()
let languageCode = NSLinguisticTagger.dominantLanguage(for: text) ?? AVSpeechSynthesisVoiceIdentifierAlex
let utterance = AVSpeechUtterance(string: text)
utterance.voice = AVSpeechSynthesisVoice(language: languageCode)
synthesizer.delegate = self
synthesizer.speak(utterance)
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
exit(0)
}
}
var text = CommandLine.arguments.dropFirst().reduce("", +)
text = text.isEmpty ? "No text" : text
let s = Synth(text: text)
RunLoop.main.run()
Guárdelo en un archivo llamado main.swift
y luego en la línea de comandos ejecutar
swiftc main.swift -o ttslanguage
Lugar ttslanguage
en su directorio de inicio, luego abra Automator.app, seleccione "Servicio" como tipo. Haz que se ejecute en la entrada de texto. Coloca "Run shell script" como primer bloque y entrada:
~/ttslanguage "$1"
Ahora podrás ejecutar el Text To Speech que detecta el idioma del texto seleccionado.
Si el texto tiene varias frases con diferentes idiomas, puede cambiar el Synth
a (no se olvide de import NaturalLanguage
):
class Synth: NSObject, AVSpeechSynthesizerDelegate {
let synthesizer = AVSpeechSynthesizer()
var lastUtterance: AVSpeechUtterance?
init(text: String) {
super.init()
let tagger = NLTagger(tagSchemes: [.language])
tagger.string = text
var utterances = [AVSpeechUtterance]()
tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .sentence, scheme: .language, options: []) { tag, tokenRange in
let txt = String(text[tokenRange])
let languageCode = NSLinguisticTagger.dominantLanguage(for: txt) ?? AVSpeechSynthesisVoiceIdentifierAlex
let utterance = AVSpeechUtterance(string: txt)
utterance.voice = AVSpeechSynthesisVoice(language: languageCode)
utterances.append(utterance)
return true
}
synthesizer.delegate = self
lastUtterance = utterances.last
for utterance in utterances {
synthesizer.speak(utterance)
}
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
guard let lastUtterance = lastUtterance else {
exit(-1)
}
if lastUtterance == utterance {
exit(0)
}
}
}
Proyecto con análisis sintáctico avanzado (incluyendo HTML + lang
atributos) se pueden encontrar en la página de github . Más información en README.