Создание плеера на BASS |
nestby | Дата: Четверг, 20.08.2009, 00:15 | Сообщение # 1 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| Я пытаюсь разобраться в библиотеке Bass и паралельно пишу плеер (или его подобие:), видел плееры POGi и ZuBy, и меня очень интересуют следующие вопросы: 1.Как узнать битрейт mp3? то есть, kbps (например бывает 320, 128kbps думаю вы меня поняли) это реализовано например в плеере POGi. 2.Как cделать, чтобы в плейлисте (компонент ListBox) кроме названия выводилось еще и время каждого файла? ВОт это есть как в POGiMP так и ZuByMP плеерах. 3.Как сделать нормальный трекбар, чтобы форма движка и картинка была своя (графическая) а не как в TrackBar длинная вертикальная и серая. Я знаю что на этом сайте есть те кто могут подсказать, подскажите пожалста!!! все это делается естественно в Delphi.
|
|
| |
|
Admin | Дата: Четверг, 20.08.2009, 09:10 | Сообщение # 2 |
Ранг 10
Группа: Пользователи
Сообщений: 1268
Награды: 16
Репутация: 2
Статус: Offline
| Quote (nestby) 3.Как сделать нормальный трекбар, чтобы форма движка и картинка была своя (графическая) а не как в TrackBar длинная вертикальная и серая. Вот из-за этого и не нравится мне GDI. После того как перешел на C# а точнее WPF такие проблемы отпали. Все это можно реализовать непребигая ни к единой строчке кода. А вообще, я давно както делал так: Кидал Image (это фон трекбара). Дальше кидал на него уже маленький Image (это уже за че таскать). Ну а дальше зная позиции, через простые формулы, на основе вычисления процентов текущего положения воспроизведения файла, от максимальной длины (не путать с пикселями, это через BASS можно узнать). Вобщем узнавал % который сейчас воспроизводится. Далее делал обратную операцию но уже с пикселями, и узнавал конкретную позицию. Ну вобщем это просто, главное понять. Формулы получил рисуя на листочке и брал круглые цифры (1000 - вся длина трека, а 200 это текущая поз. воспроизведения) На остальные вопросы попробую ответить чуть позже - сейчас некогда, там нужно смотреть сам BASS. И еще, зачем так крупно делать тему??? Переименовано. Тема должна содержать тематику основной проблемы
Не оказываю помощь через личные сообщения и ICQ
|
|
| |
|
nestby | Дата: Четверг, 20.08.2009, 11:09 | Сообщение # 3 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| спасибо большое, за один из ответов, и конечно, хорошо было б с формулами.., или исходничек, просто я тоже когда-то хотел так сделать, но тогда я еще с Bass не работал и у меня ничего не получилось. Но это конечно не самый важный вопрос, и тему я так крупно создал, потому что очень нужны ответы на эти вопросы, без них дальше никак. Пожалста, если будет время нужно, первые два вопроса !!! (И к стати, сколько рылся в документации Bass ничего про битрейт (качество и kbps) не нашел, есть только выдает в килогерцах, там например 44100, вот, а нужно именно kbps.
|
|
| |
|
Admin | Дата: Четверг, 20.08.2009, 14:02 | Сообщение # 4 |
Ранг 10
Группа: Пользователи
Сообщений: 1268
Награды: 16
Репутация: 2
Статус: Offline
| Вот набросал небольшой рисуночек, примерно также я рисовал на листочке, когда все это выдумывал. Итак, исходные данные которые ты сможеш без труда получить это длинна файла, и позиция воспроизведения файла. Также ты знаеш ширину своего трекбара. Допустим под переменными скрываются значения которые на рисунке. Первым делом нужно найти процент который воспроизведен. Из значений это видно - это 20%, но теперь нужно найти формулу. Начинаем придумывать. Открываем калькулятор и вперед. Получилось следующее: (200 / 1000)*100 = 20% Теперь подставляем переменные: Procent := (PosFile / LFile)*100 Теперь все легко и очевидно, чтобы найти координату бегунка, нужно найти 20% от 100 px. Это и будет 20px. Т.е. нужно установить ползунок в координаты 20px. Формулу выведеш сам. Не все же на блюдечке с голубой коемочкой подностить, а так будет толк, когда сам додумаешся! Ну и всякие смещения от края формы тоже сделаеш, не сложно. С 1 и 2 вопросом чуть попозже, пока нету времени. Думаю все понятно разъяснил.
Не оказываю помощь через личные сообщения и ICQ
|
|
| |
|
ZuBy | Дата: Суббота, 22.08.2009, 13:45 | Сообщение # 5 |
Ранг 5
Группа: Проверенные
Сообщений: 118
Награды: 2
Репутация: 2
Статус: Offline
| вот так быстро получаем kbps. Code function GetKBPS(Channel: DWORD): integer; var FloatLen: FLOAT; Length: Int64; len: DWORD; begin Length:= 0; Length:= BASS_ChannelGetLength(Channel, BASS_POS_BYTE);
if Length < 0 then Length:= 0; FloatLen:= BASS_ChannelBytes2Seconds(Channel, Length); len:=BASS_StreamGetFilePosition(Channel, BASS_FILEPOS_END); Result:= Round(len / (125 * FloatLen) + 0.5); end; Добавлено (20.08.2009, 15:53) ---------------------------------------------
Quote (nestby) 2.Как cделать, чтобы в плейлисте (компонент ListBox) кроме названия выводилось еще и время каждого файла? ВОт это есть как в POGiMP так и ZuByMP плеерах. Code var time:string; begin /// например можно узнать при помощи второго канала.. 1. создание канала 2. выполнение действии с потоком, тут узнаем полное время трека и вписываем его в time 3. освобождаем поток end; выводишь при помощи TextOut(rect.right-length(time)-10, rect.top, time); это всё при отрисовке drawitem и со стилем lbownerdrawfixedДобавлено (20.08.2009, 15:59) ---------------------------------------------
Quote (nestby) 3.Как сделать нормальный трекбар, чтобы форма движка и картинка была своя (графическая) а не как в TrackBar длинная вертикальная и серая то что привел Admin, очень хорошии пример. но можно всё это рисовать как в ZuByMP, и пример полностью показан в Demo от bass в папке CustomLoop. как разберёшся, так и сделаешь )) выкидывай все ненужные и оп-аля получается замечательная полоса прокрутки. а тут уже на твою фантазию. Добавлено (22.08.2009, 13:45) ---------------------------------------------
Quote (ZuBy) 3.Как сделать нормальный трекбар, чтобы форма движка и картинка была своя (графическая) а не как в TrackBar длинная вертикальная и серая если ты новичек, то используй скин движки для красоты, а если сможешь написать свой скин движок, то у тебя по дизайну все проблемы отпадут.
http://www.zubymplayer.com
|
|
| |
|
nestby | Дата: Суббота, 22.08.2009, 22:29 | Сообщение # 6 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| Спасибо всем за ответы!!! Я бы очень хотел написать скин движок, но не знаю что для этого нужно. Как узнать handle или что там трек бара чтобы загрузить в него рисунки со скина, но это второстепенное. Вот на счет своего трекбара как посоветовал Admin, это стоит попробовать. Спаисбо за функцию kbps, уже нашел)), а вот на счет листбокса, я так совсем и не понял, TextOut - это функция ListBox'a или что (делфи под рукой нет)? И в плеерах типа Aimp данные в Листбокс выводятся сразу при загрузке файлов, а я их загружаю вот так: [CODE] for i:=0 to opendialog1.Files.Count-1 do begin ListBox1.Items.Add(ExtractFileName(OpenDialog1.Files.Strings[i])); end; [/CODE] и в итоге если загрузить файлы из одной папки, а потом еще из другой, то файлы из предыдущей не воспроизводятся помогите сделать правильно, пожалуйста!
|
|
| |
|
Admin | Дата: Воскресенье, 23.08.2009, 08:13 | Сообщение # 7 |
Ранг 10
Группа: Пользователи
Сообщений: 1268
Награды: 16
Репутация: 2
Статус: Offline
| TextOut это функция, а вроде даже и процедура (помойму ничего не возвращает), которая вырисовывает на канве текст. Это метод TCanvas. А насчет вывода, попробуй в перед End написать Application.ProcessMessages; Вроде бы так пишется, но если ошибка то из списка найдеш.
Не оказываю помощь через личные сообщения и ICQ
|
|
| |
|
nestby | Дата: Воскресенье, 23.08.2009, 17:24 | Сообщение # 8 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| Quote (Admin) TextOut это функция, а вроде даже и процедура (помойму ничего не возвращает), которая вырисовывает на канве текст. Это метод TCanvas. А насчет вывода, попробуй в перед End написать Application.ProcessMessages; Вроде бы так пишется, но если ошибка то из списка найдеш. А как же сделать чтоб время выводилось не на канве, а в плейлисте, рядом с именем файла ( с правой стороны)? Добавлено (23.08.2009, 17:24) --------------------------------------------- Все, нашел событие у ListBox OnDrawItem и сделал все с TextOut'ом, и мне не хочет компилить прогу, пишет: Incompatible types: 'Integer' and 'String'. Уже как не пробую не получается!
|
|
| |
|
Admin | Дата: Воскресенье, 23.08.2009, 22:14 | Сообщение # 9 |
Ранг 10
Группа: Пользователи
Сообщений: 1268
Награды: 16
Репутация: 2
Статус: Offline
| Картинки в ListBox посмотри это, там есть этот TextOut. Да и картинки выводятся.
Не оказываю помощь через личные сообщения и ICQ
|
|
| |
|
defaultNick5302 | Дата: Понедельник, 24.08.2009, 19:42 | Сообщение # 10 |
Ранг 1
Группа: Пользователи
Сообщений: 1
Награды: 0
Репутация: 0
Статус: Offline
| Хорошо, надо будет глянуть, если заработает, будет прикольно. Конечно лучший вориант - это исходничек с этим самым плейлистом..
|
|
| |
|
ZuBy | Дата: Вторник, 25.08.2009, 16:28 | Сообщение # 11 |
Ранг 5
Группа: Проверенные
Сообщений: 118
Награды: 2
Репутация: 2
Статус: Offline
| Quote (nestby) Code for i:=0 to opendialog1.Files.Count-1 do begin ListBox1.Items.Add(ExtractFileName(OpenDialog1.Files.Strings[i])); end; и в итоге если загрузить файлы из одной папки, а потом еще из другой, то файлы из предыдущей не воспроизводятся помогите сделать правильно, пожалуйста! ты просто добавляй вот так ListBox1.Items.Add(OpenDialog1.Files[i]); Application.processmessages тут не нужен. делается это так если хочешь чтобы много файлов грузилось за меньшее время Listbox1.items.beginupdate try ListBox1.Items.Add(OpenDialog1.Files[i]); finally listbox1.items.endupdate; end; Quote (defaultNick5302) Хорошо, надо будет глянуть, если заработает, будет прикольно. Конечно лучший вориант - это исходничек с этим самым плейлистом.. вот небольшой примерчик как сделать фиксированный и выделенный цвет. Code with (control as TListBox).canvas do begin if (State = [odFocused, odSelected]) or (State = [odSelected]) then begin Font.Color := clBlack; Font.Size := 9; Brush.Style := bsClear; SetBkMode(ListBox1.canvas.Handle, TRANSPARENT); TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + extractfilename(changefileext(Items[index], ''))); // вот пример как правильно выводится TextOut. в нем выводится название файла без расширения. end else if IDPlay = Index then //IDPlay это переменная типа integer в которой находится номер трека который щас играет... begin Font.Color := clBlue; Font.Size := 9; Brush.Style := bsClear; Pen.Color := clLtGray; Rectangle(Rect); SetBkMode(Item.Handle, TRANSPARENT); TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + extractfilename(changefileext(Items[index], ''))); end else begin Font.Color := clLtGray; Brush.Style := bsClear; Font.Size := 9; SetBkMode(Item.Handle, TRANSPARENT); TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + extractfilename(changefileext(Items[index], ''))); end; end; думаю все понятно Добавлено (25.08.2009, 16:28) --------------------------------------------- если ошибки будут исправляй сам большинство по памяти писал.
http://www.zubymplayer.com
|
|
| |
|
nestby | Дата: Пятница, 28.08.2009, 00:29 | Сообщение # 12 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| Zuby, пасиба, надо будет разобраться, вот только ListBox1.Items.Add(OpenDialog1.Files[i]); это же тоже самое что ListBox1.Items.Add(ExtractFileName(OpenDialog1.Files.Strings[i])); только без ExtractFileName вот в этом вся зацепка, мне нужно чтобы в плейлист выводились не пути к файлам, а названия файлов, которая функция ExtractFileName и делает, только вот из-за нее нельзя загружать еще файла с другой папки. Может попробовать сделать с двумя ListBox ами? В один будет вбиваться путь а в другой имя файла. Хотя на самом деле я хочу чтобы в плейлист загружалась инфа из тегов, тоесть Artist и Title а не названия файлов. То есть надо создать процедуру которая при открытии файлов будет читать с ниг эти теги и загружать их в листбокс. Вот это нужно!!! Вот в плеере ZubyMP да и в других (напр. Aimp, Winamp) это происходит!! Только бы примерчик этой процедуры..)) //P.S. извиняюсь за предыдущий ник, не так немного вошел)). Добавлено (28.08.2009, 00:29) --------------------------------------------- И еще, попробовал предыдущий пример для ListBox и у меня выбивает ошибку при открытии файлов. В кнопке открытия файлов я пишу: ListBox1.Items.Add(OpenDialog1.Files[i]); А в событии листбокса On DrawItem - код который был приведен Zuby. Я правильно делаю, или нет (??), потому что постоянно выбивает ошибку при открытии файлов. у листбокса свойство Style естесственно IbOwnerDrawFixed.
|
|
| |
|
Admin | Дата: Пятница, 28.08.2009, 11:24 | Сообщение # 13 |
Ранг 10
Группа: Пользователи
Сообщений: 1268
Награды: 16
Репутация: 2
Статус: Offline
| Quote (nestby) Может попробовать сделать с двумя ListBox ами? В один будет вбиваться путь а в другой имя файла. Ну да, я так делал в далеком прошлом, но это сильно извращенный способ. Используй TStringList Quote (nestby) И еще, попробовал предыдущий пример для ListBox и у меня выбивает ошибку при открытии файлов. Вот так нужно: Code procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin if OpenDialog1.Execute then begin for i:=0 to OpenDialog1.Files.Count-1 do ListBox1.Items.Add(OpenDialog1.Files[i]) end; end; И еще не забудь сделать возможным выбор нескольких файлов в диалоге
Не оказываю помощь через личные сообщения и ICQ
|
|
| |
|
ZuBy | Дата: Пятница, 28.08.2009, 15:01 | Сообщение # 14 |
Ранг 5
Группа: Проверенные
Сообщений: 118
Награды: 2
Репутация: 2
Статус: Offline
| Quote (ZuBy) Zuby, пасиба, надо будет разобраться, вот только ListBox1.Items.Add(OpenDialog1.Files[i]); это же тоже самое что ListBox1.Items.Add(ExtractFileName(OpenDialog1.Files.Strings[i])); только без ExtractFileName вот в этом вся зацепка, мне нужно чтобы в плейлист выводились не пути к файлам, а названия файлов, которая функция ExtractFileName и делает, только вот из-за нее нельзя загружать еще файла с другой папки. это всё будет делать отрисовка. не надо 2 ListBox'а, я привел пример как у меня было в старом плеере, так всё работает... используй дополнение от Admin'a и отрисовку ListBox от меня и всё будет как ты хочешь... Quote (nestby) Хотя на самом деле я хочу чтобы в плейлист загружалась инфа из тегов, тоесть Artist и Title а не названия файлов. То есть надо создать процедуру которая при открытии файлов будет читать с ниг эти теги и загружать их в листбокс. Вот это нужно!!! Вот в плеере ZuByMP да и в других (напр. Aimp, Winamp) это происходит!! Только бы примерчик этой процедуры..)) а вот насчет этого могу подсказать, но примерчик не дам)) делается это так: 1. создать функцию которая будет вытаскивать теги из файлов. вытаскивать можно из id3v1, id3v2 - это для mp3 файлов, соответственно из других форматов, другие "модули" тегов. в интернете много информации о тегах, почитай, скачай и пользуйся. 2. в отрисовке ListBox, заменить эту строчку Code TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + extractfilename(changefileext(Items[index], ''))); на вот такую Code TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + GetTagFromFile(Items[index]))); Удачи! Работы много ))
http://www.zubymplayer.com
Сообщение отредактировал ZuBy - Пятница, 28.08.2009, 15:05 |
|
| |
|
nestby | Дата: Понедельник, 21.09.2009, 18:06 | Сообщение # 15 |
Ранг 1
Группа: Проверенные
Сообщений: 14
Награды: 0
Репутация: 0
Статус: Offline
| Ладно, спасибо, буду разбираться ) Добавлено (21.09.2009, 18:06) --------------------------------------------- Получилась наконец, отрисовка! Только вот теперь при загрузке файлов оно загружает в листбокс данное кол-во файлов, отображает их номера, только не хочет их воспроизводить . При отрисовке я использовал предыдущий пример про фиксированный и выделенный цвет. Только вот теперь функция отвечающая за воспроизведение видимо не может найти путь к файлу, потому что загружаю файл так: if OpenDialog1.Execute then begin for i:=0 to OpenDialog1.Files.Count-1 do ListBox1.Items.Add(OpenDialog1.Files[i]) end; в отрисовке участвует функция TextOut(Rect.Left + 2, Rect.Top, IntToStr(Index + 1) + '. ' + GetTag(Items[index]))); (GetTag вытаскивает теги). а в даблклилке у листбокса у меня Form1.Play; В этой процедуре и должен воспроизводиться файл. А там такой код: filename:= ListBox1.Items[ListBox1.itemIndex]; case ChannelType of ctMusic: BASS_MusicFree(Channel); ctStream: BASS_StreamFree(Channel); end; Channel:= BASS_StreamCreateFile(False, PChar(FileName), 0, 0, 0); ну и дальше как обычно. Короче как же сделать чтоб в плейлист выводило теги, но при клике воспроизводился сам файл т.к. его путь?
|
|
| |
|