Frage

In der unkomprimierten Situation, die ich weiß, ich brauche die wav-Header zu lesen, ziehen Sie die Anzahl der Kanäle, Bits und Sample-Rate und arbeiten von dort aus: (Kanäle) * (Bits) * (Proben / s) * (Sekunden) = (Dateigröße)

Gibt es einen einfacheren Weg - eine freie Bibliothek, oder etwas in der .net Framework vielleicht

Wie würde ich dies tun, wenn die WAV-Datei (mit dem MPEG-Codec zum Beispiel) komprimiert wird?

War es hilfreich?

Lösung

Sie können prüfen, das mciSendString (...) Funktion (Fehlerprüfung wird 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;
        }
    }
}

Andere Tipps

Download NAudio.dll von der Verbindung http://naudio.codeplex.com/

und dann diese Funktion nutzen

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

Sie erhalten die Dauer erhalten

Nicht alles zu nehmen von der Antwort entfernt bereits akzeptiert, aber ich war in der Lage, die Dauer einer Audiodatei (verschiedene Formate, darunter AC3, das ist, was ich zu der Zeit erforderlich) erhält die Microsoft.DirectX.AudioVideoPlayBack Namespace. Dies ist Teil der DirectX 9.0 für Managed-Code . Hinzufügen eines Verweises auf das machte meinen Code so einfach wie diese ...

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 ist ziemlich schnell, auch! Hier ist eine Referenz für die Audio Klasse.

Ich hatte Schwierigkeiten mit dem Beispiel der Mediaplayer-Klasse oben. Es könnte einige Zeit dauern, bevor der Spieler die Datei geöffnet hat. In der „realen Welt“ müssen Sie für das MediaOpened-Ereignis registrieren, danach gefeuert hat, die NaturalDuration gültig ist. In einem Konsole-App müssen Sie nur ein paar Sekunden nach dem offenen 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();
    }
  }
}

Versuchen Code unten von Wie die Länge einer .wav-Datei in C # bestimmen

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

Ja, es gibt eine freie Bibliothek, die verwendet werden kann, Zeitdauer der Audio-Datei zu erhalten. Diese Bibliothek auch viele weitere Funktionen zur Verfügung stellt.

TagLib

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

I unten Code implementiert, die Zeitdauer in Sekunden zurück.

using TagLib.Mpeg;

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

Sie können feststellen, dass die XNA-Bibliothek eine gewisse Unterstützung hat für mit WAV des usw. zu arbeiten, wenn Sie bereit sind, diesen Weg zu gehen. Es ist so konzipiert, mit C # für Spiele-Programmierung arbeiten, so könnte nur kümmern, was Sie brauchen.

Es ist ein bisschen wie ein Tutorial (mit - vermutlich - Arbeits Code, den Sie nutzen können) über Codeproject .

Das einzige, was Sie ein wenig vorsichtig sein, ist, dass es vollkommen „normal“ für eine WAV-Datei aus mehreren Stücken zusammengesetzt werden - so dass Sie über die gesamte Datei Scoot müssen sicherstellen, dass alle Stücke berücksichtigt werden.

Was genau ist Ihre Anwendung mit Druck WAVs tun? Komprimierten WAV-Dateien sind immer schwierig - ich versuche immer, und ein alternatives Container-Format in diesem Fall wie OGG oder WMA-Dateien zu verwenden. Die XNA Bibliotheken sind in der Regel entwickelt, um mit bestimmten Formaten arbeiten - obwohl es möglich ist, dass innerhalb von XACT Sie eine allgemeinere WAV-Wiedergabe-Methode zu finden. Eine mögliche Alternative ist in der SDL C # Port zu sehen, obwohl ich nur jemals verwendet habe unkomprimierten WAVs zu spielen -. Einmal geöffnet Sie die Anzahl der Proben abfragen können die Länge bestimmen

Ich werde sagen Mediainfo , ich habe seit über einem Jahr benutze es mit ein Audio / Video-Encoding-Anwendung, die ich arbeite. Es gibt alle Informationen für WAV-Dateien zusammen mit fast jedem anderen Format.

MediaInfoDll Kommt mit Probe C # -Code, wie man es bekommen Arbeits.

Ich gehe davon aus, dass Sie mit der Struktur einer .wav-Datei ein wenig vertraut sind: es enthält eine WAVEFORMATEX Header-Struktur, die von einer Reihe von anderen Strukturen gefolgt (oder „Chunks“) verschiedene Arten von Informationen enthalten. Siehe Wikipedia für weitere Informationen über das Dateiformat.

Zuerst durchlaufen die .wav-Datei und addieren Sie die die unpadded Längen der „Daten“ Chunks (die „Daten“ chunk enthält die Audiodaten für die Datei, in der Regel nur eine davon ist, aber es ist möglich, dass es könnte mehr als eine) sein. Sie haben nun die Gesamtgröße in Byte, der Audiodaten.

Als nächstes erhält das „durchschnittliche Bytes pro Sekunde“ Mitglied der WAVEFORMATEX Header Struktur der Datei.

Schließlich teilen Sie die Gesamtgröße der Audiodaten durch den durchschnittlichen Bytes pro Sekunde -. Das Ihnen die Dauer der Datei geben, in Sekunden

Das funktioniert recht gut für unkomprimierte und komprimierte Dateien.

Zeit = FileLength / (Sample Rate * Kanäle * Bits pro Probe / 8)

