-
Я только начинаю программировать.Решил написать плеер с использованием библиотеки басс.Но возникла проблема.Как сделать так,чтобы песни играли одна за другой и после воспроизведения песни она не начанала играть снова одна и таже???
ВОТ ИСХОДНЫЙ КОД ПЛЕЕРА
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Bass,MMSYSTEM, FileCtrl, StdCtrls, ExtCtrls, ComCtrls; type TChannelType = (ctUnknown, ctStream, ctMusic);
type TForm1 = class(TForm) ComboBox1: TComboBox; Label1: TLabel; Label2: TLabel; lbPosLen: TLabel; Button1: TButton; barSeek: TTrackBar; tmrMain: TTimer; Button2: TButton; Button3: TButton; procedure PlayList(P: string); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BASS_SetPosition(const Value: DWORD); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Button1Click(Sender: TObject); procedure tmrMainTimer(Sender: TObject); procedure barSeekChange(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure ComboBox1Click(Sender: TObject); private function BASS_GetLength: DWORD; function BASS_GetPosition: DWORD; procedure play;
public { Public declarations } end; var Form1: TForm1; MX: integer; MY: integer; floatable: DWORD; // floating-point channel support? chan: DWORD; CHANGE_POS: Boolean = True; FFileLength: string;
implementation
{$R *.dfm}
function TForm1.BASS_GetLength: DWORD; var SongLength: Int64; FloatLen: FLOAT; begin SongLength:= BASS_ChannelGetLength(chan); if SongLength < 0 then SongLength:= 0; FloatLen:= BASS_ChannelBytes2Seconds(chan, SongLength); Result:= Round(1000 * FloatLen); end;
function TForm1.BASS_GetPosition: DWORD; var SongPos: Int64; FloatPos: FLOAT; begin SongPos:= BASS_ChannelGetPosition(chan); if SongPos < 0 then SongPos:= 0; FloatPos:= BASS_ChannelBytes2Seconds(chan, SongPos); Result:= Round(1000 * FloatPos); end;
procedure TForm1.BASS_SetPosition(const Value: DWORD); var SongPos: Int64; begin SongPos:= BASS_ChannelSeconds2Bytes(chan, Value / 1000); BASS_ChannelSetPosition(chan, SongPos); end; var SoundP: string[255];
procedure TForm1.PlayList(P: string); var SearchRec: TSearchRec; // структура SearchRec содержит информацию // о файле, удовлетворяющем условию поиска begin ComboBox1.Clear; // сформировать список аудиофайлов if FindFirst(P + '*.mp3', faAnyFile, SearchRec) =0 then begin ComboBox1.Items.Add(SearchRec.Name); // добавим имя этого файла в список while (FindNext(SearchRec) = 0) do ComboBox1.Items.Add(SearchRec.Name); end; end; procedure TForm1.FormCreate(Sender: TObject); begin PlayList(''); ComboBox1.ItemIndex := 0; // check the correct BASS was loaded if (HIWORD(BASS_GetVersion) <> BASSVERSION) then begin MessageBox(0,'An incorrect version of BASS.DLL was loaded',0,MB_ICONERROR); Halt; end; BASS_SetConfig(BASS_CONFIG_FLOATDSP, 1); if not BASS_Init(-1, 44900, 0, Handle, nil) then begin MessageBox(0, 'Can''t initialize device', 0, 0); Halt; end; floatable := BASS_StreamCreate(44900, 2, BASS_SAMPLE_FLOAT, nil, 0); if (floatable > 0) then begin BASS_StreamFree(floatable); // woohoo! floatable := BASS_SAMPLE_FLOAT; end end;
procedure TForm1.FormDestroy(Sender: TObject); begin BASS_Free; end; procedure TForm1.play; var info: BASS_CHANNELINFO; i:sTRING; begin ComboBox1.ItemIndex := ComboBox1.ItemIndex + 1; i:=SoundP + ComboBox1.Items[ComboBox1.itemIndex]; // free both MOD and stream, it must be one of them! :) BASS_MusicFree(chan); BASS_StreamFree(chan);
chan := BASS_StreamCreateFile(False, PChar(i), 0, 0, floatable or BASS_SAMPLE_LOOP); if (chan = 0) then chan := BASS_MusicLoad(False, PChar(i), 0, 0, BASS_MUSIC_LOOP or BASS_MUSIC_RAMPS or floatable, 0);
BASS_ChannelGetInfo(chan, info); if (info.chans <> 2) then // only stereo is allowed begin BASS_MusicFree(chan); BASS_StreamFree(chan); MessageBox(0, 'Неподдерживаемый формат', 0, 0); Exit; end; tmrMain.Enabled:= True; BASS_ChannelPlay(chan, False); end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Shift<>[ssLeft] then begin MX:=X; MY:=Y; end else begin Left:=Left+X-MX; Top:=Top+Y-MY; end; end;
procedure TForm1.Button1Click(Sender: TObject); var Root: string; // корневой каталог pwRoot : PWideChar; Dir: string; begin Root := ''; // корневой каталог - папка Рабочий стол GetMem(pwRoot, (Length(Root)+1) * 2); pwRoot := StringToWideChar(Root,pwRoot,MAX_PATH*2); if not SelectDirectory('Выберите папку', pwRoot, Dir) then Dir :='' else Dir := Dir+'\';
// каталог, в котором находятся аудиофайлы выбран SoundP := Dir; PlayList(SoundP); end;
procedure TForm1.tmrMainTimer(Sender: TObject); var i:sTRING; begin if not barSeek.Enabled then barSeek.Enabled:= True; CHANGE_POS:= False; barSeek.Position:= (BASS_GetPosition * DWORD(barSeek.Max)) div BASS_GetLength; CHANGE_POS:= True; lbPosLen.Caption:= FormatDateTime('nn:ss', BASS_GetPosition / (1000 * 24 * 60 * 60)); end;
procedure TForm1.barSeekChange(Sender: TObject); var PD: Single; begin if CHANGE_POS then begin PD:= BASS_GetLength / barSeek.Max; BASS_SetPosition(Round(barSeek.Position * PD)); end; end;
procedure TForm1.Button2Click(Sender: TObject); begin ComboBox1.ItemIndex := ComboBox1.ItemIndex + 1; play; end;
procedure TForm1.Button3Click(Sender: TObject); begin ComboBox1.ItemIndex := ComboBox1.ItemIndex - 1; play; end;
procedure TForm1.ComboBox1Click(Sender: TObject); begin play; end;
end.
-
В PlayList ты забыл FindClose. Далее, 44900 откуда взялось? Вроде стандартное значение 44100.
Я уже не помню все функции bass, но нужно отслеживать окончание проигрывания очередного файла и открывать следующий. Например, отслеживать позицию.
-
ТО что надо отследить позицию окончания песни это я понял но как это сделать? Пробовал так : if (Bass_GetLength=Bass_GetPosition) then begin ComboBox1.ItemIndex := ComboBox1.ItemIndex + 1; play; end;
Но ничего из этого не выходит.Дайте пожалуйста конкретный код!
-
> и после воспроизведения песни она не начанала играть снова одна и таже???
убрать BASS_SAMPLE_LOOP
> Как сделать так,чтобы песни играли одна за другой
в timer if (BASS_ChannelIsActive(chan)<>BASS_ACTIVE_PLAYING) and (BASS_ChannelIsActive(chan)<>BASS_ACTIVE_PAUSED ) then запустить следущую
-
Спасибо.Песни играют одна за другой но меняются они через каждую секунду Т.К В ТАЙМЕРЕ ИНТЕРВАЛ 1 СЕК как сделать так ,чтобы интервал таймера был равен длине песни???.Мне надо,чтобы песня проиграла до конца. HELP !!!!!!
-
ВСЕ ПОЛУЧИЛОСЬ!!!Просто надо было поставить интервал таймера больше длины любой песни. С.П.А.С.И.Б.О. ОГРОМНОЕ ВСЕМ!!!
-
Извиняюсь нихрена не получилось возвращаюсь к предыдущему вопросу помогите я уже запарился!
-
Покажи исходник процедуры с таймером.
-
Сделай так:
В таймере if chan>0 then case BASS_ChannelIsActive(chan) of BASS_ACTIVE_PLAYING: показываешь статус проигрывания; BASS_ACTIVE_STOPPED: переходишь на след. мелодию. end;
Соответственно при нажатии на кнопку стоп освобождаешь chan.
-
Извините .Знаю ,что я тупой!!! Я разместил здесь исходник плеера.КТО-НИБУДЬ может исходя из него выложить код который будет решать мою проблему Я ТУПОЙ !!! показываешь статус проигрывания-Как его показывать???
-
Ауууу!!!
-
Где-то так:
var TrackTime:Double; TrackPos:integer; begin if chan>0 then case BASS_ChannelIsActive(chan) of BASS_ACTIVE_PLAYING: begin TrackPos:integer:=BASS_ChannelGetPosition(chan); - текущая позиция таймера TrackTime:=BASS_ChannelBytes2Seconds(chan, TrackPos); - текущее время в секундах end;
-
Точнее не текущая позиция таймера, а просто - текущая позиция.
|