Длина во времени волнового файла

У меня есть простой код, генерирующий волновой файл с использованием TTS и затем воспроизводящий его:

public void TestSpeech()
{
    SpeechSynthesizer synth = new SpeechSynthesizer();
    using (MemoryStream stream = new MemoryStream())
    {
        synth.SetOutputToWaveStream(stream);
        synth.Speak("Hello world");
        stream.Seek(0, SeekOrigin.Begin);
        IWaveSource source = new WaveFileReader(stream);
        EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
        var soundOut = new WasapiOut();
        soundOut.Initialize(source);
        soundOut.Stopped += (s, e) => waitHandle.Set();
        soundOut.Play();
        waitHandle.WaitOne();
        soundOut.Dispose();
        source.Dispose();
    }
}

Все работает нормально, но я хочу знать, прежде чем начать воспроизведение волнового файла, как долго он будет продолжаться. Есть какой-то способ вычисления этого, или это доступно где-нибудь?

Если оно доступно где-то, как рассчитывается? Я предполагаю, что это связано с количеством данных в потоке, но как?

2 ответа

Решение

Вы можете использовать CSCore или NAudio:

CSCore (из этого примера извлекаются текущая позиция воспроизведения и общая продолжительность):

using System;
using CSCore;
using CSCore.Codecs.WAV;

IWaveSource wavSource = new WaveFileReader(stream);
TimeSpan totalTime = wavSource.GetLength();

NAudio:

using System;
using NAudio.Wave;

using (var wfr = new WaveFileReader(stream))
{
    TimeSpan totalTime = wfr.TotalTime;
}

Также см. Документы MSDN для TimeSpan.

Длительность рассчитывается из общей длины данных WAVE (которая может быть оценкой для сжатых файлов) и средних байтов в секунду (согласно источнику NAudio в свойстве TotalTime):

totalTimeInSeconds = LengthInBytes / AverageBytesPerSecond;
using CSCore;

IWaveSource waveSource = new WaveFileReader(stream);
TimeSpan totalTime = waveSource.GetLength( ); //get length returns a timespan

В случае, если кто-то ищет обходной путь, я обработал его следующим образом: (простите за мой первый комментарий Stackru)

  1. Я создал bool mouseScrewsAround = false
  2. событие таймера, которое изменяет положение trackBar во время воспроизведения, срабатывает только если! mouseScrewsAround
  3. trackBar_MouseDown -> mouseScrewsAround = true
  4. trackBar_MouseUp -> изменить положение дорожки, затем mouseScrewsAround = false
Другие вопросы по тегам