« 2016年02月 | メイン | 2016年04月 »

1  2  3  4

2016年03月 記事一覧

2016年03月09日

第01回 プロジェクト作成と曲再生

今回はVisual Studio 2012を利用しました。
「ファイルメニュー」の「新規作成」にある「プロジェクトの作成」を選択し、新しいプロジェクトを作成します。

テンプレートは「Visual C#」の「Windows」にある「Windowsフォームアプリケーション」を採用し、プロジェクト名は「MP3Player」としました。

プロジェクトができたらいきなり曲を再生してみます。

再生にはWindows Media Playerのコントロールを利用します。
まずはこのコントロールを利用するために参照の追加作業。
「プロジェクト」メニューにある「参照の追加」を選択し、「参照マネージャー」を開き、ここで「参照」ボタンを押し、「C:\Windows\System32\wmp.dll」を追加します。

wmp.dlの参照を追加したら、次に曲を再生するためのコードを追加します。
ソリューションエクスプローラーから「Form1」を開き、以下のように5行追加します。

追加できたらビルドして実行。これだけで単純に曲が再生できました。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;			//追加

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();			//追加

		public Form1()
		{
			InitializeComponent();

			//以下追加
			_mediaPlayer.settings.volume = 20;
			_mediaPlayer.URL = @"G:\Desktop\mp3\コレサワ - 君のバンド\01 君のバンド.mp3";
			_mediaPlayer.controls.play();
		}
	}
}

プロジェクトファイルをダウンロード

第02回 ループ再生する

前回「第01回 プロジェクト作成と曲再生」作成したものは、1曲を1度だけ再生するものでした。
今回は曲の再生が終わったら、再び再生するようにします。

今後シークバーを追加することも考え、簡単にタイマーを使って実現します。
Windows Media Playerの再生状況はplayStateで参照でき、これがWMPPlayState.wmppsStoppedになっていたら、再度再生するという単純なものです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();		//追加

		public Form1()
		{
			InitializeComponent();


			//以下を追加
			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					_mediaPlayer.controls.play();
				}
			};
			_timer.Start();


			_mediaPlayer.settings.volume = 20;
			_mediaPlayer.URL = @"G:\Desktop\mp3\コレサワ - 君のバンド\01 君のバンド.mp3";
			_mediaPlayer.controls.play();
		}
	}
}

プロジェクトファイルをダウンロード

第03回 フォルダ内のファイルを順番に再生する

前回「第02回 ループ再生する」作成したものは同じ曲を何度もループ再生するものでした。
今回はフォルダ内にあるmp3ファイルを順番に再生するようにします。

音楽ファイルの検索はDirectory.EnumerateFiles()を利用し、これで音楽ファイル以外も含めた全ファイルの一覧を取得。その中から拡張子がmp3/m4aのファイルのみを抜き出して、_liststrFilesへ追加します。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		//以下を追加
		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		public Form1()
		{
			InitializeComponent();

			//以下を追加
			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定
			if (_liststrFiles.Count > 0)
				_nCurrentIndex = 0;

			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					//以下を追加/変更
					if (_liststrFiles.Count > 0)
					{
						_nCurrentIndex++;
						if (_nCurrentIndex >= _liststrFiles.Count)
							_nCurrentIndex = 0;
						_mediaPlayer.URL = _liststrFiles[_nCurrentIndex];	//次の曲をセット
						_mediaPlayer.controls.play();
					}
				}
			};
			_timer.Start();


			//以下を追加/変更
			_mediaPlayer.settings.volume = 20;
			if (_liststrFiles.Count > 0)
				_mediaPlayer.URL = _liststrFiles[_nCurrentIndex];			//最初の再生曲をセット
			_mediaPlayer.controls.play();
		}


		//以下を追加
		/// <summary>
		/// フォルダ内のファイルを一覧して返す
		/// </summary>
		List<string> EnumFiles(string strFolder)
		{
			List<string> ret = new List<string>();

			//指定フォルダ以下の全子フォルダから全ファイルを抜き出す
			IEnumerable<string> listFiles = Directory.EnumerateFiles(strFolder, "*.*", SearchOption.AllDirectories);

			foreach (string strFile in listFiles)
			{
				//見つかったファイルの拡張子を取り出し
				string strExt = Path.GetExtension(strFile).ToLower();
				if (strExt == "")
					continue;

				//mp3/m4a以外なら無視
				if (strExt != ".mp3" && strExt != ".m4a")
					continue;

				ret.Add(strFile);
			}

			return ret;
		}
	}
}

プロジェクトファイルをダウンロード

第04回 ランダムに再生する

前回「第03回 フォルダ内のファイルを順番に再生する作成したものは、指定したフォルダ内のmp3/m4aファイルを順番に再生するものでした。
今回はランダム再生に変更します。

ランダムにするのは再生したい曲のインデックスをRandom.Nextで決めるだけの単純な処理です。
ついでに曲再生部分のコードが重複していたので整理がてらPlay()を作成してまとめました。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定
			//以下を削除
			//if (_liststrFiles.Count > 0)
			//	_nCurrentIndex = 0;

			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					//以下を変更
					Play();
				}
			};
			_timer.Start();

			_mediaPlayer.settings.volume = 20;
			//以下を変更
			Play();
		}


		//以下を追加
		/// <summary>
		/// 曲を再生する
		/// </summary>
		void Play()
		{
			if (_liststrFiles.Count == 0)
				return;

			_nCurrentIndex = GetNextIndex();
			_mediaPlayer.URL = _liststrFiles[_nCurrentIndex];			//最初の再生曲をセット
			_mediaPlayer.controls.play();
		}



		//以下を追加
		/// <summary>
		/// 次の再生曲インデックスを決める
		/// </summary>
		int GetNextIndex()
		{
			if (_liststrFiles.Count == 0)
				return -1;

			int nIndex;
			Random rnd = new Random(Environment.TickCount);

			while (true)
			{
				//ランダムで曲を決定
				nIndex = rnd.Next(0, _liststrFiles.Count);

				//同じ曲は連続で演奏しない
				if (nIndex == _nCurrentIndex)
					continue;

				break;
			}

			return nIndex;
		}



		/// <summary>
		/// フォルダ内のファイルを一覧して返す
		/// </summary>
		List<string> EnumFiles(string strFolder)
		{
			List<string> ret = new List<string>();

			//指定フォルダ以下の全子フォルダから全ファイルを抜き出す
			IEnumerable<string> listFiles = Directory.EnumerateFiles(strFolder, "*.*", SearchOption.AllDirectories);

			foreach (string strFile in listFiles)
			{
				//見つかったファイルの拡張子を取り出し
				string strExt = Path.GetExtension(strFile).ToLower();
				if (strExt == "")
					continue;

				//mp3/m4a以外なら無視
				if (strExt != ".mp3" && strExt != ".m4a")
					continue;

				ret.Add(strFile);
			}

			return ret;
		}

	}
}

プロジェクトファイルをダウンロード

第05回 画面を作る

これまでにフォルダ内に存在するmp3/m4aをランダムに再生するところまできました。
今回はメインウインドウの作成をします。

曲名表示用のラベル「labelTitle」、
アーティスト名表示用のラベル「labelArtist」、
現在の再生時間表示用のラベル「labelTime」、
シークバー用のトラックバー「trackbarSeek」、
音量調節用のトラックバー「trackbarVolume」、
前の曲に戻るためのボタン「buttonBack」、
次の曲に進むためのボタン「buttonNext」、
再生/停止用のボタン「buttonPlay」、
再生中断用のボタン「buttonStop」、

をそれぞれフォームに配置します。
今回はデザインだけで機能の実装は次回以降に持ち越し。

2つのトラックバーは、デフォルトの設定だと大きすぎるため、プロパティの「TickStyle」を「None」、「AutoSize」を「False」に設定しました。

ボタン用の画像を用意するのが面倒だったので「Text」として「|<」や「>」、「□」、「>|」という文字を設定しています。

005_01.png

プロジェクトファイルをダウンロード

第06回 再生位置をシークバーに表示する

