gpt4 book ai didi

c# - 使用 Naudio 复制 Wave 文件 - 复制/附加最新的可用字节

转载 作者:太空狗 更新时间:2023-10-30 01:32:58 26 4
gpt4 key购买 nike

我在 Source 文件夹中有一个 Active wave 录音 wave-file.wav。我需要使用新名称 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为源文件waveReaderreader.Position
  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();
    }
    }
    }

我能够获得新内容。

是否可以将最新内容附加到现有目标文件?

如果可能的话,我在代码中做错了什么?

我的代码抛出以下异常 - 偏移量和长度超出数组范围或计数大于从索引到源集合末尾的元素数。

最佳答案

我找不到使用 NAudio 库复制 wave 音频文件的解决方案。

但我已经使用 C# MemoryStreams 和 FileStreams 实现了一个解决方案。

  1. 如果目标文件不存在,则将源文件复制到目标。
  2. 将所有最新的字节(在最后一次操作后记录)附加到目标文件。
  3. 将 Wave 文件头修改为以反射(reflect)最后附加的字节。 (否则文件的持续时间不会更新,只会增加文件大小。
  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);
    }
    }

关于c# - 使用 Naudio 复制 Wave 文件 - 复制/附加最新的可用字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35335269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com