
- •Задание на выполнение курсовой работы
- •Р еферат
- •Содержание
- •1 Разработка приложения "Audio Player":
- •Введение
- •1 Разработка приложения "Audio Player"
- •1.1 Анализ требований
- •Требования к программе:
- •Требования к пользовательскому интерфейсу:
- •1.2 Проектирование
- •1.3 Кодирование
- •1.4 Тестирование
- •Заключение
- •Список используемых источников
- •Приложение а
1.4 Тестирование
Для проверки правильности работы разработанной программы были проведены следующие действия: (Результаты работы программы приведены на рисунках 2-12)
Добавление музыкального файла в список воспроизведения:
Рисунок 2 – Добавление музыкально файла.
Рисунок 3 – Файл добавлен в список воспроизведения.
При воспроизведение файла кнопка Play должна меняться на Pause.
Рисунок 4 – Воспроизведение файла.
При удаление файла его воспроизведение продолжается.
Рисунок 5 – Файл удалён из списка воспроизведения.
Для дальней работы откроем готовый список воспроизведения.
Рисунок 6 – Открытие списка воспроизведения.
Рисунок 7 – Открытый список воспроизведения.
Список воспроизведения мы можем отсортировать. С помощью кнопок «Название» и «Время» список сортируется по соответствующим критериям.
Рисунок 8 – Сортировка по названию.
Рисунок 9 – сортировка по времени.
Кроме как открывать список воспроизведения программа может его сохранять. Сохранение списка воспроизведения происходит в формате .spl.
Рисунок 10 – Сохранение списка воспроизведения.
В нижней панели находятся кнопки «Вверх» и «Вниз» для перемещения файла в по списку воспроизведения.
Рисунок 11 – Перемещение файла в списке воспроизведения.
Информацию о программе можно узнать при нажатии «О программе»
Рисунок 12 – О программе.
Заключение
В результате выполнения курсового проекта было разработано приложение «Audio Player». Все поставленные задачи были осуществлены. Навыки, полученные при написании программы, могут быть применены в дальнейшем при написании более сложных программ.
Развитие данного приложения может осуществляться по следующим направлениям:
поиск файла в списке воспроизведения по названию;
добавление списка воспроизведения в текущий список.
Список используемых источников
Словарь по естественным наукам Глоссарий.ру
http://www.glossary.ru/cgi-bin/gl_sch2.cgi?RAiyusgyonowuigttul!vwujwgssowuigtol
2. Свободная энциклопедия ВикипедиЯ.
http://ru.wikipedia.org/wiki/Визуальное_программирование
3. Свободная энциклопедия ВикипедиЯ.
http://ru.wikipedia.org/wiki/DirectShow
Приложение а
(обязательное)
Листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.IO;
namespace MediaPlayer
{
internal enum PlayState
{
Stopped,
Paused,
Running,
Init
};
internal enum PlayMode
{
RepeatAll,
RepeatOne,
RepeatNone
};
public partial class MainForm : Form
{
private const int WMGraphNotify = 0x0400 + 13;//сообщение
private const int VolumeFull = 0;//максимальная громкость
private const int VolumeSilence = -10000;//минимальная громкасть
private IGraphBuilder graphBuilder = null;//граф фильтров для воспроизведения
private IMediaControl mediaControl = null;//управление воспроизведением
private IMediaEventEx mediaEventEx = null;//собития при воспроизведении
private IVideoWindow videoWindow = null;//окно воспроизведения видео
private IBasicAudio basicAudio = null;//управление аудио потоком
private IBasicVideo basicVideo = null;//управление видео потоком
private IMediaSeeking mediaSeeking = null;//перемещение по потоку
private IMediaPosition mediaPosition = null;//позиция при воспроизведении
private string filename = string.Empty;//полный путь воспроизводимого файла
private PlayState currentState = PlayState.Stopped;//состояние воспроизведения
private string currentPlay = "";//имя воспроизводимого файла
private PlayMode playMode = PlayMode.RepeatAll; //режим воспроизведения
public MainForm()
{
InitializeComponent();
controlPanel_SizeChanged(null, null);
LoadList("currentPlay.rpl");//загружаем последний список воспроизвдения
SetTimeLabel(0, 0);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();//выход из программы
}
private void addFileToolStripMenuItem_Click(object sender, EventArgs e)
{
if (addFilesOpenFileDialog.ShowDialog() == DialogResult.Cancel) return;
AddFiles(addFilesOpenFileDialog.FileNames);//добавляем файлы в список воспроизведния
}
private void CloseClip()//закрываем файл который воспроизводился
{
int hr = 0;
// Stop media playback
if (this.mediaControl != null)
hr = this.mediaControl.Stop();
// Clear global flags
this.currentState = PlayState.Stopped;
// Free DirectShow interfaces
CloseInterfaces();
// Clear file name to allow selection of new file with open dialog
this.filename = string.Empty;
// No current media state
this.currentState = PlayState.Init;
}
private void OpenClip(string filename, bool autoPlay)//открываем файл
{
try
{
if (filename == string.Empty)
return;
// Reset status variables
this.currentState = PlayState.Stopped;
// Start playing the media file
PlayMovieInWindow(filename, autoPlay);
}
catch
{
CloseClip();//в случае ошибки закрываем файл
}
}
private void PlayMovieInWindow(string filename, bool startPlay)//открываем файл для воспроизведения
{
int hr = 0;
if (filename == string.Empty)
return;
this.graphBuilder = (IGraphBuilder)new FilterGraph();
// Have the graph builder construct its the appropriate graph automatically
hr = this.graphBuilder.RenderFile(filename, null);
DsError.ThrowExceptionForHR(hr);
// QueryInterface for DirectShow interfaces
this.mediaControl = (IMediaControl)this.graphBuilder;
this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
this.mediaSeeking = (IMediaSeeking)this.graphBuilder;
this.mediaPosition = (IMediaPosition)this.graphBuilder;
// Query for video interfaces, which may not be relevant for audio files
this.basicAudio = this.graphBuilder as IBasicAudio;
// Is this an audio-only file (no video component)?
//CheckVisibility();
// Have the graph signal event via window callbacks for performance
hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WMGraphNotify, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
if (startPlay)//если автоматчески запустить файл на воспроизведение
{
this.Focus();
basicAudio.put_Volume((int)((double)(VolumeSilence - VolumeFull) * (1-volumeSize)));
// Run the graph to play the media file
hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
this.currentState = PlayState.Running;
}
}
private void CloseInterfaces()//освобождаем ресурсы после остановки воспроизвдения
{
int hr = 0;
try
{
lock (this)
{
// Relinquish ownership (IMPORTANT!) after hiding video window
if (this.mediaEventEx != null)
{
hr = this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}
// Release and zero DirectShow interfaces
if (this.mediaEventEx != null)
this.mediaEventEx = null;
if (this.mediaSeeking != null)
this.mediaSeeking = null;
if (this.mediaPosition != null)
this.mediaPosition = null;
if (this.mediaControl != null)
this.mediaControl = null;
if (this.basicAudio != null)
this.basicAudio = null;
if (this.basicVideo != null)
this.basicVideo = null;
if (this.videoWindow != null)
this.videoWindow = null;
if (this.graphBuilder != null)
Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;
GC.Collect();
}
}
catch
{
}
}
private void HandleGraphEvent()//обработка событий при воспроизведении
{
int hr = 0;
EventCode evCode;
IntPtr evParam1, evParam2;
// Make sure that we don't access the media event interface
// after it has already been released.
if (this.mediaEventEx == null)
return;
// Process all queued events
while (this.mediaEventEx.GetEvent(out evCode, out evParam1, out evParam2, 0) == 0)
{
// Free memory associated with callback, since we're not using it
hr = this.mediaEventEx.FreeEventParams(evCode, evParam1, evParam2);
// If this is the end of the clip, reset to beginning
if (evCode == EventCode.Complete)
//если прекратилось воспроизведение
{
switch (playMode)
{
case PlayMode.RepeatAll:
{
//если воспроизводить все, запустить следующую композицию
nextButton_Click(null, null);
return;
}
case PlayMode.RepeatOne:
{
//если воспроизводить одну, запустить с начала
DsLong pos = new DsLong(0);
// Reset to first frame of movie
hr = this.mediaSeeking.SetPositions(pos, AMSeekingSeekingFlags.AbsolutePositioning,
null, AMSeekingSeekingFlags.NoPositioning);
if (hr < 0)
{
//выполняется, если не поддерживается премещение по времени
hr = this.mediaControl.Stop();
hr = this.mediaControl.Run();
}
break;
}
case PlayMode.RepeatNone:
{
//если воспроизводить список один раз
if (filesGrid.Rows.Count < 1)
{
CloseClip();
currentState = PlayState.Stopped;
SetTimeLabel(0, 0);
return;
}
foreach (DataGridViewCell cell in filesGrid.SelectedCells)
{
int n = cell.RowIndex;
n++;
if (n > filesGrid.Rows.Count - 1)
{
CloseClip();
currentState = PlayState.Stopped;
SetTimeLabel(0, 0);
return;
}
else
{
nextButton_Click(null, null);
return;
}
}
break;
}
}
}
}
}
protected override void WndProc(ref Message m)
{//обрабатываем события пришедшие к окну
switch (m.Msg)
{
case WMGraphNotify:
{
HandleGraphEvent();
break;
}
}
if (this.videoWindow != null)
this.videoWindow.NotifyOwnerMessage(m.HWnd, m.Msg, m.WParam, m.LParam);
base.WndProc(ref m);
}
void AddFiles(string[] files)
{//добавление файлов в список воспроизведения
CloseClip();
currentState = PlayState.Stopped;
foreach (string file in files)
{
object[] ob = new object[3];
ob[0] = Path.GetFileName(file);
OpenClip(file, false);
double s;
mediaPosition.get_Duration(out s);
DateTime ds = new DateTime();
ds = ds.AddSeconds(s);
CloseClip();
ob[1] = ds.ToLongTimeString();
ob[2] = file;
filesGrid.Rows.Add(ob);
}
}
private void filesGrid_DoubleClick(object sender, EventArgs e)
{
//воспроизвдение выбранного файла
CloseClip();
currentState = PlayState.Stopped;
if (filesGrid.Rows.Count < 1) return;
foreach (DataGridViewCell cell in filesGrid.SelectedCells)
{
OpenClip(filesGrid[2, cell.RowIndex].Value as string, true);
double s;
mediaPosition.get_Duration(out s);
DateTime ds = new DateTime();
ds = ds.AddSeconds(s);
filesGrid[1, cell.RowIndex].Value = ds.ToLongTimeString();
currentState = PlayState.Running;
currentPlay = filesGrid[0, cell.RowIndex].Value as string;
break;
}
pauseButton.Visible = true;
playButton.Visible = false;
}
private void position_MouseUp(object sender, MouseEventArgs e)
{
setPositionBar();
}
private void position_Scroll(object sender, EventArgs e)
{
setPositionBar();
}
private void setPositionBar()
{
if (mediaPosition == null)
{
if (!changeBarOnResize)
positionSize = (double)positionBar.Value / (double)positionBar.Maximum;
return;
}
if (changeBarOnResize) return;
double p;
mediaPosition.get_Duration(out p);
positionSize = (double)positionBar.Value / (double)positionBar.Maximum;
double t = p * positionSize;
mediaPosition.put_CurrentPosition(t);
SetTimeLabel(t, p);
}
private void SetTimeLabel(double currentTime, double maxTime)
{
DateTime ds1 = new DateTime();
ds1 = ds1.AddSeconds(currentTime);
DateTime ds2 = new DateTime();
ds2 = ds2.AddSeconds(maxTime);
string s= "Время: " + ds1.ToLongTimeString() + "\\" + ds2.ToLongTimeString();
switch (currentState)
{
case PlayState.Stopped: s += " | Остановлено"; currentPlay = ""; break;
case PlayState.Init: s += " | Остановлено"; break;
case PlayState.Running: s += " | Воспроизведение"; break;
case PlayState.Paused: s += " | Пауза"; break;
}
if (currentPlay != "")
{
s += " | " + currentPlay;
}
timeLabel.Text = s;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (mediaPosition == null) return;
double p;
mediaPosition.get_Duration(out p);
double t;
mediaPosition.get_CurrentPosition(out t);
int z = (int)(t / p * (double)positionBar.Maximum);
if (positionBar.Value != z) positionBar.Value = z;
SetTimeLabel(t, p);
}
private void controlPanel_SizeChanged(object sender, EventArgs e)
{
ResizeBar(volumeTrackBar,volumeSize);
ResizeBar(positionBar,positionSize);
}
bool changeBarOnResize = false;
double volumeSize = 1;
double positionSize = 0;
private void ResizeBar(TrackBar bar,double size)
{
changeBarOnResize = true;
if (bar.Location.X + 105 < controlPanel.Width)
{
bar.Width = controlPanel.Width - bar.Location.X - 5;
}
else
{
bar.Width = 100;
}
bar.Maximum = bar.Width;
bar.Value = (int)((double)bar.Maximum * size);
changeBarOnResize = false;
}
private void createNewСписокToolStripMenuItem_Click(object sender, EventArgs e)
{
filesGrid.Rows.Clear();
}
//сохраниенение списка воспроизведения
private void SaveList(string fileName)
{
StreamWriter stream = new StreamWriter(fileName);
int i, n = filesGrid.Rows.Count;
for (i = 0; i < n; i++)
{
stream.WriteLine(filesGrid[0, i].Value as string);
stream.WriteLine(filesGrid[1, i].Value as string);
stream.WriteLine(filesGrid[2, i].Value as string);
}
stream.Close();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveListFileDialog.ShowDialog() == DialogResult.Cancel) return;
SaveList(saveListFileDialog.FileName);
}
private void LoadList(string fileName)
{
try
{
StreamReader stream = new StreamReader(fileName);
while (!stream.EndOfStream)
{
object[] ob = new object[3];
ob[0] = stream.ReadLine();
ob[1] = stream.ReadLine();
ob[2] = stream.ReadLine();
filesGrid.Rows.Add(ob);
}
stream.Close();
}
catch
{ };
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
SaveList("currentPlay.rpl");
}
private void playButton_Click(object sender, EventArgs e)
{
if (currentState == PlayState.Paused)
{
int hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
currentState = PlayState.Running;
playButton.Visible = false;
pauseButton.Visible = true;
return;
}
filesGrid_DoubleClick(null, null);
}
private void pauseButton_Click(object sender, EventArgs e)
{
if (currentState != PlayState.Running) return;
int hr = this.mediaControl.Pause();
DsError.ThrowExceptionForHR(hr);
currentState = PlayState.Paused;
pauseButton.Visible = false;
playButton.Visible = true;
}
private void stopButton_Click(object sender, EventArgs e)
{
CloseClip();
currentState = PlayState.Stopped;
SetTimeLabel(0, 0);
}
private void nextButton_Click(object sender, EventArgs e)
{
if (filesGrid.Rows.Count < 1) return;
foreach (DataGridViewCell cell in filesGrid.SelectedCells)
{
int n = cell.RowIndex;
n++;
if (n > filesGrid.Rows.Count - 1) n = 0;
filesGrid.ClearSelection();
filesGrid.Rows[n].Selected = true;
if(currentState==PlayState.Paused || currentState==PlayState.Running)
filesGrid_DoubleClick(null, null);
break;
}
}
private void forwardButton_Click(object sender, EventArgs e)
{
if (filesGrid.Rows.Count < 1) return;
foreach (DataGridViewCell cell in filesGrid.SelectedCells)
{
int n = cell.RowIndex;
n--;
if (n < 0) n = filesGrid.Rows.Count - 1;
filesGrid.ClearSelection();
filesGrid.Rows[n].Selected = true;
if (currentState == PlayState.Paused || currentState == PlayState.Running)
filesGrid_DoubleClick(null, null);
break;
}
}
private void ResetStatusPlay()
{
repeatAllToolStripMenuItem.Checked = false;
repeatNoneToolStripMenuItem.Checked = false;
repeatOneToolStripMenuItem.Checked = false;
}
private void playingToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
ResetStatusPlay();
switch (playMode)
{
case PlayMode.RepeatAll: repeatAllToolStripMenuItem.Checked = true; break;
case PlayMode.RepeatNone: repeatNoneToolStripMenuItem.Checked = true; break;
case PlayMode.RepeatOne: repeatOneToolStripMenuItem.Checked = true; break;
}
}
private void repeatAllToolStripMenuItem_Click(object sender, EventArgs e)
{
playMode = PlayMode.RepeatAll;
}
private void repeatOneToolStripMenuItem_Click(object sender, EventArgs e)
{
playMode = PlayMode.RepeatOne;
}
private void repeatNoneToolStripMenuItem_Click(object sender, EventArgs e)
{
playMode = PlayMode.RepeatNone;
}
private void volumeTrackBar_Scroll(object sender, EventArgs e)
{
if (basicAudio == null)
{
if (!changeBarOnResize)
volumeSize = (double)volumeTrackBar.Value / (double)volumeTrackBar.Maximum;
return;
}
if (changeBarOnResize) return;
volumeSize = (double)volumeTrackBar.Value / (double)volumeTrackBar.Maximum;
int y = (int)((double)(VolumeSilence - VolumeFull) * (1-volumeSize));
basicAudio.put_Volume(y);
}
private void openListToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openListFileDialog.ShowDialog() == DialogResult.Cancel) return;
LoadList(openListFileDialog.FileName);
}
private void deleteButton_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in filesGrid.SelectedRows)
{
filesGrid.Rows.Remove(row);
}
}
private void upButton_Click(object sender, EventArgs e)
{
int minNum = filesGrid.Rows.Count;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (DataGridViewRow row in filesGrid.SelectedRows)
{
if (row.Index < minNum) minNum = row.Index;
rows.Add(row);
}
if (minNum < 1) return;
rows.Sort(new DataGridViewRowComparer());
int i,j, n = rows.Count,t;
object o;
bool s;
for (i = 0; i < n; i++)
{
t=rows[i].Index;
for(j=0;j<3;j++)
{
s = filesGrid[j, t - 1].Selected;
o = filesGrid[j, t - 1].Value;
filesGrid[j, t - 1].Value = filesGrid[j, t].Value;
filesGrid[j, t - 1].Selected = filesGrid[j, t].Selected;
filesGrid[j, t].Value = o;
filesGrid[j, t].Selected = s;
}
}
}
private void downButton_Click(object sender, EventArgs e)
{
int maxNum = 0;
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (DataGridViewRow row in filesGrid.SelectedRows)
{
if (row.Index > maxNum) maxNum = row.Index;
rows.Add(row);
}
if (maxNum >= filesGrid.Rows.Count - 1) return;
rows.Sort(new DataGridViewRowComparer());
int i, j, n = rows.Count, t;
object o;
bool s;
for (i = n - 1; i >= 0; i--)
{
t = rows[i].Index;
for (j = 0; j < 3; j++)
{
s = filesGrid[j, t + 1].Selected;
o = filesGrid[j, t + 1].Value;
filesGrid[j, t + 1].Value = filesGrid[j, t].Value;
filesGrid[j, t + 1].Selected = filesGrid[j, t].Selected;
filesGrid[j, t].Value = o;
filesGrid[j, t].Selected = s;
}
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
AboutForm form = new AboutForm();
form.ShowDialog();
}
private void AddFile_Click(object sender, EventArgs e)
{
if (addFilesOpenFileDialog.ShowDialog() == DialogResult.Cancel) return;
AddFiles(addFilesOpenFileDialog.FileNames);//добавляем файлы в список воспроизведния
}
}
}