Skip to content

Instantly share code, notes, and snippets.

@idvorkin
Created October 22, 2023 16:35
Show Gist options
  • Save idvorkin/cfa7b482f04aceb040d8822ad95fcabe to your computer and use it in GitHub Desktop.
Save idvorkin/cfa7b482f04aceb040d8822ad95fcabe to your computer and use it in GitHub Desktop.
//
// ContentView.swift
// PlayAVFoundation
//
// Created by Igor Dvorkin on 10/22/23.
//
import SwiftUI
import AVFoundation
import Swifter
import Foundation
class PersonalSynth{
var invocation=0
let synth = AVSpeechSynthesizer()
var personalVoice = AVSpeechSynthesisVoice()
public func speak(text:String){
print("\(invocation)> \(text)")
let utterance = AVSpeechUtterance(string: text)
utterance.voice = personalVoice
synth.speak(utterance)
print("\(invocation)> done")
invocation += 1
}
init()
{
AVSpeechSynthesizer.requestPersonalVoiceAuthorization(completionHandler: { (result) in
print("Complete \(result)")
})
for voice in AVSpeechSynthesisVoice.speechVoices()
{
if voice.identifier.contains("personalvoice")
{
print(voice.identifier)
personalVoice = voice
return
}
}
print ("Personal Voice not Found")
}
}
let synth = PersonalSynth()
class TalkingWebResponder{
init()
{
let port:in_port_t = 9007
let server = HttpServer()
server["/speak"] = { request in
print ("R \(request)")
print ("R.QP \(request.queryParams)")
print ("R.P \(request.params)")
// Do URL decoding, including '+' to ' '
let text_to_speak = String(request.queryParams.first?.1.replacingOccurrences(of:"+",with:" ").removingPercentEncoding ?? "")
synth.speak(text:text_to_speak)
return HttpResponse.ok(.text(text_to_speak))
}
server.listenAddressIPv4="127.0.0.1" // Only listen on locahost
do {
print ("Starting Server: \(port)")
try server.start(port, forceIPv4: true)
print ("Ending Server")
// without the sleep, the server never runs.
sleep(1)
}
catch
{
print("Server Error \(error)")
}
}
public func forceAlive()
{
print("Force Alive")
}
}
let webServer = TalkingWebResponder()
struct ContentView: View {
@State var textInTextBox:String = "Hey, the computer is talking for me"
var body: some View {
VStack {
TextField("Igor in Text Feild", text:$textInTextBox, onEditingChanged: {starting in
if !starting {
speakText()
}
})
.frame(maxWidth: .infinity)
.font(Font.system(size: 20, design: .default))
Button("Ugly"){
speakText()
}.frame(maxWidth: .infinity)
}
.padding()
}
func speakText(){
synth.speak(text:textInTextBox)
}
init()
{
webServer.forceAlive()
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment