Как работать с плейлистом в delphi на библиотеке BASS.DLL?
|
|
xaramamburu | Дата: Понедельник, 28.05.2012, 10:49 | Сообщение # 31 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF,
Code procedure TForm1.Button2Click(Sender: TObject); begin SetLength(TS, Length(TS) + 1); TS[High(TS)] := TTabSheet.Create(PageControl1); TS[High(TS)].PageControl := PageControl1; TS[High(TS)].Caption := 'Вкладка номер: ' + IntToStr(High(TS) + 1); SetLength(List, Length(List) + 1); List[High(List)] := TListBox.Create(TS[High(TS)]); List[High(List)].Parent := TS[High(TS)]; List[High(List)].Align := alClient; List[High(List)].onDrawItem := DrawItem; List[High(List)].Style:=lbOwnerDrawFixed; end;
procedure TForm1.DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); const W = 16; H = 16; begin with (Control as TListBox).Canvas do FillRect(Rect); with (control as Tlistbox).canvas do begin Font.Color := clGray; Font.Size := 9; Brush.Style := bsClear; Brush.Color := clGray; SetBkMode((control as tlistbox).canvas.Handle, TRANSPARENT); TextOut(Rect.Left+w, Rect.Top,'Текст отрисовки'); end; end;
|
|
| |
Filo$oF | Дата: Понедельник, 28.05.2012, 13:32 | Сообщение # 32 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| А как в данном случае, чтобы для каждой строки выводился свой текст?
Я пробовал так: Code TextOut(Rect.Left+w, Rect.Top, Edit1.Text((control as tlistbox).Items[index]);
Но пишет "Missing operator or semicolon".
И почему-то нельзя задать действие для динамического listbox'а onClick, т.е. Если я создаю процедуру
Code procedure TForm1.ListBoxAdd(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin (Sender as tlistbox).Items.Add(Edit1.Text); end;
И добавляю в этот код:
Code procedure TForm1.Button2Click(Sender: TObject); begin SetLength(TS, Length(TS) + 1); TS[High(TS)] := TTabSheet.Create(PageControl1); TS[High(TS)].PageControl := PageControl1; TS[High(TS)].Caption := 'Вкладка номер: ' + IntToStr(High(TS) + 1); SetLength(List, Length(List) + 1); List[High(List)] := TListBox.Create(TS[High(TS)]); List[High(List)].Parent := TS[High(TS)]; List[High(List)].Align := alClient; List[High(List)].onDrawItem := DrawItem; List[High(List)].Style:=lbOwnerDrawFixed; end;
строку Code List[High(List)].OnClick:= ListBoxAdd;
то пишет "Incompatible types: "Parameter lists differ""
Но событие OnMouseDown работает нормально.
|
|
| |
xaramamburu | Дата: Понедельник, 28.05.2012, 15:19 | Сообщение # 33 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, Чтобы в каждой строке писался свой текст нужно выводить в каждую строку свой текст. Например вывод номера песни. Code TextOut(Rect.Left+w, Rect.Top,IntToStr(Index+1)+'. ');
И исправьте заголовок процедуры OnClick на:
Code procedure TForm1.ListBoxAdd(Sender: TObject);
|
|
| |
Filo$oF | Дата: Понедельник, 28.05.2012, 17:41 | Сообщение # 34 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| Всё ровно текст один и тот же... Может я что-то не так понял?
|
|
| |
xaramamburu | Дата: Понедельник, 28.05.2012, 17:52 | Сообщение # 35 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, У вас сейчас и будет текст один и тот же, потому что вы читаете его из Edit1 и ListBox будет выводить текст, который там записан в каждой строчке. Когда вы будите читать теги песен в зависимости от пути к песне, записанной в ListBox то и текст отрисовки будет разный.
|
|
| |
Filo$oF | Дата: Понедельник, 28.05.2012, 22:18 | Сообщение # 36 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| xaramamburu Спасибо:) Разобрался и с добавлением файлов и с отрисовкой.
Только ещё вопрос, как проиграть песню из динамического listbox'a на даблклик и переход на следующую песню в этом listbox'е даже если он не активен?
Я пробовал создать такую процедуру: Code procedure TForm_player.dbClicked(Sender: TObject); begin i:=List[High(List)].Itemindex; Filename:=List[High(List)].Items.Strings[i]; mode:=stop; player; ZMRunString1._Caption := '.:: ' +ChannelGetTagTitle(Channel)+ ' :: ' +ChannelGetTagArtist(Channel)+ ' :: ' + ExtractFileExt(FileName) + '::.'; end;
и так тоже пробовал:
Code procedure TForm_player.dbClicked(Sender: TObject); begin i:=(control as TRzListBox).Itemindex; Filename:=(control as TRzListBox).Items.Strings[i]; mode:=stop; player; ZMRunString1._Caption := '.:: ' +ChannelGetTagTitle(Channel)+ ' :: ' +ChannelGetTagArtist(Channel)+ ' :: ' + ExtractFileExt(FileName) + '::.'; end;
и вызывал так: Code List[High(List)].onDblClick := dbClicked;
Только он не срабатывает. Хотя даже в отдельной программе, событие onClick и onDblClick у меня не работает, даже если пишу так, как вы указали выше.Добавлено (28.05.2012, 21:59) --------------------------------------------- А, всё, извините, разобрался в чём дело
Только вот с переходом на следующий трек пока не понятно. Добавлено (28.05.2012, 22:18) --------------------------------------------- С этим тоже разобрался, круто выходит
Спасибо за уроки и помощь!
|
|
| |
xaramamburu | Дата: Понедельник, 28.05.2012, 23:03 | Сообщение # 37 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, Мог бы и решение выложить, раз уж начал эту тему.))))))
|
|
| |
Filo$oF | Дата: Вторник, 29.05.2012, 21:35 | Сообщение # 38 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| Если нужно создать вкладки во время работы приложения, то обрабатываю даблклик по RzPageControl
Quote begin SetLength(TS, Length(TS) + 1); TS[High(TS)] := TRzTabSheet.Create(RzPageControl1); TS[High(TS)].PageControl := RzPageControl1; TS[High(TS)].Caption := 'Defaul'; SetLength(List, Length(List) + 1); List[High(List)] := TRzListBox.Create(TS[High(TS)]); List[High(List)].Parent := TS[High(TS)]; List[High(List)].Align := alClient; List[High(List)].Style:=lbOwnerDrawFixed; List[High(List)].BorderStyle:=bsNone; List[High(List)].Color := clActiveCaption; RzPageControl1.ActivePage:=TS[High(TS)]; List[High(List)].ShowItemHints := False; List[High(List)].onDrawItem := DrawItem; List[High(List)].onDblClick := dbClicked; end;
Где строка Code List[High(List)].onDblClick := dbClicked;
Это процедура:
Code procedure TForm_player.dbClicked(Sender: TObject); begin i:=(Sender as TRzListBox).Itemindex; Filename:=(Sender as TRzListBox).Items.Strings[i]; mode:=stop; player; end;
А чтобы все остальные события работали для активных вкладок, просто везде ListBox1 заменил на List[High(List)].
Всё вполне работает. Песни перелистываются автоматически и кнопками.Файлы добавляются в активный listbox, как через кнопку, так и методом draganddrop.
Только у меня теперь к вам ещё несколько вопросов Как можно сохранить вкладки и listbox'ы с файлами в ini? Нашёл только как сохранять вкладки... Как можно узнать вес каждого файла загруженного в listbox и как подсчитать общее время всех файлов в listbox и вывести в edit?
И самый главный вопрос над которым я давно ломаю голову, как вычислить kHz ? С kbps разобрался, а вот про kHz даже найти ничего не могу.
Если можете то подскажите или натолкните на мысль, а дальше я как-нибудь соображу Добавлено (29.05.2012, 21:35) --------------------------------------------- Поторопился я с выводами. Заметил проблемму, что если создать два плейлиста, то начиная работать с вторым, другой становиться абсолютно недоступным...
Сообщение отредактировал Filo$oF - Вторник, 29.05.2012, 21:04 |
|
| |
xaramamburu | Дата: Среда, 30.05.2012, 15:57 | Сообщение # 39 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, По частоте дискретизации KHz и kbps вот нашел функции, правда не проверял: Код function KhzToStr: string; var H: Extended; bi: BASS_CHANNELINFO; begin BASS_ChannelGetInfo(Channel, bi); H := bi.freq / 1000; Result := IntToStr(Round(H)) + ' KHz'; end;
Код 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;
По работе со вкладками накидал пример: mp3 плеер с динамически создаваемыми вкладками для плейлистов Правда есть проблема, которую я так и не решил. Это уменьшение размера динамического массива при удалении плейлиста. По идее, при удалении вкладки с плейлистом нужно двигать массив плейлистов к началу и уменьшать размер массива на 1, но как двигать сдвигать массив в памяти я не знаю, а с указателями дружу очень плохо. Поэтому в этом примере, если постоянно создавать и удалять вкладки, то размер массива под вкладки и плейлисты будет постоянно расти, но думаю это не очень критично.
И вообще, думаю проще сразу создать плейлист допустим на 10 вкладок и с ним работать. Дать пользователю возможность добавлять и удалять треки, переименовывать названия плейлиста, очищать плейлист и т.д. Хотя идея с динамически создаваемыми вкладками для плейлистов мне понравилась. Вот, еще нашел пример по работе со вкладками http://www.cyberforum.ru/delphi-multimedia/thread629284.html , но переделывать под себя уже не охота, хотя вариант более перспективный.))))))
|
|
| |
Filo$oF | Дата: Среда, 30.05.2012, 18:42 | Сообщение # 40 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| xaramamburu, Спасибо, сейчас посмотрю. Добавлено (30.05.2012, 18:42) --------------------------------------------- С плейлистом вроде всё понятно, спасибо
kbps я уже давно разобрался, а вот khz выводит везде ноль. Может со временем разберусь, что там к чему
|
|
| |
xaramamburu | Дата: Среда, 30.05.2012, 19:09 | Сообщение # 41 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, Функцию khz специально попробовал запустить - все работает.))))
|
|
| |
Filo$oF | Дата: Среда, 30.05.2012, 20:07 | Сообщение # 42 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| А у меня ноль почему-то.. Попробовал так сделать
Code function TForm_player.KhzToStr: string; var H: Extended; bi: BASS_CHANNELINFO; begin BASS_StreamFree(Channel); //пытаемся загрузить файл и получить дескриптор канала Channel := BASS_StreamCreateFile(FALSE, PChar(FileName), 0, 0, 0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF}); BASS_ChannelGetInfo(Channel, bi); H := bi.freq / 1000; Result := IntToStr(Round(H)) + ' KHz'; BASS_StreamFree(Channel); end;
Стало для всех файлов 99
|
|
| |
xaramamburu | Дата: Среда, 30.05.2012, 20:36 | Сообщение # 43 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, Проверь на другом проигрывателе или посмотри размер файла, при такой частоте размер файла должен быть порядка 6 МБ. У меня показывает частоту 44 kHz для всех mp3.)))))))))
|
|
| |
Filo$oF | Дата: Среда, 30.05.2012, 21:28 | Сообщение # 44 |
Лейтенант
Группа: Пользователи
Сообщений: 61
Статус: Offline
| xaramamburu,
В Label выводит верно, а в отрисовку всё равно 99
|
|
| |
xaramamburu | Дата: Среда, 30.05.2012, 22:13 | Сообщение # 45 |
Полковник
Группа: Администраторы
Сообщений: 240
Статус: Offline
| Filo$oF, Попробуйте заменить в функции переменную Channel на Channel1 : DWORD; возможно он у вас считает частоту потока дважды т.к Channel уже используется для проигрывания трека, а вы через нее еще и частоту пытаетесь получить.
|
|
| |
|