如何在音频文件中存储文本到语音的音频 (IOS)
How to store a text-to-speech audio in an audio file (IOS)
我正在尝试使用文本转语音(就像 TikTok 所做的那样)在 IOS 中创建视频。我认为唯一的方法是将视频和音频与 AVFoundations 合并,但似乎不可能将文本到语音的音频插入 .caf 文件。
这是我试过的:
public async Task amethod(string[] _text_and_position)
{
string[] text_and_position = (string[])_text_and_position;
double tts_starting_position = Convert.ToDouble(text_and_position[0]);
string text = text_and_position[1];
var synthesizer = new AVSpeechSynthesizer();
var su = new AVSpeechUtterance(text)
{
Rate = 0.5f,
Volume = 1.6f,
PitchMultiplier = 1.4f,
Voice = AVSpeechSynthesisVoice.FromLanguage("en-us")
};
synthesizer.SpeakUtterance(su);
Action<AVAudioBuffer> buffer = new Action<AVAudioBuffer>(asss);
try
{
synthesizer.WriteUtterance(su, buffer);
}
catch (Exception error) { }
}
public async void asss(AVAudioBuffer _buffer)
{
try
{
var pcmBuffer = (AVAudioPcmBuffer)_buffer;
if (pcmBuffer.FrameLength == 0)
{
// done
}
else
{
AVAudioFile output = null;
// append buffer to file
NSError error;
if (output == null)
{
string filePath = Path.Combine(Path.GetTempPath(), "TTS/" + 1 + ".caf");
NSUrl fileUrl = NSUrl.FromFilename(filePath);
output = new AVAudioFile(fileUrl, pcmBuffer.Format.Settings, AVAudioCommonFormat.PCMInt16 , false ,out error);
}
output.WriteFromBuffer(pcmBuffer, out error);
}
}
catch (Exception error)
{
new UIAlertView("Error", error.ToString(), null, "OK", null).Show();
}
}
这与 objective-c
中的代码相同
let synthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: "test 123")
utterance.voice = AVSpeechSynthesisVoice(language: "en")
var output: AVAudioFile?
synthesizer.write(utterance) { (buffer: AVAudioBuffer) in
guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
fatalError("unknown buffer type: \(buffer)")
}
if pcmBuffer.frameLength == 0 {
// done
} else {
// append buffer to file
if output == nil {
output = AVAudioFile(
forWriting: URL(fileURLWithPath: "test.caf"),
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)
}
output?.write(from: pcmBuffer)
}
}
这段代码的问题在于“synthesizer.WriteUtterance(su, buffer);”总是崩溃,在阅读其他帖子后,我认为这是一个导致永远不会调用回调方法(缓冲区)的错误。
你知道这个错误的任何解决方法或任何其他方法来实现我正在尝试做的事情吗?
感谢您的宝贵时间,祝您今天愉快。
编辑:
我评论了 synthesizer.SpeakUtterance(su);正如 ColeX 指出的那样,现在执行了回调方法。不幸的是,我还不能将我的音频存储在一个文件中,因为我在
中遇到了另一个错误
output = new AVAudioFile(fileUrl, pcmBuffer.Format.Settings, AVAudioCommonFormat.PCMInt16 , false ,out error);
错误:
Could not initialize an instance of the type
'AVFoundation.AVAudioFile': the native
'initForWriting:settings:commonFormat:interleaved:error:' method
returned nil. It is possible to ignore this condition by setting
ObjCRuntime.Class.ThrowOnInitFailure to false.
错误仅显示 An AVSpeechUtterance shall not be enqueued twice
.
所以不要让它同时说和写。
我使用了你的代码并注释掉了 synthesizer.SpeakUtterance(su);
,错误消失了。
更新
根据我的测试,它不允许创建额外的子文件夹,所以删除 TTS/
部分,只保留文件名。
string filePath = Path.Combine(Path.GetTempPath(), 1 + ".caf");
我正在尝试使用文本转语音(就像 TikTok 所做的那样)在 IOS 中创建视频。我认为唯一的方法是将视频和音频与 AVFoundations 合并,但似乎不可能将文本到语音的音频插入 .caf 文件。
这是我试过的:
public async Task amethod(string[] _text_and_position)
{
string[] text_and_position = (string[])_text_and_position;
double tts_starting_position = Convert.ToDouble(text_and_position[0]);
string text = text_and_position[1];
var synthesizer = new AVSpeechSynthesizer();
var su = new AVSpeechUtterance(text)
{
Rate = 0.5f,
Volume = 1.6f,
PitchMultiplier = 1.4f,
Voice = AVSpeechSynthesisVoice.FromLanguage("en-us")
};
synthesizer.SpeakUtterance(su);
Action<AVAudioBuffer> buffer = new Action<AVAudioBuffer>(asss);
try
{
synthesizer.WriteUtterance(su, buffer);
}
catch (Exception error) { }
}
public async void asss(AVAudioBuffer _buffer)
{
try
{
var pcmBuffer = (AVAudioPcmBuffer)_buffer;
if (pcmBuffer.FrameLength == 0)
{
// done
}
else
{
AVAudioFile output = null;
// append buffer to file
NSError error;
if (output == null)
{
string filePath = Path.Combine(Path.GetTempPath(), "TTS/" + 1 + ".caf");
NSUrl fileUrl = NSUrl.FromFilename(filePath);
output = new AVAudioFile(fileUrl, pcmBuffer.Format.Settings, AVAudioCommonFormat.PCMInt16 , false ,out error);
}
output.WriteFromBuffer(pcmBuffer, out error);
}
}
catch (Exception error)
{
new UIAlertView("Error", error.ToString(), null, "OK", null).Show();
}
}
这与 objective-c
中的代码相同let synthesizer = AVSpeechSynthesizer()
let utterance = AVSpeechUtterance(string: "test 123")
utterance.voice = AVSpeechSynthesisVoice(language: "en")
var output: AVAudioFile?
synthesizer.write(utterance) { (buffer: AVAudioBuffer) in
guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
fatalError("unknown buffer type: \(buffer)")
}
if pcmBuffer.frameLength == 0 {
// done
} else {
// append buffer to file
if output == nil {
output = AVAudioFile(
forWriting: URL(fileURLWithPath: "test.caf"),
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)
}
output?.write(from: pcmBuffer)
}
}
这段代码的问题在于“synthesizer.WriteUtterance(su, buffer);”总是崩溃,在阅读其他帖子后,我认为这是一个导致永远不会调用回调方法(缓冲区)的错误。
你知道这个错误的任何解决方法或任何其他方法来实现我正在尝试做的事情吗?
感谢您的宝贵时间,祝您今天愉快。
编辑: 我评论了 synthesizer.SpeakUtterance(su);正如 ColeX 指出的那样,现在执行了回调方法。不幸的是,我还不能将我的音频存储在一个文件中,因为我在
中遇到了另一个错误output = new AVAudioFile(fileUrl, pcmBuffer.Format.Settings, AVAudioCommonFormat.PCMInt16 , false ,out error);
错误:
Could not initialize an instance of the type 'AVFoundation.AVAudioFile': the native 'initForWriting:settings:commonFormat:interleaved:error:' method returned nil. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false.
错误仅显示 An AVSpeechUtterance shall not be enqueued twice
.
所以不要让它同时说和写。
我使用了你的代码并注释掉了 synthesizer.SpeakUtterance(su);
,错误消失了。
更新
根据我的测试,它不允许创建额外的子文件夹,所以删除 TTS/
部分,只保留文件名。
string filePath = Path.Combine(Path.GetTempPath(), 1 + ".caf");