Как воспроизвести фрагмент звука в C# с помощью ContentPushStream?

У меня есть поток байтов в памяти, принадлежащий видеофайлу.

Обратите внимание, что поток байтов представляет не весь видеофайл, а скорее фрагмент видеофайла в байтах, который у меня есть в данный момент. Я хочу иметь возможность воспроизвести этот фрагмент на видеоплеере или передать его в потоковом режиме, если смогу. Но я хочу сам контролировать поток потока, так как я получаю источник видео с разных серверов.

Мы попробовали следующий образец:

https://www.codeproject.com/Articles/820146/HTTP-Partial-Content-In-ASP-NET-Web-API-Video

В моем случае первый фрагмент загружаемого файла и воспроизводился звук. После загрузки следующего чанка файл хоть и обновляется, но не обновляется в плеере. Нужно слить чанк и обновить файл в плеере. Пожалуйста, найдите фрагмент кода здесь:

            int count = 0;
            long remainingBytes = end - start + 1;
            long position = start;
            byte[] buffer = new byte[ReadStreamBufferSize];

            byte[] temp = new byte[ReadStreamBufferSize];

            inputStream.Position = start;
            int item = 1;
            do
            {
                try
                {

                    byte[] byteAry = new byte[ReadStreamBufferSize];
                    if (System.IO.File.Exists("D:\\test\\pp" + item + ".wav")){
                        byteAry = System.IO.File.ReadAllBytes("D:\\test\\pp" + item + ".wav");
                    }
                    else
                    {
                        break;
                    }
                    temp = temp.Concat(byteAry).ToArray();                    
                    inputStream = new MemoryStream(temp);

                    if (remainingBytes > ReadStreamBufferSize)
                        count = inputStream.Read(buffer, 0, ReadStreamBufferSize);
                    else
                        count = inputStream.Read(buffer, 0, (int)remainingBytes);
                    outputStream.Write(buffer, 0, count);
                }
                catch (Exception error)
                {
                    Debug.WriteLine(error);

                    break;
                }
                position = inputStream.Position + 100;
                end = inputStream.Length;
                remainingBytes = end - position + 1;
                item++;
            } while (position <= end);
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
606
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно воссоздать заголовок файла WAVE с учетом размера всех файлов, а затем добавить аудиоданные, например:

int item = 1;

var inputWaveFiles = new List<WaveFile>();

while (File.Exists($@"D:\test\pp{item}.wav"))
{
    var waveFile = WaveFile.ReadWaveFile($@"D:\test\pp{item}.wav");
    inputWaveFiles.Add(waveFile);
    item++;
}

WaveFile.Merge(inputWaveFiles, @"D:\test\output.wav");

public class WaveFile
{
    public string Path { get; set; }
    public int Length { get; set; }
    public short Channels { get; set; }
    public int SampleRate { get; set; }
    public int DataLength { get; set; }
    public short BitsPerSample { get; set; }

    private void WriteHeader(string filename)
    {
        using (var file = new FileStream(filename, FileMode.Create, FileAccess.Write))
        {
            using (var writer = new BinaryWriter(file))
            {
                file.Position = 0;
                writer.Write(new char[4] { 'R', 'I', 'F', 'F' });

                writer.Write(Length);

                writer.Write(new char[8] { 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ' });

                writer.Write((int)16);

                writer.Write((short)1);
                writer.Write(Channels);

                writer.Write(SampleRate);

                writer.Write((int)(SampleRate * ((BitsPerSample * Channels) / 8)));

                writer.Write((short)((BitsPerSample * Channels) / 8));

                writer.Write(BitsPerSample);

                writer.Write(new char[4] { 'd', 'a', 't', 'a' });
                writer.Write(DataLength);
            }
        }
    }

    public static WaveFile ReadWaveFile(string filename)
    {
        var waveFile = new WaveFile();
        waveFile.Path = filename;

        using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read))
        {
            using (var reader = new BinaryReader(file))
            {
                waveFile.Length = (int)file.Length - 8;
                file.Position = 22;
                waveFile.Channels = reader.ReadInt16();
                file.Position = 24;
                waveFile.SampleRate = reader.ReadInt32();
                file.Position = 34;
                waveFile.BitsPerSample = reader.ReadInt16();
                waveFile.DataLength = (int)file.Length - 44;
            }
        }
        return waveFile;
    }

    public static void Merge(List<WaveFile> waveFiles, string outputFilename)
    {
        var outputWave = new WaveFile();

        foreach(var waveFile in waveFiles)
        {
            outputWave.DataLength += waveFile.DataLength;
            outputWave.Length += waveFile.Length;
        }

        // Generate file with header (I just copy the sample rate etc.. from the first sound file)
        outputWave.BitsPerSample = waveFiles[0].BitsPerSample;
        outputWave.Channels = waveFiles[0].Channels;
        outputWave.SampleRate = waveFiles[0].SampleRate;
        outputWave.WriteHeader(outputFilename);

        // Append data
        foreach (var waveFile in waveFiles)
        {
            // Read wave file
            using (var fileReader = new FileStream(waveFile.Path, FileMode.Open, FileAccess.Read))
            {
                var inputData = new byte[fileReader.Length - 44];
                fileReader.Position = 44;
                fileReader.Read(inputData, 0, inputData.Length);

                // Write wave file
                using (var fileWriter = new FileStream(outputFilename, FileMode.Append, FileAccess.Write))
                {
                    using (var writer = new BinaryWriter(fileWriter))
                    {
                        writer.Write(inputData);
                    }
                }
            }
        }
    }
}

использованная литература

http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html

https://www.codeproject.com/Articles/15187/Concatenating-Wave-Files-Using-C-2005

Другие вопросы по теме