簡體   English   中英

使用Naudio復制Wave文件 - 復制/附加最新可用字節

[英]Replicate Wave file using Naudio - Copy/Append Latest Available bytes

我有一個Active wave錄制wave-file.wav發生在Source文件夾中。 我需要使用新名稱wave-file-copy.wav將此文件復制到Destination文件夾。

錄制和復制應該並行進行。 我已經實現了一個預定的作業,它將每10分鍾運行一次,並將source文件復制到destination

private static void CopyWaveFile(string destinationFile, string sourceFile){
        using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
            using (var reader = new WaveFileReader(fs)){
                using (var writer = new WaveFileWriter(destinationFile, reader.WaveFormat)){
                    reader.Position = 0;
                    var endPos = (int)reader.Length;
                    var buffer = new byte[1024];
                    while (reader.Position < endPos){
                        var bytesRequired = (int)(endPos - reader.Position);
                        if (bytesRequired <= 0) continue;
                        var bytesToRead = Math.Min(bytesRequired, buffer.Length);
                        var bytesRead = reader.Read(buffer, 0, bytesToRead);
                        if (bytesRead > 0){
                            writer.Write(buffer, 0, bytesRead);
                        }
                    }
                }
            }
        }
    }

即使源文件正在不斷更新,復制操作也能正常工作。

復制操作所花費的時間在線性時間內增加,因為我每次都復制整個文件。

我正在嘗試實現一個新函數ConcatenateWavFiles() ,它應該使用最新的源記錄字節來更新目標文件的內容。

我嘗試過幾個示例代碼 - 我使用的方法是:

  1. 讀取目標文件元信息,並獲取長度。
  2. 將目標文件的length設置為reader.Position 。源文件waveReader
  3. 從位置開始讀取源文件直到結束。

     public static void ConcatenateWavFiles(string destinationFile, string sourceFile){ WaveFileWriter waveFileWriter = null; var sourceReadOffset = GetWaveFileSize(destinationFile); try{ using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var reader = new WaveFileReader(fs)) { waveFileWriter = new WaveFileWriter(destinationFile, reader.WaveFormat); if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat)){ throw new InvalidOperationException( "Can't append WAV Files that don't share the same format"); } var startPos = sourceReadOffset - sourceReadOffset % reader.WaveFormat.BlockAlign; var endPos = (int) reader.Length; reader.Position = startPos; var bytesRequired = (int)(endPos - reader.Position); var buffer = new byte[bytesRequired]; if (bytesRequired > 0) { var bytesToRead = Math.Min(bytesRequired, buffer.Length); var bytesRead = reader.Read(buffer, 0, bytesToRead); if (bytesRead > 0) { waveFileWriter.Write(buffer, startPos, bytesRead); } } } } } finally{ if (waveFileWriter != null){ waveFileWriter.Dispose(); } } } 

我能夠獲得新內容。

是否可以將最新內容附加到現有目標文件?

如果可能,我在代碼中做錯了什么?

我的代碼拋出以下異常 - Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

我找不到使用NAudio Library進行波形音頻文件復制的解決方案。

但我已經使用C#MemoryStreams和FileStreams實現了一個解決方案。

  1. 如果目標文件不存在,則將源文件復制到目標。
  2. 將所有最新字節(在上次操作之后記錄)附加到目標文件。
  3. 修改Wave File Header以反映最后添加的字節。 (否則文件的持續時間不會更新,只會增加文件大小。
  4. 定期重復此追加操作。

     public void ReplicateFile(string destinationFile, string sourceFile){ if (!Directory.Exists(GetRoutePathFromFile(sourceFile))) return; if (!File.Exists(sourceFile)) return; if (Directory.Exists(GetRoutePathFromFile(destinationFile))){ if (File.Exists(destinationFile)){ UpdateLatestWaveFileContent(destinationFile, sourceFile); }else{ CopyWaveFile(destinationFile, sourceFile); } }else{ Directory.CreateDirectory(GetRoutePathFromFile(destinationFile)); CopyWaveFile(destinationFile, sourceFile); } } private static string GetRoutePathFromFile(string file){ var rootPath = Directory.GetParent(file); return rootPath.FullName; } private static void CopyWaveFile(string destination, string source){ var sourceMemoryStream = new MemoryStream(); using (var fs = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){ fs.CopyTo(sourceMemoryStream); } using (var fs = new FileStream(destination, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)){ sourceMemoryStream.WriteTo(fs); } } private static void UpdateLatestWaveFileContent(string destinationFile, string sourceFile){ var sourceMemoryStream = new MemoryStream(); long offset = 0; using (var fs = File.Open(destinationFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){ offset = fs.Length; } using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){ fs.CopyTo(sourceMemoryStream); } var length = sourceMemoryStream.Length - offset; var buffer = sourceMemoryStream.GetBuffer(); using (var fs = new FileStream(destinationFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)){ fs.Write(buffer, (int)offset, (int)length); } var bytes = new byte[45]; for (var i = 0; i < 45; i++){ bytes[i] = buffer[i]; } ModifyHeaderDataLength(destinationFile, 0, bytes); } private static void ModifyHeaderDataLength(string filename, int position, byte[] data){ using (Stream stream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)) { stream.Position = position; stream.Write(data, 0, data.Length); } } 

嘗試在源文件的實際結束之前讀取源文件一個或兩個Wav塊。

情況可能是代碼判斷源文件的結尾太近以至於不舒服。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM