locked
[UWP] [C#] mp3/audio files created in code no longer playable? RRS feed

  • Question

  • Hi all,

    I have a question here about a simple app I created which converts text-to-speech into an audio file (.mp3), which the user can save and then move on the device of their choice to play it.

    The code I use to create the audio file is included below for your information.

    Here is the problem that some users are reporting:

    "Playing mp3 files created by your app no longer works on my mp3 player, but the mp3 files I created with your app a few weeks ago can still be played".

    Note that I haven't changed the code in the app. So here is my question: Has something happened in a recent Windows 10 update that means creating audio files in code the way I do will prevent them from playing on certain devices?

    Users can still play their mp3 files using VLC on Windows 10, but not on their other/simpler mp3 players of their choice. Users on Mac/Apple also report that the audio files are not playable.

    Thanks for your help,

    Cyprien

    Code used in my app is a follows:

    using Windows.Media.SpeechSynthesis;
    
    SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(somethingToSay);
                
    var savePicker = new FileSavePicker();
    savePicker.SuggestedStartLocation = PickerLocationId.Desktop;
    savePicker.FileTypeChoices.Add("Sound", new List<string>() { ".mp3" });
    savePicker.SuggestedFileName = ((HearItFirst2015.Speech)listViewSavedList.SelectedItem).SavedName;
    
    var file = await savePicker.PickSaveFileAsync();
    
    using (var reader = new DataReader(synthesisStream))
    {
    await reader.LoadAsync((uint)synthesisStream.Size);
    IBuffer buffer = reader.ReadBuffer((uint)synthesisStream.Size);
    await FileIO.WriteBufferAsync(file, buffer);
    }


    cypripri

    Friday, November 9, 2018 11:21 PM

Answers

  • Hi Cypripri,

    Username is correct. The SpeechSynthsizer outputs its data as uncompressed PCM data. I took a look at the output generated by your code and I can confirm that there is a WAV header associated with the stream. This makes it a legitimate RIFF formatted file. This means that if the 3rd party players support playing AV / uncompressed PCM audio your users might be able to rename the files from .mp3 to .wav to solve the problem. 

    If you want to target MP3 you can use the Windows.Media.Transcoding.MediaTranscoder API to convert the PCM stream to MP3 and then write it out as a file. 

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/



    Friday, November 30, 2018 12:22 AM

All replies

  • Hi,

    What is the OS build after your customers updated their device and get this error? Did you reproduce this issue on your system with the same version ? If so, could you please told me your OS version? You could run command winver to check the OS build.

    I run the code snippet with same somethingToSay (e.g. "Hello World")in your post on build 17134.1 and 17763.55, saved the mp3 files, they can play well on windows and my iphone.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, November 12, 2018 9:37 AM
  • Is not stream generated by SpeeachSynthsizer always in .wav format? Players may be confused because they expect mp3.
    Monday, November 12, 2018 4:43 PM
  • Thank you very much for testing this for me Roy and it's reassuring to hear it worked on both your devices.

    Maybe this is relating to the user's mp3 player? I have been informed it is the Nokia 3310 phone which is used as their mp3 player. The user has version 1803 of Windows 10, but I don't know the build.

    I haven't managed to recreate the issue myself. Maybe this is an isolated case due to the Nokia 3310?

    I wanted to make sure I wasn't missing something obvious.

    Thanks,

    Cyprien


    cypripri

    Monday, November 12, 2018 10:10 PM
  • Yes that's an interesting point! I need to find out more about this...

    Thank you,

    Cyprien


    cypripri

    Monday, November 12, 2018 10:15 PM
  • Hi,

    Is there any other devices that will give this error except Nokia 3310? Try to figure out if this only happens on specific devices.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by cypripri Monday, November 19, 2018 1:38 PM
    • Unmarked as answer by cypripri Saturday, November 24, 2018 9:24 PM
    Tuesday, November 13, 2018 7:44 AM
  • I have now received the confirmation that the issue is for MP3 players which don't run on PC, iOS or Android.

    The following have been tested by a user and the mp3 file cannot be played any longer (the issue here mainly is that it used to work!):

    - Nokia 3310 mp3 player

    Energy system mp3 player

    - Sansa sandisk player

    - Agptek player

    Thank you.


    cypripri

    Saturday, November 24, 2018 9:29 PM
  • Hi,

    I've been asking other engineers about this. There might be some time delay.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 29, 2018 8:44 AM
  • Hi Cypripri,

    Username is correct. The SpeechSynthsizer outputs its data as uncompressed PCM data. I took a look at the output generated by your code and I can confirm that there is a WAV header associated with the stream. This makes it a legitimate RIFF formatted file. This means that if the 3rd party players support playing AV / uncompressed PCM audio your users might be able to rename the files from .mp3 to .wav to solve the problem. 

    If you want to target MP3 you can use the Windows.Media.Transcoding.MediaTranscoder API to convert the PCM stream to MP3 and then write it out as a file. 

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/



    Friday, November 30, 2018 12:22 AM
  • Transcoding to MP3 is not as easy as you would think. I spent some time and threw together some really naïve but apparently functional code.

    May contain bugs. No warranties. Use at your own risk. 

        public sealed partial class MainPage : Page
        {
            InMemoryRandomAccessStream _OutStream = new InMemoryRandomAccessStream();
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void _btnTalk_Click(object sender, RoutedEventArgs e)
            {
                // The media object for controlling and playing audio.
                MediaElement mediaElement = this._ME;
    
                // The object for controlling the speech synthesis engine (voice).
                var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
    
                // Generate the audio stream from plain text.
                SpeechSynthesisStream InStream = null;
                InStream = await synth.SynthesizeTextToStreamAsync("Hello World");
    
                // Convert the stream to an MP3 and then save it to file.
                ConvertToMP3(InStream);
             
                // Send the stream to the media object.
                mediaElement.SetSource(InStream, InStream.ContentType);
                mediaElement.Play();
            }
    
            private async void ConvertToMP3(IRandomAccessStream InStream)
            {
                _tbTranscodingStatus.Text = "Transcoding";
    
                MediaTranscoder _Transcoder = new Windows.Media.Transcoding.MediaTranscoder();
    
                // NOTE: Setting a profile with AudioEncodingQuality.Auto does not work iwht MP3.
                MediaEncodingProfile Profile = MediaEncodingProfile.CreateMp3(AudioEncodingQuality.Low);
    
                var PrepTranscode = await _Transcoder.PrepareStreamTranscodeAsync(InStream, _OutStream, Profile);
    
                if(PrepTranscode.CanTranscode == true)
                {
                    var TranscodeAsyncResult = PrepTranscode.TranscodeAsync();
    
                    TranscodeAsyncResult.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
                }
                else
                {
                    _tbTranscodingStatus.Text = "Unable to Transcode";
                }
            }
    
            private async void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus asyncStatus)
            {
                asyncInfo.GetResults();
                if (asyncInfo.Status == AsyncStatus.Completed)
                {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        _tbTranscodingStatus.Text = "Transcoding Complete";
                        SaveMP3ToFile(_OutStream);
                    });
                }
                else if (asyncInfo.Status == AsyncStatus.Canceled)
                {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        _tbTranscodingStatus.Text = "Transcoding Canceled";
                    });
                }
                else
                {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                    () =>
                    {
                        _tbTranscodingStatus.Text = "Transcoding Error";
                    });
                }           
            }
    
            private async void SaveMP3ToFile(IRandomAccessStream stream)
            {
                _tbTranscodingStatus.Text = "Writing File";
    
                var savePicker = new FileSavePicker();
                savePicker.SuggestedStartLocation = PickerLocationId.Desktop;
                savePicker.FileTypeChoices.Add("Sound", new List<string>() { ".mp3" });
    
                var file = await savePicker.PickSaveFileAsync();
    
                //NOTE: You must seek back to the beginnign of the sream before you can create your DataReader.
                stream.Seek(0);
    
                using (var reader = new DataReader(stream))
                {
                    await reader.LoadAsync((uint)stream.Size);
    
                    IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
                    await FileIO.WriteBufferAsync(file, buffer);
                }
    
                _tbTranscodingStatus.Text = "File Write Success";
            }
        }

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Friday, November 30, 2018 1:58 AM
  • Thank you very much for your explanation and code sample,

    this makes sense and I will be able to work with this.

    Thanks :)


    cypripri

    Friday, November 30, 2018 8:14 PM