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

27
задан John Sibly 22 October 2018 в 12:40
поделиться

10 ответов

Можно рассмотреть использование 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;
        }
    }
}
20
ответ дан John Sibly 28 November 2019 в 04:38
поделиться

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

Первый, выполните итерации через .wav файл и сложите незаполненные длины блоков "данных" (блок "данных" содержит аудиоданные для файла; обычно существует только один из них, но возможно, что мог быть больше чем один). У Вас теперь есть общий размер, в байтах, аудиоданных.

Затем, получают "средние байты в секунду" член структуры заголовка WAVEFORMATEX файла.

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

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

0
ответ дан 28 November 2019 в 04:38
поделиться

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

MediaInfoDll Идет с демонстрационным кодом C# того, как получить его работа.

1
ответ дан sieben 28 November 2019 в 04:38
поделиться

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

единственная вещь, которой необходимо немного остерегаться, состоит в том, что "совершенно нормально" для файла WAV состоять из нескольких блоков - таким образом, необходимо подвинуться весь файл, чтобы гарантировать, что все блоки составляются.

1
ответ дан moobaa 28 November 2019 в 04:38
поделиться

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

1
ответ дан 28 November 2019 в 04:38
поделиться

Я испытал трудности с примером 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();
    }
  }
}
4
ответ дан Lars 28 November 2019 в 04:38
поделиться
3
ответ дан Cetra 28 November 2019 в 04:38
поделиться

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

1
ответ дан xan 28 November 2019 в 04:38
поделиться

Ничего не убирать с ответа, уже принятого, но я смог получить продолжительность звукового файла (несколько различных форматов, в том числе 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
ответ дан 28 November 2019 в 04:38
поделиться

Скачайте "PresentationCore.dll" и "WindowsBase.dll" из:

http://www.search-dll.com/dll-files/download/windowsbase.dll.html

Вставьте файлы в папку bin вашего приложения для справки. Теперь все должно работать.

-8
ответ дан 28 November 2019 в 04:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: