如何创建在C#中\NAudio音乐播放器搜索栏? [英] How do I create a seekbar in C#\NAudio Music Player?

查看:395
本文介绍了如何创建在C#中\NAudio音乐播放器搜索栏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的两个n音讯和C#和我设法创建一个简单的MP3播放器,你可以选择一个文件并进行播放。它也有一个播放/暂停按钮。



我现在想添加一个搜索栏,但对如何做到这一点毫无头绪。也有可能在波形风格搜索栏?



openButton单击处理程序

 私人无效openButton_Click(对象发件人,EventArgs五)
{
打开文件对话框打开=新的OpenFileDialog();
open.Filter =音响文件| * .MP3;;

如果(open.ShowDialog()= DialogResult.OK!)
的回报;

CloseWaveOut(); //部署的waveOutDevice和audiofilereader
waveOutDevice =新waveout的();
audioFileReader =新AudioFileReader(open.FileName);

waveOutDevice.Init(audioFileReader);
waveOutDevice.Play();

pauseButton.Enabled = TRUE;
}


从单纯的用户界面 -

解决方案

除了基于担忧,有三个基本的​​东西,你需要能够做到:




  1. 阅读歌曲长度


  2. 获取播放位置。


  3. 设置播放位置。




宋长和当前播放位置是很简单 - 他们是通过 TOTALTIME 和<$ C $可用C>在的WaveStream 对象,这意味着你的 audioFileReader 对象CURRENTTIME 属性支持他们太多。一旦建成, audioFileReader.TotalTime 会给你的文件的总长度,和<$ C一时间跨度对象$ C> audioFileReader.CurrentTime 会给你当前播放位置。



您也可以的设置的播放位置通过分配到 audioFileReader.CurrentTime ...但这样做是一个棘手的过程,除非你知道自己在做什么。下面的代码跳到2.5秒作品有时和崩溃的可怕别人:

  audioFileReader.CurrentTime = audioFileReader.CurrentTime.Add(TimeSpan.FromSeconds(2.5)); 



这里的问题是,所得的的(以字节为单位)位置可能不正确对齐到样品的开始,有几个原因(包括在后台完成浮点运算)。这可将输出迅速转向垃圾。



更好的选择是使用位置流时的属性要更改播放位置。 位置是以字节为单位的当前播放位置,因此是一点点困难去努力。不太多,但:

  audioFileReader.Position + = audioFileReader.WaveFor​​mat.AverageBytesPerSecond; 

如果你正在加紧前进或后退的整数秒,这很好。如果没有,你需要确保你总是在定位的样本边界,使用 WaveFor​​mat.BlockAlign 属性来找出其中的界限。

  //计算新的位置
长newPos = audioFileReader.Position +(长)(audioFileReader.WaveFor​​mat.AverageBytesPerSecond * 2.5);
//强制其对齐到块边界
如果
newPos - = newPos%audioFileReader.WaveFor​​mat.BlockAlign((newPos%audioFileReader.WaveFor​​mat.BlockAlign)!= 0);
//强制新的位置进入有效范围内
newPos = Math.Max​​(0,Math.Min(audioFileReader.Length,newPos));
//设置位置
audioFileReader.Position = newPos;



简单的事情,在这里做的是定义一组扩展到的WaveStream的类,将寻道操作期间处理块对齐。基本对齐到块的操作可以通过才算无论从任何你把在新位置的变化被调用,所以是这样的:

 公共静态类WaveStreamExtensions 
{
//设置的WaveStream的位置最接近的块来提供的位置
公共静态无效SETPOSITION(此的WaveStream STRM,多头头寸)
{
//从块边界的距离(可能是0)
长ADJ =位置%strm.WaveFor​​mat.BlockAlign;
//调整位置,边界和钳位到有效范围
长newPos = Math.Max​​(0,Math.Min(strm.Length,位置 - ADJ));
//设置播放位置
strm.Position = newPos;
}

//按秒
公共静态无效SETPOSITION(此的WaveStream STRM,双秒)
{
strm.SetPosition设置的WaveStream的播放位置((长)(秒* strm.WaveFor​​mat.AverageBytesPerSecond));
}

//通过时间设定的WaveStream的播放位置(时间跨度)
公共静态无效SETPOSITION(此的WaveStream STRM,时间跨度时间)
{
strm.SetPosition(time.TotalSeconds);
}

//设置的WaveStream相对的播放位置当前位置
公共静态无效SEEK(此的WaveStream STRM,双胶纸)
{
STRM .SetPosition(strm.Position +(长)(偏移* strm.WaveFor​​mat.AverageBytesPerSecond));
}
}

通过在地方,你可以叫 audioFileReader.SetPosition(10.0)跳转到播放位置 00:00:10.0 ,电话 audioFileReader.Seek (-5)跳回5秒,等等,而不必担心通过抽样寻求到一个点半路上。



