【问题标题】:How to save SpeechSynthesis audio to a Mp3 file in a UWP application如何将 SpeechSynthesis 音频保存到 UWP 应用程序中的 Mp3 文件
【发布时间】:2020-03-22 11:41:07
【问题描述】:

我正在开发 UWP TTS(文本到语音)应用程序,但无法将语音保存到文件中,最好是 Mp3 格式。有谁知道如何做到这一点?在 WPF 中,我使用了 NAUDIO 和 NAUDIO.LAME,但不幸的是,这似乎不支持 UWP。我想我必须使用 Windows.Media.Transcoding API,但我没有找到任何如何做到这一点的例子。我在 MSDN 上的一篇文章中找到了下面的代码,但它不正确。

        StorageFile file = await savePicker.PickSaveFileAsync();
        if (file != null)
        {
            try
            {
                SpeechSynthesisStream stream = await WCSVariables.Synthesizer.SynthesizeTextToStreamAsync(rtbText.Text);

                using (var reader = new DataReader(stream))
                {
                    await reader.LoadAsync((uint)stream.Size);
                    IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
                    await FileIO.WriteBufferAsync(file, buffer);
                }


            }
            catch (Exception ex)
            {
                MessageDialog msgdlg = new MessageDialog(ex.Message);
                msgdlg.ShowAsync();
            }

********** 更新 **********

为 TXT 和 MP3 添加功能和文件类型关联后,我能够将 TXT 文件保存在任何文件夹中,但 MP3 文件的格式不正确。文件已创建但不播放音频。

FileSavePicker savePicker = new FileSavePicker();
        savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
        savePicker.FileTypeChoices.Add("Mp3 Audio File", new List<string>() { ".mp3" });
        savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" });
        savePicker.SuggestedFileName = "New Document";

        StorageFile file = await savePicker.PickSaveFileAsync();
        if (file != null)
        {
            try
            {
                if (file.FileType == ".txt")
                {
                    await FileIO.WriteTextAsync(file, rtbText.Text);
                }
                else
                {
                    string path = file.Path.Remove(file.Path.IndexOf(file.Name), file.Name.Length);

                    StorageFolder mp3Folder = await StorageFolder.GetFolderFromPathAsync(path);
                    StorageFile mp3File = await mp3Folder.CreateFileAsync(file.Name, CreationCollisionOption.ReplaceExisting);
                    SpeechSynthesisStream stream = await WCSVariables.Synthesizer.SynthesizeTextToStreamAsync(rtbText.Text);

                    using (var reader = new DataReader(stream))
                    {
                        await reader.LoadAsync((uint)stream.Size);
                        IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
                        await FileIO.WriteBufferAsync(mp3File, buffer);
                    }
                }
            } 
            catch (Exception ex)
            {
                MessageDialog msgdlg = new MessageDialog(ex.Message);
                msgdlg.ShowAsync();
            }
        }

【问题讨论】:

    标签: c# uwp mp3 naudio


    【解决方案1】:

    您可以先创建一个 .mp3 文件,然后从基本文本字符串生成语音音频流。之后,将流写入文件。

    StorageFolder folder = KnownFolders.VideosLibrary;
    StorageFile file = await folder.CreateFileAsync("MyVideo.mp3",CreationCollisionOption.ReplaceExisting);
    if (file != null)
    {
        try
        {
            var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
            SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
    
            using (var reader = new DataReader(stream))
            {
                await reader.LoadAsync((uint)stream.Size);
                IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
                await FileIO.WriteBufferAsync(file, buffer);
            }
        }
        catch {}
    }
    

    【讨论】:

    • MSFT,此 StorageFolder 导致访问权限错误。我试图包含对 broadFileSystemAccess 功能的引用,但它也没有解决。我可以使它工作的唯一方法是将 StorageFolder 更改为 ApplicationData.Current.LocalFolder,但这不适合我。有什么建议吗?
    • 如果你想像上面那样访问视频库,你需要在清单中添加“视频库”功能而不是 broadFileSystemAccess。访问文件路径时使用broadFileSystemAccess。
    • 感谢@Faywang,对于我正在开发的桌面应用程序,用户可以访问除视频、图片和音乐之外的许多文件夹。如何访问这些文件夹以保存和恢复文件?在 Microsoft 文档中,我找到了使用 LocalCache 文件夹的建议,但是如何将它与 FilePicker 一起使用?
    • 如果您想访问其他文件夹,您需要使用StorageFolder.GetFolderFromPathAsync() 方法通过传递文件夹的路径并声明broadFileSystemAccess 能力或使用FileOpenPicker 来获取文件夹。此外,关于 FileOpenPicker,它会打开一个类似于文件资源管理器的对话框,然后您可以从您想要的位置选择文件并在您的应用程序中使用它。但是要找到您的 LocalCache 文件夹并不容易。所以最好不要将缓存文件夹与选择器一起使用。可以使用Windows.Storage.ApplicationData.Current.LocalCacheFolder.Path查看缓存文件夹在哪里。
    • 我在主题中添加了更新。现在我可以将文件保存在任何文件夹中,但是 Mp3 格式不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 2022-11-14
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    相关资源
    最近更新 更多