ios - 如何将文本到语音的输出写入 Swift UI 中的文件?
问题描述
我正在尝试将文本到语音的输出写入声音文件。我基本上从这个 stackoverflow 答案中复制了代码,我发现它在故事板应用程序中工作,但当我迁移到 SwiftUI 时不再工作。
以下是一个完整的应用程序,只需将其粘贴到新的 SwiftUI 应用程序中的 ContentView 中并点击运行即可。
import SwiftUI
import AVFoundation
struct ContentView: View {
var body: some View {
Button(action: runSpeech) {
Text("Button")
}
}
func runSpeech() {
let fileURL = generateSpeech("hello world", 1.0)
if FileManager.default.fileExists(atPath: fileURL!.path) {
print(" Speech file exists at \(fileURL!)")
} else {
print(" no file exists at \(fileURL!)")
}
return
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
func generateSpeech(_ speech: String, _ speechRate: Float) -> URL? {
let synth = AVSpeechSynthesizer()
let myUtterance = AVSpeechUtterance(string: speech)
myUtterance.rate = speechRate
myUtterance.voice = AVSpeechSynthesisVoice(language: "en")!
myUtterance.postUtteranceDelay = 2
let dataPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
do {
try FileManager.default.createDirectory(atPath: dataPath?.path ?? "", withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
print("Error creating directory: \(error.localizedDescription)")
}
let fileName = "myspeech.caf"
let fileURL = dataPath?.appendingPathComponent(fileName)
if FileManager.default.fileExists(atPath: fileURL!.path) {
print("Speech file exists at \(fileURL!)")
return fileURL
}
print("Speech file does not exist at \(fileURL!)")
var output: AVAudioFile?
synth.write(myUtterance) { (buffer: AVAudioBuffer) in
print("callback")
guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
fatalError("unknown buffer type: \(buffer)")
}
if pcmBuffer.frameLength == 0 {
// done
} else {
// append buffer to file
do {
if output == nil {
try output = AVAudioFile(
forWriting: fileURL!,
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)
}
try output?.write(from: pcmBuffer)
} catch {
print("error")
}
}
}
print("return")
return fileURL!
}
预期输出:
Speech file does not exist at file:///var/mobile/Containers/Data/Application/A5E69CE0-FB83-481C-89B2-26C802446A03/Documents/myspeech.caf
callback
return
Speech file exists at file:///var/mobile/Containers/Data/Application/A5E69CE0-FB83-481C-89B2-26C802446A03/Documents/myspeech.caf
实际输出:
Speech file does not exist at file:///var/mobile/Containers/Data/Application/A5E69CE0-FB83-481C-89B2-26C802446A03/Documents/myspeech.caf
return
no file exists at file:///var/mobile/Containers/Data/Application/A5E69CE0-FB83-481C-89B2-26C802446A03/Documents/myspeech.caf
特别注意callback
永远不会运行,那里出了点问题。
解决方案
let fileName = "Content.txt";
let fileManger = FileManager.default;
let doumentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString;
let filePath = doumentDirectoryPath.appendingPathComponent(fileName);
if fileManger.fileExists(atPath: filePath) {
let url = URL(fileURLWithPath: filePath);
//your file is in url
}else{
// file not exist
}
推荐阅读
- java - 在Java中以相反的顺序对ArrayList进行排序
- c# - 带有 MVC 数据库的 ASP.NET MVC 谷歌图表
- here-api - 免费增值帐户中可用的 ADAS_ATTRIB 属性?
- angular - 构建'找不到名称'排除'时出现lodash-es错误。
- java - 通过套接字或回调进行持续的服务器客户端通信
- docker - 无论如何要跟踪谁从私有存储库下载了 docker 映像
- javascript - 声明一个变量并在html中使用它
- javascript - 如何让这个java脚本在视频结尾显示广告
- azure - 如何为读者角色授予对 Azure 应用服务的 ssh 访问权限?
- powershell - powershell中带引号的字符串变量