所以.. 。一些按钮添加到您的形式和设置它们调用寻找法+/-值走动。然后添加某种可以用来显示和设置播放位置的滑块。扔在一个定时器来更新滑块的位置,以当前的播放位置,你即将完成。


I am new to both NAudio and C# and I managed to create a simple MP3 player where you can choose a file and play it. It also has a play/pause button.

I would now like to add a seek bar but have no clue on how to do this. Also is it possible to have seekbar in waveform style?

The openButton click Handler

private void openButton_Click(object sender, EventArgs e)
{
    OpenFileDialog open = new OpenFileDialog();
    open.Filter = "Audio File|*.mp3;";

    if (open.ShowDialog() != DialogResult.OK) 
        return;

    CloseWaveOut();  // disposes the waveOutDevice and audiofilereader
    waveOutDevice = new WaveOut();
    audioFileReader = new AudioFileReader(open.FileName);

    waveOutDevice.Init(audioFileReader);
    waveOutDevice.Play();

    pauseButton.Enabled = true;            
}

解决方案

Apart from the purely UI-based concerns, there are three basic things you need to be able to do:

  1. Read song length.

  2. Get playback position.

  3. Set playback position.

Song length and current playback position are simple enough - they are available via the TotalTime and CurrentTime properties of the WaveStream object, which means your audioFileReader object supports them too. Once constructed, audioFileReader.TotalTime will give you a TimeSpan object with the total length of the file, and audioFileReader.CurrentTime will give you the current playback position.

You can also set the playback position by assigning to audioFileReader.CurrentTime... but doing so is a tricky process unless you know what you're doing. The following code to skip ahead 2.5 seconds works sometimes and crashes horribly at others:

audioFileReader.CurrentTime = audioFileReader.CurrentTime.Add(TimeSpan.FromSeconds(2.5));

The problem here is that the resultant stream position (in bytes) may not be correctly aligned to the start of a sample, for several reasons (including floating point math done in the background). This can quickly turn your output to garbage.

The better option is to use the Position property of the stream when you want to change playback position. Position is the currently playback position in bytes, so is a tiny bit harder to work on. Not too much though:

audioFileReader.Position += audioFileReader.WaveFormat.AverageBytesPerSecond;

If you're stepping forward or backwards an integer number of seconds, that's fine. If not, you need to make sure that you are always positioning at a sample boundary, using the WaveFormat.BlockAlign property to figure out where those boundaries are.

// Calculate new position
long newPos = audioFileReader.Position + (long)(audioFileReader.WaveFormat.AverageBytesPerSecond * 2.5);
// Force it to align to a block boundary
if ((newPos % audioFileReader.WaveFormat.BlockAlign) != 0)
    newPos -= newPos % audioFileReader.WaveFormat.BlockAlign;
// Force new position into valid range
newPos = Math.Max(0, Math.Min(audioFileReader.Length, newPos));
// set position
audioFileReader.Position = newPos;

The simple thing to do here is define a set of extensions to the WaveStream class that will handle block aligning during a seek operation. The basic align-to-block operation can be called by variations that just calculate the new position from whatever you put in, so something like this:

public static class WaveStreamExtensions
{
    // Set position of WaveStream to nearest block to supplied position
    public static void SetPosition(this WaveStream strm, long position)
    {
        // distance from block boundary (may be 0)
        long adj = position % strm.WaveFormat.BlockAlign;
        // adjust position to boundary and clamp to valid range
        long newPos = Math.Max(0, Math.Min(strm.Length, position - adj));
        // set playback position
        strm.Position = newPos;
    }

    // Set playback position of WaveStream by seconds
    public static void SetPosition(this WaveStream strm, double seconds)
    {
        strm.SetPosition((long)(seconds * strm.WaveFormat.AverageBytesPerSecond));
    }

    // Set playback position of WaveStream by time (as a TimeSpan)
    public static void SetPosition(this WaveStream strm, TimeSpan time)
    {
        strm.SetPosition(time.TotalSeconds);
    }

    // Set playback position of WaveStream relative to current position
    public static void Seek(this WaveStream strm, double offset)
    {
        strm.SetPosition(strm.Position + (long)(offset* strm.WaveFormat.AverageBytesPerSecond));
    }
}

With that in place, you can call audioFileReader.SetPosition(10.0) to jump to playback position 00:00:10.0, call audioFileReader.Seek(-5) to jump back 5 seconds, etc. without worrying about seeking to a point half way through a sample.

So... add some buttons to your form and set them up to call the Seek method with +/- values to move around. Then add a slider of some sort that you can use to display and set the playback position. Throw in a timer to update the slider position to the current playback position and you're about done.

这篇关于如何创建在C#中\NAudio音乐播放器搜索栏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