web-dev-qa-db-fra.com

Comment puis-je déterminer la longueur (c'est-à-dire la durée) d'un fichier .wav en C #?

Dans la situation non compressée, je sais que je dois lire l'en-tête wav, extraire le nombre de canaux, de bits et de fréquence d'échantillonnage, puis le calculer à partir de cet emplacement: (canaux) * (bits) * (échantillons/s) * (secondes) = (taille du fichier)

Y at-il un moyen plus simple - une bibliothèque libre, ou quelque chose dans le cadre de .net peut-être?

Comment ferais-je cela si le fichier .wav est compressé (avec le codec mpeg par exemple)?

26
John Sibly

Vous pouvez envisager d'utiliser la fonction mciSendString (...) (la vérification des erreurs est omise pour plus de clarté):

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

Téléchargez NAudio.dll À partir du lien http://naudio.codeplex.com/

et ensuite utiliser cette fonction

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

vous obtiendrez la durée

29
Monti Pal

Je n'ai rien enlevé à la réponse déjà acceptée, mais j'ai pu obtenir la durée d'un fichier audio (plusieurs formats différents, y compris AC3, ce dont j'avais besoin à l'époque) en utilisant l'espace de noms Microsoft.DirectX.AudioVideoPlayBack. Cela fait partie de DirectX 9.0 for Managed Code . Ajouter une référence à cela a rendu mon code aussi simple que cela ...

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

Et c'est assez rapide aussi! Voici une référence pour la classe Audio .

5
Josh Stodola
3
Cetra

Oui, une bibliothèque gratuite peut être utilisée pour obtenir la durée du fichier audio. Cette bibliothèque fournit également beaucoup plus de fonctionnalités.

TagLib

TagLib est distribué sous les licences GNU Lesser General Public License (LGPL) et Mozilla Public License (MPL).

J'ai implémenté le code ci-dessous qui renvoie la durée en secondes.

using TagLib.Mpeg;

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

J'ai eu des difficultés avec l'exemple de la classe MediaPlayer ci-dessus. Cela pourrait prendre un certain temps avant que le lecteur ait ouvert le fichier. Dans le "monde réel", vous devez vous inscrire à l'événement MediaOpened. Après son déclenchement, NaturalDuration est valide. Dans une application console, il vous suffit d'attendre quelques secondes après l'ouverture.

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

Essayez le code ci-dessous à partir de Comment déterminer la longueur d’un fichier .wav en C #

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

Je vais devoir dire MediaInfo , je l'utilise depuis plus d'un an avec une application de codage audio/vidéo sur laquelle je travaille. Il donne toutes les informations pour les fichiers wav avec presque tous les autres formats.

MediaInfoDll Fourni avec un exemple de code C # sur la façon de le faire fonctionner.

1
sieben

Vous constaterez peut-être que la bibliothèque XNA prend en charge l'utilisation de WAV, etc. si vous êtes prêt à suivre cette voie. Il est conçu pour fonctionner avec C # pour la programmation de jeux. Vous pouvez donc vous occuper de ce dont vous avez besoin.

1
xan

Il existe un peu de didacticiel (avec - vraisemblablement - un code fonctionnel que vous pouvez exploiter) sur CodeProject .

La seule chose à laquelle vous devez faire attention, c'est qu'il est parfaitement "normal" qu'un fichier WAV soit composé de plusieurs morceaux. Vous devez donc parcourir l'ensemble du fichier pour vous assurer que tous les morceaux sont comptabilisés.

1
moobaa

Que fait exactement votre application avec les WAV compressés? Les fichiers WAV compressés sont toujours délicats. J'essaie toujours d'utiliser un format de conteneur alternatif dans ce cas, tel que les fichiers OGG ou WMA. Les bibliothèques XNA ont tendance à être conçues pour fonctionner avec des formats spécifiques - bien qu'il soit possible que XACT contienne une méthode de lecture wav plus générique. Une alternative possible consiste à examiner le port SDL C #, même si je ne l'ai utilisé que pour lire des fichiers WAV non compressés - une fois ouvert, vous pouvez interroger le nombre d'échantillons pour déterminer la longueur.

1
Bubba

j'ai testé le code bluffé échouerait, les formats de fichier sont comme "\\ 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;
    }
}

pendant que naudio fonctionne

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

Je suppose que vous connaissez un peu la structure d'un fichier .WAV: il contient une structure d'en-tête WAVEFORMATEX, suivie de plusieurs autres structures (ou "morceaux") contenant divers types d'informations. Voir Wikipedia pour plus d’informations sur le format de fichier.

Tout d’abord, parcourez le fichier .wav et additionnez les longueurs non complétées des morceaux de "données" (le morceau "data" contient les données audio du fichier; habituellement, il n’en existe qu’un seul, mais il est possible qu’il existe plus d'un). Vous avez maintenant la taille totale, en octets, des données audio.

Ensuite, obtenez le membre "octets moyens par seconde" de la structure d'en-tête WAVEFORMATEX du fichier.

Enfin, divisez la taille totale des données audio par le nombre moyen d'octets par seconde. Cela vous donnera la durée du fichier, en secondes.

Cela fonctionne assez bien pour les fichiers non compressés et compressés.

0
GogglesPisano

time = FileLength/(fréquence d'échantillonnage * canaux * bits par échantillon/8)

0
Martin Abilev