Вторник, 16.04.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Как часто ви на этот сайт заходите?
Всего ответов: 159
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Мультимедиа » Звук

Работа с форматом M3U

Интро.

Поводом для написания этой статьи послужило то, что я в Интернете не нашёл ни одной подобной статьи, описывающей такой формат. Начнём с назначения m3u файлов. Не для кого, думаю, не секрет, что этот тип файлов используется в WinAmp 'е для (со)хранения «плей листа». В этой статье мы рассмотрим запись и чтение 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;

The End.

Получить ссылку на материал

Категория: Звук | Добавил: Барон (20.12.2011)
Просмотров: 2079 | Теги: m3u, формат | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
Звук [8]
Королевство Delphi © 2010-2024
Яндекс цитирования