Работа с форматом M3U
Формат этого файла таков: в начале файла есть служебное слово [#EXTM3U], означающее, что выбранный нами файл действительно m3u. Далее идут строки вида:
#EXTINF:120,Вася барабанщик – Kill My
My Music\Kill_My.mp3
Где [#EXTINF:] служебное слово, [120] – длина трека в секундах, [Вася барабанщик – Kill My ] – тэг, а [ My Music\Kill_My.mp3] – путь к файлу. Причём путь к файлу не полный и зависит от места расположения m3u файла. Пример: m3u файл находится в папке X:\ Music, а муз. файлы в X:\Music\My Music\Kill_My.mp3, тогда путь к файлу в плей листе будет My Music\Kill_My.mp3. А если файл музыки и файл плей листа будут на разных дисках, то путь будет полным. К чему такие сложности я не знаю, ведь можно просто писать полный путь и никаких проблем не будет. И ещё, если переместить файл плей листа, то WinAmp (и др. программы) не смогут воспроизвести файл, так как не найдут путь к нему. (При условии, что путь неполный).
Казалось бы неполный путь к файлу создаёт нам дополнительные проблемы. Это так. Но я написал функцию, которая восстанавливает этот путь. Итак, рассмотрим на примере, как можно загрузить в ListView данные из m3u файла. На форму помещаем ListView с тремя колонками. 1-я колонка – тэг, 2-я – длина трека, 3-я – путь. И добавим OpenDialog, для открытия файла, и кнопочку.
function NotFullPathToFullPath(FM3U, FM: string): string; (*Из неполного пути -> полный*) var Ress: string; begin Ress := ''; Result := ''; (*Если 1-й символ ‘\’, то просто добавляем букву диска*) if FM[1] = '\' then begin Result := ExtractFileDrive(FM3U) + FM; exit; end else begin (*Путь к m3u + неполный путь к файлу*) if FileExists(ExtractFilePath(FM3U) + FM) then begin Result := ExtractFilePath(FM3U) + FM; exit; end; (*А вдруг путь уже полный?*) if FileExists(FM) then begin Result := FM; exit; end; end; end; procedure ReadM3U(files: string); (*Чтение m3u*) (*Думаю всё и так понятно без комментариев ;)*) var List: TStringList; i, n: integer; s, a: string; ListItem: TListItem; begin (*Очищаем ЛистВив*) Form1.ListView1.Clear; List := TStringList.Create; try List.LoadFromFile(files); for i := 0 to List.Count - 1 do begin (*Первая строка – «#EXTM3U»? Если да, то это файл m3u*) if List.Strings[0] = '#EXTM3U' then begin s := List.Strings[i]; if s[1] <> '#' then begin ListItem.SubItems.Add(''); s := NotFullPathToFullPath(Files, s); ListItem.SubItems[1] := s; end else begin if s <> '#EXTM3U' then begin Delete(S, 1, 8); a := ''; n := 1; repeat a := a + s[n]; Inc(n); until s[n] = ','; Delete(S, 1, Length(a) + 1); ListItem := Form1.ListView1.Items.Add; ListItem.Caption := s; ListItem.SubItems.Add(Format('%d:%.2d', [StrToInt(a) div 60, StrToInt(a) mod 60])); end; end; end; end; finally List.Free; end; end;А вызывать будем по кнопке:
procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.Execute then ReadM3U(OpenDialog1.FileName) else exit; end;Так. Открытие мы сделали. Можете открыть свой плей лист, сохраненный в WinAmp'е и вглянуть на то, что получилось. Перейдём к сохранению. Положите на форму ещё одну кнопку и в путь. Не забудьте подключить модуль StrUtils.
function ExtNotFullPath(FM3U, FM: string): string; (*Из полного пути в неполный*) var i: integer; Ress: string; begin Ress := ''; Result := ''; for i := 1 to Length(FM3U) do begin if FM3U[i] = FM[i] then begin Ress := Ress + FM3U[i]; if FM3U[i] = '\' then Result := Ress; end else exit; end; end; function MinToSec(tim: string): string; (*Это такой компьютерный юмор, функция из минут в секунды, результат String ;)*) (*Помнишь мы секунды преобразовывали в минуты? Вот теперь всё наоборот*) var n: integer; a: string; begin n := 1; a := ''; repeat a := a + tim[n]; Inc(n); until tim[n] = ':'; Delete(tim, 1, Length(a) + 1); result := IntToStr((StrToInt(a) * 60) + StrToInt(tim)); end; procedure SaveList(SaveFile: string); (*Сохранение...*) var List: TStringList; i: integer; b, s: string; begin List := TStringList.Create; List.Add('#EXTM3U'); for i := 0 to Form1.ListView1.Items.Count - 1 do begin s := ''; List.Add('#EXTINF:' + MinToSec(Form1.ListView1.Items.Item[i].SubItems.Strings[0]) + ',' + Form1.ListView1.Items.Item[i].Caption); b := ExtNotFullPath(SaveFile, Form1.ListView1.Items.Item[i].SubItems.Strings[1]); if Length(b) < Length(ExtractFilePath(SaveFile)) then begin s := Form1.ListView1.Items.Item[i].SubItems.Strings[1]; if b<>`` then //проверка, на одинаковых ли дисках? Delete(s, 1, 2); end else s := AnsiReplaceText(Form1.ListView1.Items.Item[i].SubItems.Strings[1], b, ''); List.Add(s); end; (*Сохраняем в файл*) List.SaveToFile(SaveFile); List.Free; end;А вот и кнопочка пригодилась :-)
procedure TForm1.Button2Click(Sender: TObject); begin if SaveDialog1.Execute then begin if ExtractFileExt(SaveDialog1.FileName) = '.m3u' then SaveList(SaveDialog1.FileName) else SaveList(SaveDialog1.FileName + '.m3u'); end; end;Вот и всё, Удачи!