[英]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()
,它應該使用最新的源記錄字節來更新目標文件的內容。
我嘗試過幾個示例代碼 - 我使用的方法是:
length
設置為reader.Position
。源文件waveReader
從位置開始讀取源文件直到結束。
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實現了一個解決方案。
定期重復此追加操作。
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.