Разборы кода (Дали код? Скажи спасибо и пойди выучи и разберись как он работает. )
Заметки кажущиеся на данном этапе полезными.
Описание пройденного материала своими словами для лучшего усваивания и возможности получить замечание, от мимо проходивших специалистов.
Заметки кажущиеся на данном этапе полезными.
Описание пройденного материала своими словами для лучшего усваивания и возможности получить замечание, от мимо проходивших специалистов.
Фоновая музыка в приложении WinForms. Разбор кода.
Запись от Leshakk размещена 13.04.2022 в 16:43
Показов 2478
Комментарии 4
|
Разбор кода в учебных целях. Добрый день. Для практики делал игру "пятнашки" в WinForms, коими полон интернет. Ну и захотелось, чтобы еще играла любимая музыка. Несколько треков по кругу. И значит чтобы были кнопки play, stop, и регулятор громкости. Вроде сделал. Но как-то коряво. И если нажимаешь на Плей, то играет следующая песня, а если ничего не нажимать, то песня заканчивается и тишина, надо опять нажимать. В этой теме: Создать плеер хотя бы с кнопкой "открыть" "играть" и с TrackBar для проигрывания mp3, Уважаемый I can дал код, который сразу заработал, и заработал так как и было нужно. И поскольку проект был учебным. Хотелось бы не просто скопипастить код, а разобрать его устройство. Получить знания так сказать. Если вы, дорогой читатель, изучаете C# более чем 2 месяца, то наврядли вам тут будет интересно. Но вы можете поправить, или подсказать. И за это зараннее спасибо. Вот сам код: Кликните здесь для просмотра всего текста
Итак: ⚫ this.timer1.Tick += new System.EventHandler(this.timer1_Tick); На первый нубовзгляд эта строчка, напоминает создание обьекта класса, но во первых нет переменной, куда записывается экземпляр класса. Во вторых, зачем вместо = написано +=? Такого мы еще не проходили. Идем в гугл копать. И находим там страшные, ужасные доселе неведомые....События!!! И.....ДЕЛЕГАТЫ!!! Что там в гугле про События и делегаты...много чего..Ссылки копировать нельзя, а обьяснить сложно,особенно, когда сам не понял... timer1.Tick это событие += это подписка на событие........................или нет......... Можно интуитивно предположить следующее: метод this.timer1_Tick подписан на событие this.timer1.Tick таймер запускается при нажатии кнопки плей, и начинает тикать. И каждые 100милисекунд ( можно любое значение, но сейчас вот 100мс) выполняется метод - обработчик события: timer1_Tick. private void timer1_Tick(object sender, EventArgs e) { Text = WMP.status.ToString(); if (Text == "Остановлено") button_Play_Click(null,null); } Этот метод говорит: Давайте-ка запишем в виртуальный Текст статус плеера, а потом проверим его, и если плеер имеет статус "Остановлено", то давайте нажмем кнопку плей еще раз. А если нет статуса "Остановлено" то ничего делать не будет. И так каждые 100мс, пока играет музыка. И если в очередной раз выяснится что статус "Остановлено" появился,а он появится когда трек закончится, то метод сбросит кнопку плей командой button_Play_Click(null,null) и все повторится. Такой своего рода цикл по рандомизации песен, их проигрыванию, и с проверкой статуса плеера с заданным интервалом. То есть, если установить, например в свойствах таймера 24 часа, то рандомная песня будет играть раз в сутки. Остановить это все, можно кнопкой стоп. ⚫ private void button_Stop_Click(object sender, EventArgs e) { WMP.controls.stop(); timer1.Stop(); Text = ""; } Это кнопка стоп, точнее метод-обработчик события: останавливает проигрывание, останавливает таймер, и очищает виртуальный текст от записаного туда статуса плеера. ⚫ public WMPLib.WindowsMediaPlayer WMP = new WMPLib.WindowsMediaPlayer(); Создание экземпляра класса WMPLib.WindowsMediaPlayer, странный конечно класс, но по ситаксису, таки-да, это экземпляр класса. И записывается он в переменную - обьект WMP. ⚫ private void button_Play_Click(object sender, EventArgs e) Эта фигня сама создается, когда на форму заносишь кнопку и кликаешь на нее два раза. Официальный тутор говорит что это: "Обработчик событий — это метод, привязанный к событию. При возникновении события выполняется код в обработчике событий. " Короче нажали кнопку, выполнился код который в фигурных скобках. Random dise = new Random(); string[] a = System.IO.Directory.GetFiles(Application .StartupPath, "*.wav"); WMP.URL = a[dise.Next(0, a.Length)]; trackBar1.Value = 5; WMP.settings.volume = trackBar1.Value * 10; timer1.Start(); Ну наконец-то, хоть какие то знакомые слова! Random dise = new Random(); проходили! Тут короче стандартная процедура, создание экземпляра класса, запись его в новый обьект dise Kласс рандом, выдает случайные числа в заданном диапазоне посредством метода Next и принимаемых им параметров ⚫ string[] a = System.IO.Directory.GetFiles(Application .StartupPath, "*.wav"); Здесь объявлен и проинициализирован строковый массив и в него записаны все песни в формате wav которые лежат.... ⚫ System.IO.Directory.GetFiles(Application .StartupPath, "*.wav") Это значит так: System.IO.Directory.GetFiles ==Возвращает имена файлов, соответствующих указанным критериям Application.StartupPath ==путь для исполняемого файла, запустившего приложение, не включая исполняемое имя. "*.wav" == звуковой формат. Короче надо пойти туда, где лежит исполняемый файл, найти и собрать имена всех WAVок, и записать их в массив string[] a ⚫ WMP.URL = a[dise.Next(0, a.Length)]; Гугл находит только URL и говорит что это свойство, но там непонятно все. Наверное это как в пословице : Понять это невозможно, это можно только запомнить!!! Поэтому запомним что URL это адрес (локация, местонахождение) для чего-то. Если попытаться обьяснить своими словами то объект WMP не знает где брать песню, для того чтобы ему это как-то обьяснить, надо наделить его свойством, умением разбираться в картах и навигации. Этим свойством его наделяет URL. А затем треки записваются в массив, и скормливаются, плееру, любым способом читающим массив. Просто так приписать WMP.URL = a; не сработает потому что плеер не будет знать какую именно песню из всего массива брать и играть. И только когда метод Next a[dise.Next(0, a.Length)] выберет рандомную песню , одну, определенную, и даст ее Плееру, тогда он наконец ее захавает. Надо кстати для практики попробовать другие способы обработки массива, например последовательное проигрывание всего массива, или через одну песню, или исключить песни с цифрой 2 в названии. Чисто поугорать для тренировки. Но это потом. ⚫ trackBar1.Value = 5; WMP.settings.volume = trackBar1.Value * 10; Это громкость звука. Школа трекбара по умолчанию имеет 10 делений. А громкость Медиаплеера по умолчанию 0 - 100. И значит здесь при старте, ползунок трекбара станет на 5,а громкость 5 * 10 будет 50. Короче по умолчанию будет по серединке, а там уже регулировать. ⚫ timer1.Start(); Ну тут уже понятно, уже разобрали, старт таймера. Остался вопрос, берется статус "Остановлено" почему он на русском? Почему не стоп и не stop, какие еще бывают статусы и где их найти. Гуглил-не нашел. Точнее нашел на английском Stop, а на русском нигде не пошел. Это "Остановлено" совсем уже замучило свой загадочностью. | |||||
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 4
Комментарии
-
Уважаемые читатели, если кто забредет сюда, поправьте пожалуйста, что не так. Хотелось бы довести это до ума, не только в тексте но и в голове.Запись от Leshakk размещена 13.04.2022 в 16:46
-
Попробую пояснить некоторые моменты (в которых разобрался сам) и внести изменения/дополнения:
● с таймером можно поступить проще - кинуть на форму из панели элементов "Компоненты" таймер. Тогда можно будет пока пропустить изучение делегатов и т.п. Все свойства и задания на обработку событий можно будет изменять на панели "Свойства".
● с trackBar1 можно поступить проще - изменить в свойства максимальное значение на 100, тогда ничего умножать не надо будет.
● WMP.URL - указываем, какой файл проигрывать. Запоминать ничего не надо. Свойство всеядно - понимает как локальные аудиофайлы, так и стримы/онлайнрадио с интернета. Естественно, желательно, придерживаться правил указания абсолютных путей к файлам.
● Список файлов тоже можно изменить - WMP прекрасно воспроизводит почти все известные форматы аудио/видео а не только *.WAV. Удобнее заранее накидать в определённую папку (например "MEDIA") нужные файлы wav, mp3, midi, ogg... и просто весь список без разбора закидывать в плейлист.
● ещё насчёт таймера. Если не нужна позиция проигрывания и т.п., то он и не нужен. У WMPLib есть событие PlayStateChange, в котором он передаёт индекс нового состояния плеера. Всего их 13 (здесь они перечислены). А статус "Остановлено" получается при преобразовании перечисления состояний в строку на русифицированной системе.
Для задания обработки события изменения состояния можно так поступить - написать процедуру, например:
А после объявления переменной WMP указать на этот обработчик:C# 1 2 3 4
private void WMP_PlayStateChange(int NewState) { // здесь и будет обрабатываться событие изменения состояния }
Для примера отсюда у меня была такая обработка:C# 1
WMP.PlayStateChange += WMP_PlayStateChange;
C# 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
private void WMP_PlayStateChange(int NewState) { // изменение состояния плеера if (NewState == (int)WMPPlayState.wmppsMediaEnded) { // по окончанию воспроизведения на следующий, если не последний if (currtrack < listTracks.Items.Count - 1) { listTracks.SelectedIndex++; WMP.URL = ""; } else { btn_stop.PerformClick(); } } if (NewState == (int)WMPPlayState.wmppsReady) { // если состояние готовности и программа воспроизводит, нажимаем кнопку PLAY if (flg_play) btn_play.PerformClick(); } if (NewState == (int)WMPPlayState.wmppsPlaying) { // если начал воспроизведение, считываем продолжительность трека и запускаем таймер lbl_duration.Text = ToTime(WMP.currentMedia.duration); timer1.Start(); currplay = currtrack; } if (NewState == (int)WMPPlayState.wmppsStopped) { // если останавливается, то и таймер стоп timer1.Stop(); } StatusLabel1.Text = status[NewState]; }
Запись от roach1967 размещена 14.04.2022 в 15:54
-
Уххх! Спасибо!!! Буду разбираться.Запись от Leshakk размещена 14.04.2022 в 18:22
-
А вот про статусы прям обидно и стыдно. Рылся основательно в этом плеере и не нашел. Спасибо что ткнули носом.
currentStateLabel.Text = "Stopped"; Вот же он! В переводе на русский "Остановлено", да.
Спасибо еще раз!Запись от Leshakk размещена 15.04.2022 в 10:40


