2012-12-28 63 views
0

我必須從SpeechSynthesizer生成的流中創建音頻文件。無法將流複製到文件

這是代碼我使用

var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language); 
      var reader = new Windows.Storage.Streams.DataReader(stream.GetInputStreamAt(0)); 
      await reader.LoadAsync((uint)stream.Size); 

      byte[] bytes = new byte[stream.Size]; 
      reader.ReadBytes(bytes); 

      var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting); 

      using (var outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite)) 
      { 

       Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite(); 
       await os.WriteAsync(bytes, 0, bytes.Length); 
      } 

我發現了問題是,在「os.WriteAsync」沒有被期待已久的。當我在該行放置一個斷點並等待幾秒鐘,然後正確創建文件。在進入下一行之前,await關鍵字是否應該等到所有字節都被複制到流中?

我不介意是否有人可以建議任何更好的方式將InMemoryRandomAccessStream複製到文件?

編輯:

Mahantesh的答案就像一個魅力。非常感謝。但是我面臨一個新問題。

創建文件後,我試圖再次打開它來播放它,但得到這個錯誤。

「訪問被拒絕(異常來自HRESULT:0X80070005(E_ACCESSDENIED))」。

這是我的代碼。

if (!cacheHit) 
     { 
      var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language); 

      //write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request) 
      var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting); 

      outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite); 

      await RandomAccessStream.CopyAsync(stream, outputStream);     

     } 

     //read agenda from disk and play back the audio 
     var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename); 
     var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read);    

     _MediaPlayer.Url = text; 
     _MediaPlayer.SetBytestream(agendaStreamFromDisk); 
     _MediaPlayer.Play();  

正在錯誤在這行:

var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read); 

任何想法可能什麼錯?

回答

1

我認爲你可以

await RandomAccessStream.CopyAsync(inMemoryStream, outputStream); 

解決新問題的嘗試:

if (!cacheHit) 
    { 
     var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language); 

     //write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request) 
     var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting); 

     using(outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite)){ 
     await RandomAccessStream.CopyAsync(stream, outputStream);} 

    } 

    //read agenda from disk and play back the audio 
    var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename); 
    using (var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read)){ 

    _MediaPlayer.Url = text; 
    _MediaPlayer.SetBytestream(agendaStreamFromDisk); 
    _MediaPlayer.Play(); } 
+0

非常感謝您的回答。但是當我試圖打開文件時,我正面臨着一個新的問題。我編輯了這個問題,你能告訴我哪裏可能會出錯嗎? – Bitsian

+1

需要在下次打開之前關閉輸出流(outputStream .Close)或嘗試「使用」塊 – Mahantesh

0

當您使用await關鍵字等待最好是使用方法syncronous版本,像

using (var outputStream = audioFile.Open(FileAccessMode.ReadWrite)) 
{ 
    Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite(); 
    os.Write(bytes, 0, bytes.Length); 
} 
+0

即使那不工作.....不知道y!但是當我放置一個斷點並在os.Write之後的下一行等待幾秒時,outputstream會獲得一定的大小。真奇怪。任何想法可能發生什麼? – Bitsian

相關問題