【问题标题】:How to store a text-to-speech audio in an audio file (IOS)如何将文本到语音的音频存储在音频文件中(IOS)
【发布时间】:2022-01-01 08:31:46
【问题描述】:

我正在尝试在 IOS 中创建一个带有文本转语音的视频(就像 TikTok 一样)。我认为做到这一点的唯一方法是将视频和音频与 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);

错误:

无法初始化该类型的实例 'AVFoundation.AVAudioFile':本机 'initForWriting:settings:commonFormat:interleaved:error:' 方法 返回零。可以通过设置忽略此条件 ObjCRuntime.Class.ThrowOnInitFailure 为 false。

【问题讨论】:

    标签: c# ios objective-c xamarin.forms avfoundation


    【解决方案1】:

    错误只是显示An AVSpeechUtterance shall not be enqueued twice

    所以不要让它同时说和写。

    我使用了你的代码并注释掉了synthesizer.SpeakUtterance(su);,错误消失了。

    更新

    根据我的测试,它不允许创建额外的子文件夹,所以删除TTS/部分,只保留文件名。

    string filePath = Path.Combine(Path.GetTempPath(),  1 + ".caf");
    

    【讨论】:

    • 谢谢,ColeX,你的回答对解决上面提到的问题很有帮助,不幸的是,另一个问题合并了,我编辑了我的原帖,你能看一下吗?非常感谢您的参与。 (:
    • 检查我的更新。
    • 感谢您的帮助ColeX,我已经更新了我的代码,现在“.caf”文件已成功生成,但是,该文件不包含指定的音频,它是0秒-长度的音频文件。知道为什么会发生这种情况吗?
    • 好的,我刚刚找到了我缺少的东西,“AVAudioFile output = null;”应该在方法之外,否则,它会一遍又一遍地重置自己。感谢您的帮助 ColeX,我会将您的消息标记为答案,祝您有美好的一天。 (:
    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    相关资源
    最近更新 更多