it-swarm-ru.tech

Как я могу определить длину (то есть продолжительность) WAV-файла в C #?

В несжатой ситуации я знаю, что мне нужно прочитать wav-заголовок, извлечь количество каналов, бит и частоту дискретизации и обработать их оттуда: (Каналы) * (биты) * (сэмплы/с) * (секунд) = (размер файла)

Есть ли более простой способ - бесплатная библиотека или что-то в фреймворке .net?

Как мне это сделать, если файл .wav сжимается (например, с помощью кодека mpeg)?

26
John Sibly

Вы можете рассмотреть возможность использования функции mciSendString (...) (проверка ошибок для ясности опущена):

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace Sound
{
    public static class SoundInfo
    {
        [DllImport("winmm.dll")]
        private static extern uint mciSendString(
            string command,
            StringBuilder returnValue,
            int returnLength,
            IntPtr winHandle);

        public static int GetSoundLength(string fileName)
        {
            StringBuilder lengthBuf = new StringBuilder(32);

            mciSendString(string.Format("open \"{0}\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);
            mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);
            mciSendString("close wave", null, 0, IntPtr.Zero);

            int length = 0;
            int.TryParse(lengthBuf.ToString(), out length);

            return length;
        }
    }
}
18
Jan Zich

Загрузите файл NAudio.dll По ссылке http://naudio.codeplex.com/

а затем использовать эту функцию

public static TimeSpan GetWavFileDuration(string fileName)       
{     
    WaveFileReader wf = new WaveFileReader(fileName);
    return wf.TotalTime; 
}

вы получите продолжительность

29
Monti Pal

Не отнимать ничего от уже принятого ответа, но я смог получить длительность аудиофайла (несколько разных форматов, включая AC3, что мне было нужно в то время), используя пространство имен Microsoft.DirectX.AudioVideoPlayBack. Это часть DirectX 9.0 для управляемого кода . Добавление ссылки сделало мой код таким простым ...

Public Shared Function GetDuration(ByVal Path As String) As Integer
    If File.Exists(Path) Then
        Return CInt(New Audio(Path, False).Duration)
    Else
        Throw New FileNotFoundException("Audio File Not Found: " & Path)
    End If
End Function

И это тоже довольно быстро! Вот ссылка на класс Audio .

5
Josh Stodola
3
Cetra

Да, есть бесплатная библиотека, которую можно использовать для определения продолжительности аудио файла. Эта библиотека также предоставляет гораздо больше функциональных возможностей.

TagLib

TagLib распространяется на условиях GNU Малой общедоступной лицензии (LGPL) и Общественной лицензии Mozilla (MPL).

Я реализовал ниже код, который возвращает продолжительность времени в секундах.

using TagLib.Mpeg;

public static double GetSoundLength(string FilePath)
{
    AudioFile ObjAF = new AudioFile(FilePath);
    return ObjAF.Properties.Duration.TotalSeconds;
}
2
Manish Nayak

У меня были трудности с примером MediaPlayer-класса выше. Это может занять некоторое время, прежде чем игрок открыл файл. В «реальном мире» вы должны зарегистрироваться для MediaOpened-события, после того, как оно запущено, NaturalDuration действует ........ В консольном приложении вам просто нужно подождать несколько секунд после открытия.

using System;
using System.Text;
using System.Windows.Media;
using System.Windows;

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      if (args.Length == 0)
        return;
      Console.Write(args[0] + ": ");
      MediaPlayer player = new MediaPlayer();
      Uri path = new Uri(args[0]);
      player.Open(path);
      TimeSpan maxWaitTime = TimeSpan.FromSeconds(10);
      DateTime end = DateTime.Now + maxWaitTime;
      while (DateTime.Now < end)
      {
        System.Threading.Thread.Sleep(100);
        Duration duration = player.NaturalDuration;
        if (duration.HasTimeSpan)
        {
          Console.WriteLine(duration.TimeSpan.ToString());
          break;
        }
      }
      player.Close();
    }
  }
}
2
Lars

Попробуйте код ниже из Как определить длину WAV-файла в C #

    string path = @"c:\test.wav";
    WaveReader wr = new WaveReader(File.OpenRead(path));
    int durationInMS = wr.GetDurationInMS();
    wr.Close();
2
Aleks

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

MediaInfoDll Поставляется с примером кода C # о том, как заставить его работать.

1
sieben

Вы можете обнаружить, что библиотека XNA имеет некоторую поддержку для работы с WAV и т.д., Если вы хотите пойти по этому пути. Он предназначен для работы с C # для программирования игр, поэтому может позаботиться о том, что вам нужно.

1
xan

Есть немного учебника (с - по-видимому - рабочим кодом, который вы можете использовать) над CodeProject .

Единственное, с чем вам следует быть осторожным, это то, что файл WAV, состоящий из нескольких фрагментов, совершенно «нормален», поэтому вам нужно прокрутить весь файл, чтобы убедиться, что все фрагменты учтены.

1
moobaa

Что именно ваше приложение делает со сжатыми WAV? Сжатые WAV-файлы всегда сложны - в этом случае я всегда стараюсь использовать альтернативный формат контейнера, например, файлы OGG или WMA. Библиотеки XNA, как правило, предназначены для работы с конкретными форматами - хотя возможно, что в XACT вы найдете более общий метод воспроизведения wav. Возможная альтернатива - заглянуть в порт SDL C #, хотя я когда-либо использовал его только для воспроизведения несжатых WAV - после открытия вы можете запросить количество выборок, чтобы определить длину.

1
Bubba

я проверил блю код не получится, форматы файлов такие как \\ ip\dir\*. wav

 public static class SoundInfo
   {
     [DllImport("winmm.dll")]
     private static extern uint mciSendString
     (
        string command,
        StringBuilder returnValue,
        int returnLength,
        IntPtr winHandle
     );

     public static int GetSoundLength(string fileName)
      {
        StringBuilder lengthBuf = new StringBuilder(32);

        mciSendString(string.Format("open \"{0}\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);
        mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);
        mciSendString("close wave", null, 0, IntPtr.Zero);

        int length = 0;
        int.TryParse(lengthBuf.ToString(), out length);

        return length;
    }
}

пока наудио работает

    public static int GetSoundLength(string fileName)
     {
        using (WaveFileReader wf = new WaveFileReader(fileName))
        {
            return (int)wf.TotalTime.TotalMilliseconds;
        }
     }`
0
item.wu

Я предполагаю, что вы немного знакомы со структурой файла .WAV: он содержит структуру заголовка WAVEFORMATEX, за которой следует ряд других структур (или «блоков»), содержащих различную информацию. Смотрите Википедия для получения дополнительной информации о формате файла.

Во-первых, переберите файл .wav и добавьте незаполненные фрагменты «data» (блок «data» содержит аудиоданные для файла; обычно есть только один из них, но возможно, что больше одного). Теперь у вас есть общий размер аудиоданных в байтах.

Затем получите элемент «Среднее число байт в секунду» структуры заголовка файла WAVEFORMATEX.

Наконец, разделите общий размер аудиоданных на среднее число байтов в секунду - это даст вам продолжительность файла в секундах.

Это работает достаточно хорошо для несжатых и сжатых файлов.

0
GogglesPisano

время = FileLength/(частота дискретизации * каналы * биты на выборку/8)

0
Martin Abilev