前回「第05回 画面を作る」はメインウインドウにカタチだけシークバーとなるトラックバーコントロールなどを配置しました。
今回はそのシークバーの中身を実装します。

処理の流れは、タイマーで曲のどの辺を再生しているのかを取得し、それをトラックバーコントロールに適用します。
それだけでは人の操作によるシーク位置の設定ができませんが、それは次回以降に持ち越し。
今回はシーク位置の表示のみです。

曲の長さは_mediaPlayer.controls.currentItem.durationにdouble値で、
再生位置は_mediaPlayer.controls.currentPositionにdouble値で、
文字列としての再生位置は_mediaPlayer.controls.currentPositionStringにstring値で、
取得できるためそれらを利用しています。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定

			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				//以下を追加
				if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
				{
					try
					{
						//シークバーに再生位置を表示
						//曲変更タイミングによっては例外出る可能性ある
						trackBarSeek.Maximum = (int)(_mediaPlayer.controls.currentItem.duration * 100);
						trackBarSeek.Value = (int)(_mediaPlayer.controls.currentPosition * 100);
					}
					catch(Exception)
					{
					}

					//再生時間の表示
					labelTime.Text = _mediaPlayer.controls.currentPositionString;
				}

				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					Play();
				}
			};
			_timer.Start();

			_mediaPlayer.settings.volume = 20;
			Play();
		}

プロジェクトファイルをダウンロード

第07回 再生位置をシークバーで移動する

前回「第06回 再生位置をシークバーに表示する」はシークバーに現在の再生位置を表示しました。
今回はシークバーを操作することで再生位置を自由に設定できるようにします。

トラックバーを操作するとき=トラックバーにフォーカスがある
という等式を利用した簡易的な実装にしました。
そのためトラックバーにフォーカスがあるとシーク位置が更新されません。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定

			//追加
			//フォームが表示されたときの処理
			Shown += delegate
			{
				//シークバーにフォーカスがあると、再生位置が表示されないのでここで再生ボタンにフォーカスを与える
				buttonPlay.Focus();
			};

			//追加
			//再生位置のシーク
			trackBarSeek.ValueChanged += delegate
			{
				if (trackBarSeek.Focused)
				{
					_mediaPlayer.controls.currentPosition = (double)trackBarSeek.Value / 100;
				}
			};


			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
				{
					//変更
					trackBarSeek.Maximum = (int)(_mediaPlayer.controls.currentItem.duration * 100);
					//シークバーにフォーカスがないときだけ再生位置を表示する
					if (trackBarSeek.Focused == false)
					{
						try
						{
							//シークバーに再生位置を表示
							//曲変更タイミングによっては例外出る可能性ある
							trackBarSeek.Value = (int)(_mediaPlayer.controls.currentPosition * 100);
						}
						catch (Exception)
						{
						}
					}

					//再生時間の表示
					labelTime.Text = _mediaPlayer.controls.currentPositionString;
				}

				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					Play();
				}
			};
			_timer.Start();

			_mediaPlayer.settings.volume = 20;
			Play();
		}

プロジェクトファイルをダウンロード

第08回 音量を調節可能にする

前回「第07回 再生位置をシークバーで移動する」はシークバーによる再生位置の設定をしました。
今回は同じようにボリューム用のトラックバーを実装します。

