it-swarm-vi.com

Làm cách nào tôi có thể xác định độ dài (tức là thời lượng) của tệp .wav trong C #?

Trong tình huống không nén tôi biết tôi cần đọc tiêu đề wav, rút ​​số kênh, bit và tốc độ mẫu và xử lý nó từ đó: (kênh) * (bit) * (mẫu/s) * (giây) = (kích thước tập tin)

Có một cách đơn giản hơn - một thư viện miễn phí, hoặc một cái gì đó trong khung .net có lẽ?

Tôi sẽ làm điều này như thế nào nếu tệp .wav được nén (ví dụ với codec mpeg)?

26
John Sibly

Bạn có thể xem xét sử dụng hàm mciSendString (...) (kiểm tra lỗi được bỏ qua cho rõ ràng):

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ải xuống NAudio.dll [.__.] Từ liên kết [.__.] http://naudio.codeplex.com/ /

và sau đó sử dụng chức năng này

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

bạn sẽ nhận được Thời lượng

29
Monti Pal

Không lấy bất cứ điều gì từ câu trả lời đã được chấp nhận, nhưng tôi có thể nhận được thời lượng của tệp âm thanh (một số định dạng khác nhau, bao gồm AC3, đó là những gì tôi cần tại thời điểm đó) bằng cách sử dụng không gian tên Microsoft.DirectX.AudioVideoPlayBack. Đây là một phần của DirectX 9.0 cho Mã được quản lý . Thêm một tham chiếu đến đó làm cho mã của tôi đơn giản như thế này ...

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

Và nó cũng khá nhanh! Đây là một tài liệu tham khảo cho Audio class.

5
Josh Stodola
3
Cetra

Có, có một thư viện miễn phí có thể được sử dụng để lấy thời lượng của tệp Âm thanh. Thư viện này cũng cung cấp nhiều chức năng hơn.

TagLib

TagLib được phân phối theo GNU Giấy phép công cộng chung nhỏ hơn (LGPL) và Giấy phép công cộng Mozilla (MPL).

Tôi đã triển khai mã bên dưới trả về thời gian tính bằng giây.

using TagLib.Mpeg;

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

Tôi gặp khó khăn với ví dụ về lớp MediaPlayer ở trên. Có thể mất một thời gian, trước khi người chơi đã mở tệp. Trong "thế giới thực", bạn phải đăng ký sự kiện MediaOpened, sau khi phát hành, NaturalDuration là hợp lệ. [.__.

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

Hãy thử mã dưới đây từ Cách xác định độ dài của tệp .wav trong C #

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

Tôi sẽ phải nói MediaInfo , tôi đã sử dụng nó được hơn một năm với ứng dụng mã hóa âm thanh/video mà tôi đang làm việc. Nó cung cấp tất cả thông tin cho các tập tin wav cùng với hầu hết các định dạng khác.

MediaInfoDll Đi kèm với mã C # mẫu về cách làm cho nó hoạt động.

1
sieben

Bạn có thể thấy rằng thư viện XNA có một số hỗ trợ để làm việc với WAV, v.v. nếu bạn sẵn sàng đi theo tuyến đường đó. Nó được thiết kế để hoạt động với C # để lập trình trò chơi, vì vậy có thể chỉ cần quan tâm đến những gì bạn cần.

1
xan

Có một chút hướng dẫn (với - có lẽ - mã làm việc mà bạn có thể tận dụng) tại CodeProject .

Điều duy nhất bạn phải cẩn thận một chút là nó hoàn toàn "bình thường" khi một tệp WAV được tạo thành từ nhiều khối - vì vậy bạn phải lướt qua toàn bộ tệp để đảm bảo rằng tất cả các khối được tính.

1
moobaa

Chính xác thì ứng dụng của bạn đang làm gì với WAV nén? Các tệp WAV được nén luôn luôn phức tạp - Tôi luôn thử và sử dụng một định dạng chứa thay thế trong trường hợp này, chẳng hạn như các tệp OGG hoặc WMA. Các thư viện XNA có xu hướng được thiết kế để hoạt động với các định dạng cụ thể - mặc dù có thể trong XACT bạn sẽ tìm thấy một phương thức phát lại wav chung chung hơn. Một cách khác có thể là xem xét cổng SDL C #, mặc dù tôi chỉ từng sử dụng nó để phát WAV không nén - một khi đã mở, bạn có thể truy vấn số lượng mẫu để xác định độ dài.

1
Bubba

tôi đã thử mã thổi sẽ thất bại, các định dạng tệp giống như "\\ 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;
    }
}

trong khi naudio hoạt động

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

Tôi sẽ giả định rằng bạn đã quen thuộc với cấu trúc của tệp .WAV: nó chứa cấu trúc tiêu đề WAVEFORMATEX, theo sau là một số cấu trúc khác (hoặc "khối") chứa nhiều loại thông tin khác nhau. Xem Wikipedia để biết thêm thông tin về định dạng tệp.

Đầu tiên, lặp qua tệp .wav và thêm độ dài không được đệm của các đoạn "dữ liệu" (đoạn "dữ liệu" chứa dữ liệu âm thanh cho tệp; thường chỉ có một trong số đó, nhưng có thể có nhiều hơn một). Bây giờ bạn có tổng kích thước, tính bằng byte, của dữ liệu âm thanh.

Tiếp theo, lấy thành viên "byte trung bình mỗi giây" của cấu trúc tiêu đề WAVEFORMATEX của tệp.

Cuối cùng, chia tổng kích thước của dữ liệu âm thanh cho các byte trung bình mỗi giây - điều này sẽ cung cấp cho bạn thời lượng của tệp, tính bằng giây.

Điều này hoạt động hợp lý tốt cho các tập tin không nén và nén.

0
GogglesPisano

time = FileLpm/(Tốc độ mẫu * Kênh * Bits trên mỗi mẫu/8)

0
Martin Abilev