it-swarm-eu.dev

Wie kann ich die Länge (d. H. Die Dauer) einer WAV-Datei in C # bestimmen?

In der unkomprimierten Situation, die ich kenne, muss ich den WAV-Header lesen, die Anzahl der Kanäle, Bits und die Abtastrate herausziehen und von dort aus berechnen: (Kanäle) * (Bits) * (Samples/s) * (Sekunden) = (Dateigröße)

Gibt es einen einfacheren Weg - eine kostenlose Bibliothek oder etwas im .net-Framework?

Wie mache ich das, wenn die WAV-Datei komprimiert ist (zum Beispiel mit dem MPEG-Codec)?

26
John Sibly

Sie können die Verwendung der Funktion mciSendString (...) in Betracht ziehen (die Fehlerprüfung ist der Übersichtlichkeit halber weggelassen):

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

Laden Sie NAudio.dll Über den Link http://naudio.codeplex.com/ herunter.

und dann diese Funktion verwenden

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

sie erhalten die Dauer

29
Monti Pal

Um der bereits akzeptierten Antwort nichts zu entziehen, konnte ich die Dauer einer Audiodatei (mehrere verschiedene Formate, einschließlich AC3, was ich damals brauchte) mit dem Microsoft.DirectX.AudioVideoPlayBack-Namespace abrufen. Dies ist ein Teil von DirectX 9.0 für verwalteten Code . Das Hinzufügen eines Verweises machte meinen Code so einfach wie folgt ...

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

Und es geht auch ziemlich schnell! Hier ist eine Referenz für die Audio Klasse.

5
Josh Stodola
3
Cetra

Ja, es gibt eine kostenlose Bibliothek, die verwendet werden kann, um die Dauer der Audiodatei abzurufen. Diese Bibliothek bietet auch viele weitere Funktionen.

TagLib

TagLib wird unter der GNU Lesser General Public License (LGPL) und Mozilla Public License (MPL) vertrieben.

Ich habe den folgenden Code implementiert, der die Zeitdauer in Sekunden angibt.

using TagLib.Mpeg;

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

Ich hatte Schwierigkeiten mit dem obigen Beispiel der MediaPlayer-Klasse. Es kann einige Zeit dauern, bis der Player die Datei geöffnet hat. In der "realen Welt" müssen Sie sich für das MediaOpened-Event registrieren, nachdem die NaturalDuration ausgelöst wurde. In einer Konsolen-App müssen Sie nur wenige Sekunden nach dem Öffnen warten.

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

Versuchen Sie den folgenden Code aus So bestimmen Sie die Länge einer .wav-Datei in C #

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

Ich muss sagen MediaInfo , ich verwende es seit über einem Jahr mit einer Audio-/Video-Codierungsanwendung, an der ich gerade arbeite. Es enthält alle Informationen zu wav-Dateien sowie fast alle anderen Formate.

MediaInfoDll Kommt mit Beispiel-C # -Code, wie es funktioniert.

1
sieben

Möglicherweise stellen Sie fest, dass die XNA-Bibliothek etwas Unterstützung für die Arbeit mit WAVs usw. bietet, wenn Sie diesen Weg einschlagen möchten. Es wurde entwickelt, um mit C # für die Spielprogrammierung zusammenzuarbeiten. Vielleicht müssen Sie sich nur darum kümmern, was Sie brauchen.

1
xan

Unter CodeProject gibt es ein kleines Tutorial (mit - vermutlich mit funktionierendem Code, den Sie nutzen können).

Das einzige, worauf Sie ein wenig aufpassen müssen, ist, dass es vollkommen "normal" ist, wenn eine WAV-Datei aus mehreren Chunks besteht. Sie müssen also die gesamte Datei überblättern, um sicherzustellen, dass alle Chunks berücksichtigt werden.

1
moobaa

Was genau macht Ihre Anwendung mit komprimierten WAVs? Komprimierte WAV-Dateien sind immer schwierig. In diesem Fall versuche ich immer, ein alternatives Containerformat wie OGG- oder WMA-Dateien zu verwenden. Die XNA-Bibliotheken sind in der Regel für die Verwendung mit bestimmten Formaten konzipiert. In XACT finden Sie jedoch möglicherweise eine allgemeinere Wav-Wiedergabemethode. Eine mögliche Alternative ist der Blick in den SDL-C # -Port, obwohl ich ihn bisher immer nur zum Abspielen von unkomprimierten WAVs verwendet habe. Nach dem Öffnen können Sie die Anzahl der Samples abfragen, um die Länge zu bestimmen.

1
Bubba

ich habe getestet, dass der Code fehlschlägt, Dateiformate sind wie "\\ 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;
    }
}

während naudio funktioniert

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

Ich gehe davon aus, dass Sie mit der Struktur einer .WAV-Datei vertraut sind: Sie enthält eine WAVEFORMATEX-Kopfstruktur, gefolgt von einer Reihe anderer Strukturen (oder "Chunks"), die verschiedene Informationen enthalten. Siehe Wikipedia für weitere Informationen zum Dateiformat.

Zuerst durchlaufen Sie die .wav-Datei und addieren Sie die nicht aufgefüllten Längen der "data" -Stückchen (der "data" -Stück enthält die Audiodaten für die Datei; normalerweise gibt es nur eine davon, aber es ist möglich, dass dies möglich ist mehr als eine). Sie haben jetzt die Gesamtgröße der Audiodaten in Byte.

Rufen Sie als Nächstes den Member "Average Bytes Per Second" der WAVEFORMATEX-Headerstruktur der Datei ab.

Teilen Sie schließlich die Gesamtgröße der Audiodaten durch die durchschnittlichen Bytes pro Sekunde - dies gibt Ihnen die Dauer der Datei in Sekunden.

Dies funktioniert relativ gut für unkomprimierte und komprimierte Dateien.

0
GogglesPisano

time = FileLength/(Sample Rate * Channels * Bits pro Sample/8)

0
Martin Abilev