ボリュームは再生位置とは異なり、ユーザー側で設定するのみなので実装は簡単です。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定


			//フォームが表示されたときの処理
			Shown += delegate
			{
				//シークバーにフォーカスがあると、再生位置が表示されないのでここで再生ボタンにフォーカスを与える
				buttonPlay.Focus();
			};


			//再生位置のシーク
			trackBarSeek.ValueChanged += delegate
			{
				if (trackBarSeek.Focused)
				{
					_mediaPlayer.controls.currentPosition = (double)trackBarSeek.Value / 100;
				}
			};


			//追加
			//音量の調節
			_mediaPlayer.settings.volume = 20;
			trackBarVolume.Maximum = 100;			//音量はゼロから100
			trackBarVolume.Value = _mediaPlayer.settings.volume;
			trackBarVolume.ValueChanged += delegate
			{
				_mediaPlayer.settings.volume = (int)trackBarVolume.Value;
			};


			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
				{
					//変更
					trackBarSeek.Maximum = (int)(_mediaPlayer.controls.currentItem.duration * 100);
					//シークバーにフォーカスがないときだけ再生位置を表示する
					if (trackBarSeek.Focused == false)
					{
						try
						{
							//シークバーに再生位置を表示
							//曲変更タイミングによっては例外出る可能性ある
							trackBarSeek.Value = (int)(_mediaPlayer.controls.currentPosition * 100);
						}
						catch (Exception)
						{
						}
					}

					//再生時間の表示
					labelTime.Text = _mediaPlayer.controls.currentPositionString;
				}

				//止まっていたら再び再生
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					Play();
				}
			};
			_timer.Start();


			//_mediaPlayer.settings.volume = 20;		//削除
			Play();
		}

プロジェクトファイルをダウンロード

第09回 再生/停止/次ボタンを実装する

今回は放置していたボタンのうち3つ、再生/停止/次の曲ボタンを実装します。

フォームのデザイナー上で各ボタンをダブルクリックして、
buttonPlay_Click()
buttonStop_Click()
buttonNext_Click()
をそれぞれ自動生成。それらの中身を追加します。

		private void buttonPlay_Click(object sender, EventArgs e)
		{
			//以下を追加
			if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying)
				_mediaPlayer.controls.pause();
			else if (_nCurrentIndex >= 0)
				_mediaPlayer.controls.play();
		}

		private void buttonStop_Click(object sender, EventArgs e)
		{
			//以下を追加
			if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
			{
				_bStopButtonPushed = true;
				_mediaPlayer.controls.stop();
			}
		}

		private void buttonNext_Click(object sender, EventArgs e)
		{
			Play();			//追加
		}

それだけだと、「停止」ボタンを押して曲の再生が止まったと思ったらすぐに次の曲が再生されたり、
ボタンの表示が再生中も一時停止中も「>」のままで変化しないなど微妙に問題があります。
そのためさらに_mediaPlayer.PlayStateChangeを追加して、再生状況の変化に応じた処理をいれます。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		//以下を追加
		bool _bStopButtonPushed = false;	//「停止」ボタンを押したらtrue

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定


			//フォームが表示されたときの処理
			Shown += delegate
			{
				//シークバーにフォーカスがあると、再生位置が表示されないのでここで再生ボタンにフォーカスを与える
				buttonPlay.Focus();
			};


			//再生位置のシーク
			trackBarSeek.ValueChanged += delegate
			{
				if (trackBarSeek.Focused)
				{
					_mediaPlayer.controls.currentPosition = (double)trackBarSeek.Value / 100;
				}
			};


			//音量の調節
			_mediaPlayer.settings.volume = 20;
			trackBarVolume.Maximum = 100;			//音量はゼロから100
			trackBarVolume.Value = _mediaPlayer.settings.volume;
			trackBarVolume.ValueChanged += delegate
			{
				_mediaPlayer.settings.volume = (int)trackBarVolume.Value;
			};


			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
				{
					//変更
					trackBarSeek.Maximum = (int)(_mediaPlayer.controls.currentItem.duration * 100);
					//シークバーにフォーカスがないときだけ再生位置を表示する
					if (trackBarSeek.Focused == false)
					{
						try
						{
							//シークバーに再生位置を表示
							//曲変更タイミングによっては例外出る可能性ある
							trackBarSeek.Value = (int)(_mediaPlayer.controls.currentPosition * 100);
						}
						catch (Exception)
						{
						}
					}

					//再生時間の表示
					labelTime.Text = _mediaPlayer.controls.currentPositionString;
				}

				//以下を変更
				//止まっていたら再び再生。ただし停止ボタンが押されている場合は無視
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					if (_bStopButtonPushed == false)
						Play();
				}
			};
			_timer.Start();


			//以下を追加
			_mediaPlayer.PlayStateChange += delegate(int nNewState)
			{
				WMPPlayState state = (WMPPlayState)nNewState;

				switch (state)
				{
					case WMPPlayState.wmppsStopped:
						buttonPlay.Text = ">";
						trackBarSeek.Value = 0;
						break;

					case WMPPlayState.wmppsPaused:
						_timer.Stop();
						buttonPlay.Text = ">";
						break;

					case WMPPlayState.wmppsPlaying:
						_bStopButtonPushed = false;
						buttonPlay.Text = "||";
						_timer.Start();
						break;

					case WMPPlayState.wmppsTransitioning:
						break;
				}
			};

			Play();
		}

