The example shows how to download TS files from a video stream using the MultiDownloader component.
The task of downloading and joining TS video streams consists of three steps:
1) discover a m3u8 playlist URL, download this URL, and extract all TS file links;
2) download all extracted TS file links.
3) prepare config files for the ffmpeg utility.
You can obtain an m3u8 URL using Firefox with the installed Stream Detector add-on. This add-on allows you to automatically extract all TS video links and copy them to the clipboard.
procedure TForm1.btnGetListClick(Sender: TObject);
var
i, counter: Integer;
item: TclDownLoadItem;
list: TStrings;
urlParser: TclUrlParser;
s: String;
begin
if (clMultiDownLoader1.IsBusy) then
begin
ShowMessage('The downloading is in progress');
Exit;
end;
clDownLoader1.URL := edtM3U8Url.Text;
clDownLoader1.LocalFile := 'downloadlist.m3u8';
clDownLoader1.LocalFolder := edtSaveToFolder.Text;
clDownLoader1.ThreadCount := 1;
clDownLoader1.Start(False);
clMultiDownLoader1.DownLoadList.Clear();
list := TStringList.Create();
urlParser := TclUrlParser.Create();
try
list.LineBreak := #10;
list.LoadFromFile(clDownLoader1.LocalFile);
counter := 1;
for i := 0 to list.Count - 1 do
begin
s := list[i];
if (s <> '') and (s[1] <> '#') and (Pos('.ts', s) > 0) then
begin
item := clMultiDownLoader1.DownLoadList.Add();
urlParser.Parse(edtM3U8Url.Text, s);
item.URL := urlParser.AbsoluteUri;
item.LocalFile := Format('%d.ts', [counter]);
Inc(counter);
end;
end;
finally
urlParser.Free();
list.Free();
end;
if (clMultiDownLoader1.DownLoadList.Count > 0) then
begin
edtProgress.Text := Format('%d video files found', [clMultiDownLoader1.DownLoadList.Count]);
end else
begin
ShowMessage(
'The provided m3u8 file doesn''t contain video files, please choose another URL.');
end;
end;
procedure TForm1.btnStartClick(Sender: TObject);
begin
if (clMultiDownLoader1.IsBusy) then
begin
ShowMessage('The downloading is in progress');
Exit;
end;
memLog.Lines.Clear();
FSuccessful := 0;
FFailed := 0;
clMultiDownLoader1.MaxStartedItems := StrToInt(edtDownloadBy.Text);
clMultiDownLoader1.InternetAgent := edtUserAgent.Text;
clMultiDownLoader1.TryCount := StrToInt(edtTryCount.Text);
clMultiDownLoader1.TimeOut := StrToInt(edtTimeout.Text);
clMultiDownLoader1.LocalFolder := edtSaveToFolder.Text;
clMultiDownLoader1.Start();
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
clMultiDownLoader1.Stop();
end;
procedure TForm1.clMultiDownLoader1StatusChanged(Sender: TObject;
Item: TclInternetItem; Status: TclProcessStatus);
begin
case Status of
psSuccess: Inc(FSuccessful);
psFailed, psErrors, psTerminated:
begin
Inc(FFailed);
memLog.Lines.Add(Item.URL);
end;
end;
edtProgress.Text := Format('Downloading successful: %d, failed: %d', [FSuccessful, FFailed]);
end;
This program doesn't join downloaded TS files. You can do that using the ffmpeg open-source utility. The program prepares a list of downloaded files to join in one single TS stream file. Optionally, we can re-split this stream on separated parts.
procedure TForm1.btnPrepareListClick(Sender: TObject);
var
list: TStrings;
batch: Integer;
item: TclDownLoadItem;
i, counter: Integer;
begin
list := TStringList.Create();
try
batch := clMultiDownLoader1.DownLoadList.Count div StrToInt(edtSplitOn.Text);
counter := 1;
for i := 0 to clMultiDownLoader1.DownLoadList.Count - 1 do
begin
item := clMultiDownLoader1.DownLoadList[i];
list.Add('file ''' + ExtractFileName(item.LocalFile) + '''');
if(list.Count = batch) then
begin
list.SaveToFile(AddTrailingBackSlash(edtSaveToFolder.Text) +
Format('list%d.txt', [counter]));
list.Clear();
Inc(counter);
end;
end;
if(list.Count > 0) then
begin
list.SaveToFile(AddTrailingBackSlash(edtSaveToFolder.Text) + Format('list%d.txt',
[counter]));
end;
finally
list.Free();
end;
ShowMessage('Done');
end;
Have questions?
Article ID: 163, Created: May 19, 2020 at 1:24 PM, Modified: June 4, 2020 at 4:24 PM