я замучился думать как преобразовать из позиции побайтно в час:мин:сек. если надо подскажу.
С этим проблемы не вижу, учитывая что весь необходимый для этого функционал предоставляет библиотека. Кстати это я за 10 минут сделал, правда тракбар еще не приделывал. Единственное что не радует, так это то что в инно фиксированный тип буфера при чтении из TFileStream - string, из-за этого возникают трудности с чтением ID3-тегов, стабильно читаются только ID2-теги, т.к у них фиксированный размер и не требуется узнавать hex-значения размера тега т.д.. Как много дел считались невозможными, пока они не были осуществлены. (Гай Плиний Секунд) Не занимаюсь подключением FreeArc/ISDone к чужим скриптам.
С этим проблемы не вижу, учитывая что весь необходимый для этого функционал предоставляет библиотека. Кстати это я за 10 минут сделал
А я за 1,5 часа . Просто я пытался написать функцию которая бы преобразовывала из секунд в час:мин:сек, а когда практически её написал случайно наткнулся на function FormatDateTime и остальное время с ней баловался
Quote (Shegorat)
Единственное что не радует, так это то что в инно фиксированный тип буфера при чтении из TFileStream - string, из-за этого возникают трудности с чтением ID3-тегов, стабильно читаются только ID2-теги, т.к у них фиксированный размер и не требуется узнавать hex-значения размера тега т.д..
А вот с тэгами, к сожалению не могу вам ничего подсказать, так как пока с ними ещё не работал.
PS. Всё время удивлялся почему у всех скриптов на инно(в том числе и ваш модуль басс) регулируется громкость в самой системе, а не в отдельном канале(как в плейерах).Почему никто не пользуется BASS_ChannelSetAttribute?
Дата: Понедельник, 30.05.2011, 07:11 | Сообщение # 35
Местный гуру
Администратор
Сообщений: 150
Статус: Offline
В общем пока было время доделал вывод ID3v1-тегов в виде всплывающего сообщения. Также сделал показ длительности песни. Жду графику, чтобы переделать на ботву.
UPD: 30/05/2011 7:10 (МСК)
Исправил ошибку с удалением пробелов (спасибо DaRKdemoN)
Поправил вывод всплывающего сообщения с информацией о песне
function MyProc(h: HWND; Msg, wParam, lParam: longint): Longint; begin if Msg=WM_MOVE then SetWindowPos(Mp3Form.Handle, 0, WizardForm.Left+WizardForm.Width+5, WizardForm.Top, 0, 0, $415); if Msg=WM_ACTIVATE then SendMessage(Mp3Form.Handle, WM_NCACTIVATE, 1, 0); Result:= CallWindowProc(OldProc, h, Msg, wParam, lParam); end;
function MyProc1(h: HWND; Msg, wParam, lParam: longint): Longint; begin if Msg=WM_MOVE then begin SetWindowPos(WizardForm.Handle, 0, Mp3Form.Left-(WizardForm.Width+5), Mp3Form.Top, 0, 0, $415); end; if Msg=WM_CLOSE then begin SendMessage(WizardForm.handle, WM_CLOSE, 0, 0); Exit; end; Result:= CallWindowProc(OldProc1, h, Msg, wParam, lParam); if Msg=WM_ACTIVATE then SendMessage(WizardForm.Handle, WM_NCACTIVATE, 1, 0); end;
function GetSelected(): Integer; var n: integer; begin Result:= -1; for n:=0 to Mp3List.Items.Count-1 do begin if mp3List.Selected[n] then begin Result:= n; Break; end; end; end;
procedure SetSelected(Index: Integer); begin SendMessage(Mp3List.Handle, $186, Index, 0); end;
procedure SetCurrentMp3(Index: Integer); var name: string; begin CurMp3Name.Caption:= Mp3List.Items.Strings[Index]+' '; name:= AddbackSlash(Mp3Info.Mp3Path)+Mp3List.Items.Strings[Index]; BASS_StreamFree(Mp3Info.Mp3Handle); Mp3Info.Mp3Handle:= BASS_StreamCreateFile(FALSE, PChar(name), 0, 0, 0, 0, $40000); BASS_ChannelPlay(Mp3Info.Mp3Handle, False); if Mp3Info.Mp3Files[Index].TotalSize=0 then Mp3Info.Mp3Files[Index].TotalSize:= BASS_ChannelGetLength(Mp3Info.Mp3Handle, 0); if Mp3Info.Mp3Files[Index].TotalTime=0 then Mp3Info.Mp3Files[Index].TotalTime:= BASS_ChannelBytes2Seconds(Mp3Info.Mp3Handle, Mp3Info.Mp3Files[Index].TotalSize, 0); Mp3Play.Caption:= 'Pause'; Mp3Info.IsMp3Playing:= True; end;
procedure GetClickedItem(Sender: TObject); begin SetCurrentMp3(GetSelected()); end;
procedure NextSelected(Sender: TObject); var n: Integer; begin n:= GetSelected()+1; if n>=Mp3List.Items.Count then n:=0; SetSelected(n); SetCurrentMp3(n); end;
procedure PreviousSelected(Sender: TObject); var n: Integer; begin n:= GetSelected()-1; if n<0 then n:= Mp3List.Items.Count-1; SetSelected(n); SetCurrentMp3(n); end;
procedure PlayMp3(Sender: TObject); begin if Mp3Info.IsMp3Playing then begin Mp3Play.Caption:='Play'; BASS_ChannelPause(Mp3Info.Mp3Handle); Mp3Info.IsMp3Playing:= False; end else begin Mp3Play.Caption:='Pause'; BASS_ChannelPlay(Mp3Info.Mp3Handle, False); Mp3Info.IsMp3Playing:= True; end; end;
Function TrimTab(S: String): String; begin while pos(#0, S)>0 do StringChange(S, #0, ''); while (Length(S)>=1)and(S[length(S)]=' ') do SetLength(S, Length(S)-1); while (Length(S)>=1)and(S[1]=' ') do Delete(S, 1, 1); Result:= S; end;
procedure Mp3CreateFilesList(Dir: String; Mask: String); var FSR: TFindRec; k: Integer; FStream: TFileStream; Buffer: string; begin Mp3Info.Mp3Path:= Dir; SetArrayLength(Mp3Info.Mp3Files, 0); if FindFirst(AddBackSlash(Dir)+Mask, FSR) then repeat k:= GetArrayLength(Mp3Info.Mp3Files); SetArrayLength(Mp3Info.Mp3Files, k+1); Mp3Info.Mp3Files[k].Filename:= AddBackslash(Dir)+FSR.Name; FStream:= TFileStream.Create(AddBackslash(Dir)+FSR.Name, fmOpenRead ); try FStream.Seek(-128, soFromEnd); SetLength(Buffer, 128); FStream.Read(Buffer, 128); if Buffer <> '' then begin Mp3Info.Mp3Files[k].ID:= TrimTab(copy(Buffer, 1, 3)); Mp3Info.Mp3Files[k].Title:= TrimTab(copy(Buffer, 4, 30)); Mp3Info.Mp3Files[k].Artist:= TrimTab(copy(Buffer, 34, 30)); Mp3Info.Mp3Files[k].Album:= TrimTab(copy(Buffer, 64, 30)); Mp3Info.Mp3Files[k].Year:= TrimTab(copy(Buffer, 94, 30)); Mp3Info.Mp3Files[k].Comment:= TrimTab(copy(Buffer, 98, 30)); Mp3Info.Mp3Files[k].Genre:= Ord(Buffer[128]); if Mp3Info.Mp3Files[k].Genre>128 then Mp3Info.Mp3Files[k].Genre:=12; end; finally FStream.Free; end; until not FindNext(FSR); FindClose(FSR); end;
procedure Mp3ListAddFiles(Dir: String; Mask: String); var n: integer; begin Mp3CreateFilesList(Dir, Mask); for n:=0 to getArrayLength(Mp3Info.Mp3Files)-1 do begin Mp3List.Items.Add(ExtractFilename(Mp3Info.Mp3Files[n].Filename)) end; end;
function ToTime(time: double): string; begin Result:= Padz(FloatToStr(trunc(time/3600)), 2)+':'+PADZ(FloatToStr(trunc((time-trunc(time/3600)*3600)/60)), 2)+':'+PADZ(FloatToStr(trunc(time - trunc(time/60)*60)), 2); end;
procedure Mp3TimerProc(HandleW, msg, idEvent, TimeSys: LongWord); var s: string; Mp3Pos: DWORD; MP3PosTime: double; begin LastEvent:=LastEvent+50; if (BASS_ChannelIsActive(Mp3Info.Mp3Handle) = 0)and(Mp3Info.IsMp3Playing) then NextSelected(nil);
if (CurMp3Name.Caption<>'')and(LastEvent>=300) then begin s:= CurMp3Name.Caption s:= s+Copy(s, 1, 1); Delete(s, 1, 1); CurMp3Name.Caption:=s; LastEvent:=0; end;
if Mp3Info.IsMp3Playing then begin Mp3Pos:= BASS_ChannelGetPosition(Mp3Info.Mp3Handle, 0); MP3PosTime:= BASS_ChannelBytes2Seconds(Mp3Info.Mp3Handle, Mp3Pos, 0); TimeLabel.Caption:= ToTime(MP3PosTime) +' / '+ ToTime(Mp3Info.Mp3Files[GetSelected].TotalTime); end; end;
procedure Mp3GetIndexHint(Sender: TObject; Shift: TShiftState; X,Y: Integer); var i: integer; pt: TPoint; begin pt.x:=X; pt.y:= Y; i:= Mp3List.ItemAtPos(pt, true); if (Mp3Info.LastHintIndex<>i) then begin Mp3List.Hint:=''; Mp3List.ShowHint:= False; if i<>-1 then begin Mp3Info.LastHintIndex:= i; Exit; end; end;
if (i<>-1) then begin Mp3List.Hint:= 'Title: '+Mp3Info.Mp3Files[i].Title+#13+ 'Artist: '+Mp3Info.Mp3Files[i].Artist+#13+ 'Album: '+Mp3Info.Mp3Files[i].Album+#13+ 'Year: '+Mp3Info.Mp3Files[i].Year+#13+ 'Genre: '+Genres[Mp3Info.Mp3Files[i].Genre]; Mp3List.ShowHint:= True; end;
end;
procedure InitializeWizard(); begin ExtractTemporaryFile('#1_01_Eagles_Otel California.mp3'); ExtractTemporaryFile('#1_02_Urge overkill_Girl you''ll be a woman soon.mp3'); ExtractTemporaryFile('#1_03_Gary Moore_Still got the blues.mp3'); ExtractTemporaryFile('#1_04_Extreme_More than worlds.mp3'); ExtractTemporaryFile('#1_05_Chris Rea_I just wanna be with you.mp3'); ExtractTemporaryFile('#1_06_The Beatles_Yesterday.mp3');
Дата: Понедельник, 30.05.2011, 10:51 | Сообщение # 37
Местный гуру
Администратор
Сообщений: 150
Статус: Offline
Quote (South)
ID3 тэги 2-ой версии не читаются, либо с кодировкой проблемы
Скорее всего проблемы с кодировкой. Можешь залить пару файлов для тестирования? Теги ID3v2 криво читаются в инно, поэтому я пока не стал их трогать, только ID3v1. Как много дел считались невозможными, пока они не были осуществлены. (Гай Плиний Секунд) Не занимаюсь подключением FreeArc/ISDone к чужим скриптам.
Дата: Понедельник, 30.05.2011, 15:17 | Сообщение # 38
Проверенный
Сообщений: 8
Статус: Offline
Shegorat, вот файлики для тестов http://ifolder.ru/23850774 в свое время Виктор Добров меня тоже попинал с этими тэгами, да и файлы эти он мне скинул когда-то для тестов
Дата: Понедельник, 30.05.2011, 19:32 | Сообщение # 39
Местный гуру
Администратор
Сообщений: 150
Статус: Offline
Quote (South)
Shegorat, вот файлики для тестов http://ifolder.ru/23850774 в свое время Виктор Добров меня тоже попинал с этими тэгами, да и файлы эти он мне скинул когда-то для тестов
Спасибо. Я это исправил вроде, сейчас тестирую. А вот теги ID3v2 в инно никак не получается читать, т.к текст из TFileStream читается до первого знака #0 считая его завершающим... Как много дел считались невозможными, пока они не были осуществлены. (Гай Плиний Секунд) Не занимаюсь подключением FreeArc/ISDone к чужим скриптам.
Дата: Понедельник, 30.05.2011, 21:32 | Сообщение # 40
Проверенный
Сообщений: 8
Статус: Offline
Quote (Shegorat)
А вот теги ID3v2 в инно никак не получается читать, т.к текст из TFileStream читается до первого знака #0 считая его завершающим...
если память не изменяет, то там не до #0 читать надо, надо получать размер "секции" и считывать соответствующее кол-во байт и из этого месива получать содержимое тэга могу попробовать переписать модуль с делфи на инно, правда не помню как там с кодировками вопрос решался
если память не изменяет, то там не до #0 читать надо, надо получать размер "секции" и считывать соответствующее кол-во байт и из этого месива получать содержимое тэга
Я знаю это. Я и пытаюсь получить длину ID3v2 тега. Заголовок ID3 тега состоит из 10 байт, первые 3 это всегда "ID3", затем 2 байта - версия IDv2 тега, затем 1 байт - это флаги, и затем 4 байта в которых записан размер ID3v2 тега. И я не говорил что я читаю до первого #0 Просто я неправильно определял размер тега, не производя нужных преобразований с байтами, потому мне и выдавало невесть что. Сейчас порывшись в гугле нашел модуль для работы с ID3v2 тегами, из него выдрал вычисление размера тега. Вроде нормально работает. Осталась только проблема с кодировками. P.S. Та ошибка про которую ты говорил не из-за кодировок. У меня не было проверки на наличие ID3v1 тега, и он всегда читал 128 байт в конце файла. А в том файле-примере не было этого самого ID3v1 тега. Как много дел считались невозможными, пока они не были осуществлены. (Гай Плиний Секунд) Не занимаюсь подключением FreeArc/ISDone к чужим скриптам.
Shegorat, да, тут ты прав, это я подзабыл и я уже почти переписал модуль на инно, пока не могу нормально получить номер трека в альбоме и с кодировкой остался вопрос. точнее перекодирование работает, но непонятно откуда там еще один невнятный символ берется, пока просто его выкидываю, а так разобраться надо будет. остальное все пашет. может сегодня допишу, если время позволит
ЗЫ на твой PS - вполне логично. примеры так и подбирались, чтобы все проверить можно было
ЗЗЫ в принципе модуль я написал, только он не хочет работать на юникодном инно, на анси работает . сейчас у меня уже нет времени ковыряться, если есть желание, то могу выложить, а дальше сам подправишь
Добавлено (31.05.2011, 21:20) --------------------------------------------- Shegorat, вот, написал чтение ID3-тэгов Доступно только для пользователей проверял на 5.4.2(a) и 5.4.2(u), все компилится и вроде работает естественно здесь может быть куча ошибок, т.к. на тестирование у меня нет времени оптимизацией кода я тоже не занимался, в паре мест точно можно упростить код, я просто получил рабочий вариант и на этом успокоился
ЗЫ к тебе просьба - писать модули без использования рестулсовской сборки, а то прежде чем что-то протестить или просто посмотреть приходится еще тратить время на шаманство.
Сообщение отредактировал South - Четверг, 02.06.2011, 18:42
Дата: Понедельник, 06.06.2011, 15:29 | Сообщение # 43
Энтузиаст
Проверенный
Сообщений: 110
Статус: Offline
Shegorat Слушай, а реально сделать, чтобы в модуле басс, громкость уменьшалась только в инсталляторе, а в самой системе оставалась прежней? Кто не с нами, тот в запое...
Дата: Понедельник, 06.06.2011, 16:02 | Сообщение # 44
Местный гуру
Администратор
Сообщений: 150
Статус: Offline
Quote (Edison007)
Слушай, а реально сделать, чтобы в модуле басс, громкость уменьшалась только в инсталляторе, а в самой системе оставалась прежней?
Реально. Сделаю но попозже, сейчас времени нету... Как много дел считались невозможными, пока они не были осуществлены. (Гай Плиний Секунд) Не занимаюсь подключением FreeArc/ISDone к чужим скриптам.
Раньше я этим вопросом тоже задавался, но потом как начал читать справку по басс многие такие же вопросы отпали(советую тоже почитать). Ответом на ваш вопрос будет функция BASS_ChannelSetAttribute со вторым параметром BASS_ATTRIB_VOL. Эксперементируйте