windows 读取整个mp3文件 显示到带时间轴的波形显示控件代码
时间: 2024-05-01 21:23:47 浏览: 13
以下是一个使用NAudio库来读取MP3文件并在WinForms应用程序中显示波形的示例代码:
```
using NAudio.Wave;
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WaveformViewer
{
public partial class Form1 : Form
{
private WaveFileReader waveFileReader;
private WaveOut waveOut;
private Bitmap bitmap;
private Graphics graphics;
private int bytesPerSample = 2;
private int samplesPerPixel = 128;
private Pen pen = new Pen(Color.Green, 1);
public Form1()
{
InitializeComponent();
}
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "MP3 Files (*.mp3)|*.mp3";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
waveFileReader = new WaveFileReader(openFileDialog.FileName);
waveOut = new WaveOut();
waveOut.Init(waveFileReader);
trackBar.Maximum = (int)waveFileReader.TotalTime.TotalSeconds;
bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
graphics = Graphics.FromImage(bitmap);
}
}
private void playToolStripMenuItem_Click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Play();
timer.Start();
}
}
private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Pause();
timer.Stop();
}
}
private void stopToolStripMenuItem_Click(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Stop();
timer.Stop();
waveFileReader.Position = 0;
}
}
private void timer_Tick(object sender, EventArgs e)
{
TimeSpan currentTime = waveOut.GetPositionTimeSpan();
labelCurrentTime.Text = currentTime.ToString(@"mm\:ss");
trackBar.Value = (int)currentTime.TotalSeconds;
int bytesToRead = (int)(waveFileReader.WaveFormat.SampleRate * bytesPerSample * samplesPerPixel);
byte[] waveData = new byte[bytesToRead];
int bytesRead = waveFileReader.Read(waveData, 0, bytesToRead);
if (bytesRead > 0)
{
DrawWaveform(waveData, bytesRead);
pictureBox.Image = bitmap;
}
}
private void DrawWaveform(byte[] waveData, int bytesRead)
{
int samples = bytesRead / bytesPerSample;
int bytesPerPixel = bytesPerSample * samplesPerPixel;
int pixels = bytesRead / bytesPerPixel;
for (int i = 0; i < pixels; i++)
{
float max = 0;
float min = 0;
for (int j = 0; j < samplesPerPixel; j++)
{
float sample = 0;
if (bytesPerSample == 2)
{
sample = BitConverter.ToInt16(waveData, i * bytesPerPixel + j * bytesPerSample) / 32768f;
}
else if (bytesPerSample == 4)
{
sample = BitConverter.ToInt32(waveData, i * bytesPerPixel + j * bytesPerSample) / 2147483648f;
}
if (sample > max)
{
max = sample;
}
else if (sample < min)
{
min = sample;
}
}
int x = i * samplesPerPixel;
int y = (int)((1f - max) * pictureBox.Height / 2);
int height = (int)((max - min) * pictureBox.Height / 2);
graphics.DrawLine(pen, x, y, x, y + height);
}
}
private void trackBar_ValueChanged(object sender, EventArgs e)
{
if (waveOut != null)
{
waveOut.Pause();
waveFileReader.Position = trackBar.Value * waveFileReader.WaveFormat.SampleRate * bytesPerSample;
waveOut.Play();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (waveOut != null)
{
waveOut.Dispose();
}
if (waveFileReader != null)
{
waveFileReader.Dispose();
}
if (graphics != null)
{
graphics.Dispose();
}
if (bitmap != null)
{
bitmap.Dispose();
}
}
}
}
```
这个应用程序包含一个菜单,用于打开、播放、暂停和停止MP3文件。它还包含一个带有时间轴的 `TrackBar` 控件,可以用来跳转到文件中的特定位置。当播放时,应用程序会定期从文件中读取一些数据,并将其显示为波形。`samplesPerPixel` 变量控制每个像素所表示的音频样本数,它越大,波形就越平滑。请注意,该示例代码仅适用于16位或32位PCM编码的音频文件,如果您要处理其他编码的文件,需要相应地修改代码。