Ich habe blies getesteten Code fehlschlagen würde, 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 Werke

    public static int GetSoundLength(string fileName)
     {
        using (WaveFileReader wf = new WaveFileReader(fileName))
        {
            return (int)wf.TotalTime.TotalMilliseconds;
        }
     }`
Imports System.IO
Imports System.Text

Imports System.Math
Imports System.BitConverter

Public Class PulseCodeModulation
    ' Pulse Code Modulation WAV (RIFF) file layout

    ' Header chunk

    ' Type   Byte Offset  Description
    ' Dword       0       Always ASCII "RIFF"
    ' Dword       4       Number of bytes in the file after this value (= File Size - 8)
    ' Dword       8       Always ASCII "WAVE"

    ' Format Chunk

    ' Type   Byte Offset  Description
    ' Dword       12      Always ASCII "fmt "
    ' Dword       16      Number of bytes in this chunk after this value
    ' Word        20      Data format PCM = 1 (i.e. Linear quantization)
    ' Word        22      Channels Mono = 1, Stereo = 2
    ' Dword       24      Sample Rate per second e.g. 8000, 44100
    ' Dword       28      Byte Rate per second (= Sample Rate * Channels * (Bits Per Sample / 8))
    ' Word        32      Block Align (= Channels * (Bits Per Sample / 8))
    ' Word        34      Bits Per Sample e.g. 8, 16

    ' Data Chunk

    ' Type   Byte Offset  Description
    ' Dword       36      Always ASCII "data"
    ' Dword       40      The number of bytes of sound data (Samples * Channels * (Bits Per Sample / 8))
    ' Buffer      44      The sound data

    Dim HeaderData(43) As Byte

    Private AudioFileReference As String

    Public Sub New(ByVal AudioFileReference As String)
        Try
            Me.HeaderData = Read(AudioFileReference, 0, Me.HeaderData.Length)
        Catch Exception As Exception
            Throw
        End Try

        'Validate file format

        Dim Encoder As New UTF8Encoding()

        If "RIFF" <> Encoder.GetString(BlockCopy(Me.HeaderData, 0, 4)) Or _
            "WAVE" <> Encoder.GetString(BlockCopy(Me.HeaderData, 8, 4)) Or _
            "fmt " <> Encoder.GetString(BlockCopy(Me.HeaderData, 12, 4)) Or _
            "data" <> Encoder.GetString(BlockCopy(Me.HeaderData, 36, 4)) Or _
            16 <> ToUInt32(BlockCopy(Me.HeaderData, 16, 4), 0) Or _
            1 <> ToUInt16(BlockCopy(Me.HeaderData, 20, 2), 0) _
        Then
            Throw New InvalidDataException("Invalid PCM WAV file")
        End If

        Me.AudioFileReference = AudioFileReference
    End Sub

    ReadOnly Property Channels() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 22, 2), 0) 'mono = 1, stereo = 2
        End Get
    End Property

    ReadOnly Property SampleRate() As Integer
        Get
            Return ToUInt32(BlockCopy(Me.HeaderData, 24, 4), 0) 'per second
        End Get
    End Property

    ReadOnly Property ByteRate() As Integer
        Get
            Return ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0) 'sample rate * channels * (bits per channel / 8)
        End Get
    End Property

    ReadOnly Property BlockAlign() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 32, 2), 0) 'channels * (bits per sample / 8)
        End Get
    End Property

    ReadOnly Property BitsPerSample() As Integer
        Get
            Return ToUInt16(BlockCopy(Me.HeaderData, 34, 2), 0)
        End Get
    End Property

    ReadOnly Property Duration() As Integer
        Get
            Dim Size As Double = ToUInt32(BlockCopy(Me.HeaderData, 40, 4), 0)
            Dim ByteRate As Double = ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0)
            Return Ceiling(Size / ByteRate)
        End Get
    End Property

    Public Sub Play()
        Try
            My.Computer.Audio.Play(Me.AudioFileReference, AudioPlayMode.Background)
        Catch Exception As Exception
            Throw
        End Try
    End Sub

    Public Sub Play(playMode As AudioPlayMode)
        Try
            My.Computer.Audio.Play(Me.AudioFileReference, playMode)
        Catch Exception As Exception
            Throw
        End Try
    End Sub

    Private Function Read(AudioFileReference As String, ByVal Offset As Long, ByVal Bytes As Long) As Byte()
        Dim inputFile As System.IO.FileStream

        Try
            inputFile = IO.File.Open(AudioFileReference, IO.FileMode.Open)
        Catch Exception As FileNotFoundException
            Throw New FileNotFoundException("PCM WAV file not found")
        Catch Exception As Exception
            Throw
        End Try

        Dim BytesRead As Long
        Dim Buffer(Bytes - 1) As Byte

        Try
            BytesRead = inputFile.Read(Buffer, Offset, Bytes)
        Catch Exception As Exception
            Throw
        Finally
            Try
                inputFile.Close()
            Catch Exception As Exception
                'Eat the second exception so as to not mask the previous exception
            End Try
        End Try

        If BytesRead < Bytes Then
            Throw New InvalidDataException("PCM WAV file read failed")
        End If

        Return Buffer
    End Function

    Private Function BlockCopy(ByRef Source As Byte(), ByVal Offset As Long, ByVal Bytes As Long) As Byte()
        Dim Destination(Bytes - 1) As Byte

        Try
            Buffer.BlockCopy(Source, Offset, Destination, 0, Bytes)
        Catch Exception As Exception
            Throw
        End Try

        Return Destination
    End Function
End Class

Download "PresentationCore.dll" und "WindowsBase.dll" aus:

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

Fügen Sie die Dateien in Ihrer Anwendung Binärordner Referenz. Es soll jetzt funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top