プロジェクトファイルをダウンロード

第10回 「戻る」ボタンを実装する

今回は「前の曲に戻る」ボタンを実装します。

「戻る」ためには再生曲の履歴を保存する必要があります。
また、さらに戻った後に再び同じ曲を再生できるように未来の曲も併せて保存する必要が生じます。
それらをPlay()とGetNextIndex()で行うことにしました。

フォームのデザイナで「戻る」ボタンをダブルクリックしてbuttonBack_Click()を自動生成後にコードを追加/変更します。

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.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		Timer _timer = new Timer();

		List<string> _liststrFiles;			//音楽ファイル一覧
		int _nCurrentIndex = -1;			//↑へのインデックス

		//以下を追加
		List<int> _listPlayHistory = new List<int>();		//過去の再生曲
		List<int> _listPlayNext = new List<int>();			//未来の再生曲。なければランダム


		bool _bStopButtonPushed = false;	//「停止」ボタンを押したらtrue

		public Form1()
		{
			InitializeComponent();

			_liststrFiles = EnumFiles(@"G:\Desktop\mp3\");		//再生したいmp3保存フォルダを指定


			//フォームが表示されたときの処理
			Shown += delegate
			{
				//シークバーにフォーカスがあると、再生位置が表示されないのでここで再生ボタンにフォーカスを与える
				buttonPlay.Focus();
			};


			//再生位置のシーク
			trackBarSeek.ValueChanged += delegate
			{
				if (trackBarSeek.Focused)
				{
					_mediaPlayer.controls.currentPosition = (double)trackBarSeek.Value / 100;
				}
			};


			//音量の調節
			_mediaPlayer.settings.volume = 20;
			trackBarVolume.Maximum = 100;			//音量はゼロから100
			trackBarVolume.Value = _mediaPlayer.settings.volume;
			trackBarVolume.ValueChanged += delegate
			{
				_mediaPlayer.settings.volume = (int)trackBarVolume.Value;
			};


			_timer.Interval = 300;			//300msecごとに処理を実行
			_timer.Tick += delegate
			{
				if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
				{
					trackBarSeek.Maximum = (int)(_mediaPlayer.controls.currentItem.duration * 100);
					//シークバーにフォーカスがないときだけ再生位置を表示する
					if (trackBarSeek.Focused == false)
					{
						try
						{
							//シークバーに再生位置を表示
							//曲変更タイミングによっては例外出る可能性ある
							trackBarSeek.Value = (int)(_mediaPlayer.controls.currentPosition * 100);
						}
						catch (Exception)
						{
						}
					}

					//再生時間の表示
					labelTime.Text = _mediaPlayer.controls.currentPositionString;
				}

				//止まっていたら再び再生。ただし停止ボタンが押されている場合は無視
				if (_mediaPlayer.playState == WMPPlayState.wmppsStopped)
				{
					if (_bStopButtonPushed == false)
						Play();
				}
			};
			_timer.Start();


			_mediaPlayer.PlayStateChange += delegate(int nNewState)
			{
				WMPPlayState state = (WMPPlayState)nNewState;

				switch (state)
				{
					case WMPPlayState.wmppsStopped:
						buttonPlay.Text = ">";
						trackBarSeek.Value = 0;
						break;

					case WMPPlayState.wmppsPaused:
						_timer.Stop();
						buttonPlay.Text = ">";
						break;

					case WMPPlayState.wmppsPlaying:
						_bStopButtonPushed = false;
						buttonPlay.Text = "||";
						_timer.Start();
						break;

					case WMPPlayState.wmppsTransitioning:
						break;
				}
			};

			Play();
		}





		/// <summary>
		/// 曲を再生する
		/// </summary>
		void Play(bool bPlayNext = true)			//変更
		{
			if (_liststrFiles.Count == 0)
				return;

			//追加/変更
			if (bPlayNext || _listPlayHistory.Count == 0)
			{
				//次の曲を再生する

				if (_nCurrentIndex >= 0)
				{
					_listPlayHistory.Add(_nCurrentIndex);					//今の曲を履歴として保存
					if (_listPlayHistory.Count > 100)						//履歴の最大保存数は100
						_listPlayHistory.RemoveAt(0);
				}

				_nCurrentIndex = GetNextIndex();
			}
			else
			{
				//前の曲を再生する
				if (_nCurrentIndex >= 0)
					_listPlayNext.Insert(0, _nCurrentIndex);					//今の曲を次の曲として保存
				_nCurrentIndex = _listPlayHistory[_listPlayHistory.Count - 1];	//一番最新の履歴曲を今の曲とする
				_listPlayHistory.RemoveAt(_listPlayHistory.Count - 1);			//一番最新の履歴曲を削除
			}

			_mediaPlayer.URL = _liststrFiles[_nCurrentIndex];			//最初の再生曲をセット
			_mediaPlayer.controls.play();
		}



		/// <summary>
		/// 次の再生曲インデックスを決める
		/// </summary>
		int GetNextIndex()
		{
			if (_liststrFiles.Count == 0)
				return -1;

			int nIndex;
			Random rnd = new Random(Environment.TickCount);

			while (true)
			{
				//変更
				if (_listPlayNext.Count == 0)
				{
					//未来の曲リストが空ならランダムで曲を決定
					nIndex = rnd.Next(0, _liststrFiles.Count);
				}
				else
				{
					//未来の曲リストから次の曲を決定
					nIndex = _listPlayNext[0];
					_listPlayNext.RemoveAt(0);
				}

				//同じ曲は連続で演奏しない
				if (nIndex == _nCurrentIndex)
					continue;

				break;
			}

			return nIndex;
		}



		/// <summary>
		/// フォルダ内のファイルを一覧して返す
		/// </summary>
		List<string> EnumFiles(string strFolder)
		{
			List<string> ret = new List<string>();

			//指定フォルダ以下の全子フォルダから全ファイルを抜き出す
			IEnumerable<string> listFiles = Directory.EnumerateFiles(strFolder, "*.*", SearchOption.AllDirectories);

			foreach (string strFile in listFiles)
			{
				//見つかったファイルの拡張子を取り出し
				string strExt = Path.GetExtension(strFile).ToLower();
				if (strExt == "")
					continue;

				//mp3/m4a以外なら無視
				if (strExt != ".mp3" && strExt != ".m4a")
					continue;

				ret.Add(strFile);
			}

			return ret;
		}



		private void buttonPlay_Click(object sender, EventArgs e)
		{
			if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying)
				_mediaPlayer.controls.pause();
			else if (_nCurrentIndex >= 0)
				_mediaPlayer.controls.play();
		}

		private void buttonStop_Click(object sender, EventArgs e)
		{
			if (_mediaPlayer.playState == WMPPlayState.wmppsPlaying || _mediaPlayer.playState == WMPPlayState.wmppsPaused)
			{
				_bStopButtonPushed = true;
				_mediaPlayer.controls.stop();
			}
		}

		private void buttonNext_Click(object sender, EventArgs e)
		{
			Play();
		}

		private void buttonBack_Click(object sender, EventArgs e)
		{
			//以下を追加
			Play(false);		//前の曲を再生
		}

	}
}

プロジェクトファイルをダウンロード

1  2  3  4





usefullcode@gmail.com

About 2016年03月

2016年03月にブログ「UsefullCode.net」に投稿されたすべてのエントリーです。

前の記事は2016年02月です。

次の記事は2016年04月です。

他にも多くのエントリーがあります。メインページ記事一覧も見てください。