Есть отличная библиотека bass.NET которая может проигрывать любые аудио файлы, она почти бесплатна
Для начало определим что будет в приложении. 1 - кнопка проигрывания, 2 - визуальный эффект, ну как в Windows Media Player, 3 - кнопка смены качества. Ну и на последок сделаем его красивым, добавив MetroUI,
Шаг 1. Добавим нужные библиотеки
Из bass.NET нужно только 2 файла - bass.dll, и bass.Net.dll
из MetroUI нужен Metroframework.dll
Шаг 2. Я не буду описывать работать с MetroUI, но скажу только что достаточно его подключить через References из студии, и в главной форме Form1 написать
Шаг 4. Метод Play() принимает несколько важных аргументов, точнее всего 1, но оочень важный, угадаете** ? - это ссылка на файл.
Шаг 5. Спектрум
Тут выбор очень хороший, будем использовать всё что есть
Шаг .. какойта там
Обернем весь код, что бы было проще обращаться, и в отдельную библиотеку
Настало время использовать все это добро
Для начало определим что будет в приложении. 1 - кнопка проигрывания, 2 - визуальный эффект, ну как в Windows Media Player, 3 - кнопка смены качества. Ну и на последок сделаем его красивым, добавив MetroUI,
Шаг 1. Добавим нужные библиотеки
Из bass.NET нужно только 2 файла - bass.dll, и bass.Net.dll
из MetroUI нужен Metroframework.dll
Шаг 2. Я не буду описывать работать с MetroUI, но скажу только что достаточно его подключить через References из студии, и в главной форме Form1 написать
public partial class Form1 : MetroFramework.Forms.MetroFormШаг 3. Маленька обертка для упрощения обращения с Bass.NET, в основном нам понадобятся методы Play() ну и так понятно что для плейнга сонга, GetSpectrum() для получения изображении спектра. Звучит заманчиво? Басс нет предоставляет куча-вар-иантов спектрума, воспользуемся всеми. + еще одни хандлер для перебора спектрумов (пусть это будет PictureBox Click event handler)
Шаг 4. Метод Play() принимает несколько важных аргументов, точнее всего 1, но оочень важный, угадаете** ? - это ссылка на файл.
public void Play()
{
if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
{
//stream = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, BASSFlag.BASS_DEFAULT);
stream = Bass.BASS_StreamCreateURL(_url, 0, BASSFlag.BASS_DEFAULT, null, IntPtr.Zero);
if (stream != 0)
{
Bass.BASS_ChannelPlay(stream, false);
vs = new Visuals();
}
else
{
throw new Exception(string.Format("Stream error: {0}", Bass.BASS_ErrorGetCode()));
}
}
}
Здесь как видно, Bass имеет два метода, из файла, или из ссылки, остальные аргумены трогать не стоит, аргумент _url определен как строка с адресом на интернет ресурсШаг 5. Спектрум
Тут выбор очень хороший, будем использовать всё что есть
public enum Waves
{
Line = 0,
Bean = 1,
Dot = 2,
//Elipse = 3,
LinePeak = 4,
Wave = 5
}
Теперь метод для получения того самого спектрума ** странное словоpublic Image GetSpectrum(Waves waveType)
{
if (stream != 0)
{
if (vs != null)
{
switch (waveType)
{
case Waves.Line:
return (Image)vs.CreateSpectrumLine(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
case Waves.Bean:
return (Image)vs.CreateSpectrumBean(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, false, true, true);
case Waves.Dot:
return (Image)vs.CreateSpectrumDot(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
//case Waves.Elipse:
// return (Image)vs.CreateSpectrumEllipse(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
case Waves.LinePeak:
return (Image)vs.CreateSpectrumLinePeak(stream, _width, _height, _colorBase, Color.White, _colorBase, _colorBackground, _thickness, _thickness, _distance, 5, false, true, true);
case Waves.Wave:
return (Image)vs.CreateSpectrumWave(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, false, true, true);
default:
return (Image)vs.CreateSpectrumLine(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
}
}
}
return null;
}
Откуда все эти vs? _widht? _colorBase?
это просто поля которые мы настраиваем под наше приложение, width height означают высоту ширину картинки, дада, метод возвращает картинку, которые мы будем ежесекундно перезавать в наш picturebox, и понадобится таймер, ну и что бы приложение было красивым я использовал metroui в синем-белов цвете, и что бы спектрум соответсвтовал цветовой гамме, мы и передаем _colorBase и прочее, ниже полный список
private Un4seen.Bass.Misc.Visuals vs;
private int stream;
private string _url;
public string URL { get { return _url; } set { _url = value; } }
private Timer timer1;
private Color _colorBase = Color.Black;
public Color ColorBase { get { return _colorBase; } set { _colorBase = value; } }
private Color _colorPeak = Color.Gray;
public Color ColorPeak { get { return _colorPeak; } set { _colorPeak = value; } }
private Color _colorBackground = Color.White;
public Color ColorBackground { get { return _colorBackground; } set { _colorBackground = value; } }
private int _width = 200;
public int Width { get { return _width; } set { _width = value; } }
private int _height = 50;
public int Height { get { return _height; } set { _height = value; } }
private int _thickness = 1;
public int Thickness { get { return _thickness; } set { _thickness = value; } }
private int _distance = 3;
public int Distance { get { return _distance; } set { _distance = value; } }
vs - объект передающий спектрумы,
ColorBase - основной цвет
ColorPeak - цвет при пике этой пригающей полоски
ColorBackground - тут все понятно
timer1 - получаем картинки
height, width - размеры спектрума
thickness размер полоски спектрума
distance - дистанция между полосками спектрума
Как видите настрайвать тут много чего можно, ну можно и дефолтные использоватьШаг .. какойта там
Обернем весь код, что бы было проще обращаться, и в отдельную библиотеку
using Un4seen.Bass;
using Un4seen.Bass.Misc;
namespace EuropaPlus
{
public enum Waves
{
Line = 0,
Bean = 1,
Dot = 2,
//Elipse = 3,
LinePeak = 4,
Wave = 5
}
public class Engine : IDisposable
{
private Un4seen.Bass.Misc.Visuals vs;
private int stream;
private string _url;
public string URL { get { return _url; } set { _url = value; } }
private Timer timer1;
private Color _colorBase = Color.Black;
public Color ColorBase { get { return _colorBase; } set { _colorBase = value; } }
private Color _colorPeak = Color.Gray;
public Color ColorPeak { get { return _colorPeak; } set { _colorPeak = value; } }
private Color _colorBackground = Color.White;
public Color ColorBackground { get { return _colorBackground; } set { _colorBackground = value; } }
private int _width = 200;
public int Width { get { return _width; } set { _width = value; } }
private int _height = 50;
public int Height { get { return _height; } set { _height = value; } }
private int _thickness = 1;
public int Thickness { get { return _thickness; } set { _thickness = value; } }
private int _distance = 3;
public int Distance { get { return _distance; } set { _distance = value; } }
public Engine(string Url, Color Base, Color Peak, Color Background, int width, int height, int thickness, int distance)
{
this._url = Url;
this._colorBase = Base;
this._colorPeak = Peak;
this._colorBackground = Background;
this._width = width;
this._height = height;
this._thickness = thickness;
this._distance = distance;
}
public Engine(string Url, Color Base, Color Peak, Color Background, int width, int height)
{
this._url = Url;
this._colorBase = Base;
this._colorPeak = Peak;
this._colorBackground = Background;
this._width = width;
this._height = height;
}
public Engine(string Url, int width, int height)
{
this._url = Url;
this._width = width;
this._height = height;
}
public Engine(string Url)
{
this._url = Url;
}
///
/// Custom spectrum wave from 'url'
///
/// Image
public void Play()
{
if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
{
//stream = Bass.BASS_StreamCreateFile("test.mp3", 0, 0, BASSFlag.BASS_DEFAULT);
stream = Bass.BASS_StreamCreateURL(_url, 0, BASSFlag.BASS_DEFAULT, null, IntPtr.Zero);
if (stream != 0)
{
Bass.BASS_ChannelPlay(stream, false);
vs = new Visuals();
}
else
{
throw new Exception(string.Format("Stream error: {0}", Bass.BASS_ErrorGetCode()));
}
}
}
public void FlushSpectrum()
{
vs = new Visuals();
}
public Image GetSpectrum(Waves waveType)
{
if (stream != 0)
{
if (vs != null)
{
switch (waveType)
{
case Waves.Line:
return (Image)vs.CreateSpectrumLine(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
case Waves.Bean:
return (Image)vs.CreateSpectrumBean(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, false, true, true);
case Waves.Dot:
return (Image)vs.CreateSpectrumDot(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
//case Waves.Elipse:
// return (Image)vs.CreateSpectrumEllipse(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
case Waves.LinePeak:
return (Image)vs.CreateSpectrumLinePeak(stream, _width, _height, _colorBase, Color.White, _colorBase, _colorBackground, _thickness, _thickness, _distance, 5, false, true, true);
case Waves.Wave:
return (Image)vs.CreateSpectrumWave(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, false, true, true);
default:
return (Image)vs.CreateSpectrumLine(stream, _width, _height, _colorBase, _colorPeak, _colorBackground, _thickness, _distance, false, true, true);
}
}
}
return null;
}
public void Dispose()
{
Bass.BASS_Free();
this._url = null;
this.stream = 0;
vs = null;
}
}
}
Настало время использовать все это добро
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Un4seen.Bass;
using Un4seen.Bass.Misc;
using MetroFramework;
namespace EuropaPlus
{
public partial class Form1 : MetroFramework.Forms.MetroForm
{
public Form1()
{
InitializeComponent();
//this.Size = new Size(190, 173);
this.metroButton1.Size = new Size(150, 80);
this.metroButton1.Location = new Point(20, 60);
//this.pictureBox1.Size = new Size(150, 80);
//this.pictureBox1.Location = new Point(20, 60);
this.metroButton1.Text = "Play";
this.metroToggle1.Visible = false;
this.metroToggle2.Visible = false;
wvv = Waves.Line;
rnd = new Random();
}
private bool animDone = false;
private bool animDone2 = false;
private Random rnd;
private Waves wvv;
private Engine eng;
private const string music = "http://ep256.streamr.ru";
private const string music2 = "http://ep128.streamr.ru";
private MetroFramework.Animation.MoveAnimation mvAnimBut;
//private MetroFramework.Animation.ExpandAnimation exAnimForm;
private MetroFramework.Animation.ExpandAnimation exAnimBut;
private void StartGrabbing()
{
eng.FlushSpectrum();
timer1.Stop();
timer1.Interval = 100;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
GetImages();
}
private void GetImages()
{
this.pictureBox1.Image = eng.GetSpectrum(wvv);
}
private void metroButton1_Click(object sender, EventArgs e)
{
if (animDone2 == true)
{
eng.Dispose();
if (metroToggle2.CheckState == CheckState.Checked)
eng = new Engine(music, this.pictureBox1.Width, this.pictureBox1.Height);
else
eng = new Engine(music2, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play();
StartGrabbing();
}
else
{
try
{
if (metroToggle2.CheckState == CheckState.Checked)
eng = new Engine(music, this.pictureBox1.Width, this.pictureBox1.Height);
else
eng = new Engine(music2, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play();
StartGrabbing();
DoAnim();
animDone2 = true;
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return;
}
}
}
private void DoAnim()
{
if (animDone == false)
{
mvAnimBut = new MetroFramework.Animation.MoveAnimation();
exAnimBut = new MetroFramework.Animation.ExpandAnimation();
//exAnimForm = new MetroFramework.Animation.ExpandAnimation();
exAnimBut.Start(metroButton1, new Size(48, 17), MetroFramework.Animation.TransitionType.EaseOutExpo, 50);
//exAnimForm.Start(this, new Size(600, 200), MetroFramework.Animation.TransitionType.EaseOutExpo, 50);
mvAnimBut.Start(this.metroButton1, new Point(74, 128), MetroFramework.Animation.TransitionType.EaseOutCubic, 50);
this.metroToggle1.Visible = true;
this.metroToggle2.Visible = true;
animDone = true;
this.metroButton1.Text = "Playing";
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void metroToggle1_CheckedChanged(object sender, EventArgs e)
{
if (this.metroStyleManager1.Theme == MetroThemeStyle.Light)
{
this.metroStyleManager1.Theme = MetroThemeStyle.Dark;
eng.ColorBackground = Color.FromArgb(19,19,19);
}
else
{
this.metroStyleManager1.Theme = MetroThemeStyle.Light;
eng.ColorBackground = Color.White;
}
}
private void metroToggle2_CheckedChanged(object sender, EventArgs e)
{
if (metroToggle2.CheckState == CheckState.Checked)
{
eng.Dispose();
eng = new Engine(music, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play(); StartGrabbing();
}
else
{
eng.Dispose();
eng = new Engine(music2, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play(); StartGrabbing();
}
}
//http://ep128.streamr.ru
private void pictureBox1_Click(object sender, EventArgs e)
{
wvv = (Waves)rnd.Next(5);
StartGrabbing();
}
}
}
Теперь по порядку, приложение запускается, появляется милинькое окошко
при нажатии Play приложение вызывает
private void metroButton1_Click(object sender, EventArgs e)
{
if (animDone2 == true)
{
eng.Dispose();
if (metroToggle2.CheckState == CheckState.Checked)
eng = new Engine(music, this.pictureBox1.Width, this.pictureBox1.Height);
else
eng = new Engine(music2, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play();
StartGrabbing();
}
else
{
try
{
if (metroToggle2.CheckState == CheckState.Checked)
eng = new Engine(music, this.pictureBox1.Width, this.pictureBox1.Height);
else
eng = new Engine(music2, this.pictureBox1.Width, this.pictureBox1.Height);
eng.Thickness = 1;
eng.Distance = 0;
eng.ColorBase = Color.DeepSkyBlue;
if (metroStyleManager1.Theme == MetroThemeStyle.Light) eng.ColorBackground = Color.White;
else eng.ColorBackground = Color.FromArgb(19, 19, 19);
eng.ColorPeak = Color.DeepSkyBlue;
eng.Play();
StartGrabbing();
DoAnim();
animDone2 = true;
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
return;
}
}
}
в котором описано поведение, то есть кнопка уменьшается, движется в середину, и изменяется текст, и в соответсви с выбранной темой, все преобразуется в некую гамму,
ну чесно говоря в коде все итак понятно, думаю никчему больше слов, )) Исходник на Github


