3
51
fe329d86-741f-4816-a195-57c0a4e876dc
234DF17B-418C-4FDC-9DFE-CD0C586D2E76
4
YoutubeChannels_v3
527
--maxresults=25 --dopvideo=off --orderby=date --safesearch=none --pattern='[{num0}] {title} ({published})' --replacefrom='' --replaceto='' --replacefrom2='' --replaceto2='' --replacefrom3='' --replaceto3='' --dopvideopattern='{num} {title} ({published})' --delemptybrackets=on --getfilesize=off --gettimelength=on --backupstars=on --log=off
515
1
700
0
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
512
0
532
1
553
1
522
0
570
0
245
fe329d86-741f-4816-a195-57c0a4e876dc
93
41825,5740458449
530
// [GetList] Скрипт получения списка видео с Youtube
// Made By Vadim_S, http://storvild.ru
const
VER = 'HMS.3.0.19.beta'; //Release версия пишется с точкой в конце HMS.3.0.10.
csSiteLink = 'HMS';
INTERNET_FLAG_NO_COOKIES = $00080000; { no automatic cookie handling }
INTERNET_FLAG_NO_AUTO_REDIRECT = $00200000;
INTERNET_FLAG_RELOAD = $80000000;
mpiYoutubePageToken = 141206;
mpiYoutubeType = 141207;
mpiYoutubeCode = 141208;
mpiYoutubeUrl = 141209;
mpiYoutubeCurPage = 141210;
mpiYoutubeTTSUrl = 141211;
mpiYoutubeVideoHeight = 141212;
mpiYoutubeVideoID = 141213;
mpiYoutubeViewCount = 141214;
mpiYoutubeDuration = 141215;
mpiYoutubeDescription = 141216;
mpiYoutubeChannelTitle= 141217;
mpiYoutubeChannelId = 141218;
mpiYoutubeRating = 141219;
var
csStarsBackupFileName: string = HmsDataDirectory+'\hms_stars.backup';
gpSafeSearch: string = 'moderate'; //Показывать ли закрытый контент. none | moderate | strict
gpMaxResults: Integer = 25; //Кол-во результатов на страницу 1-50
gpOrderBy: string = 'date'; // date | rating | relevance | title | viewCount
gpPublishedAfter: string = ''; //Найти видео до указанной даты '2014-02-23T00:00:00Z'
gpPublishedBefore: string = ''; //Найти видео после указанной даты '2015-03-01T00:00:00Z'
gpRelevanceLanguage: string = ''; // Язык роликов ('ru', 'en')
gpVideoDimension: string = 'any'; // any | 2d | 3d
gpVideoDefinition: string = 'any'; // Качество (any | high | standard)
gpVideoDuration: string = 'any'; // Длина видео (any | long | medium | short)
gpReplaceFrom: string = '';
gpReplaceTo: string = '';
gpReplaceFrom2: string = '';
gpReplaceTo2: string = '';
gpReplaceFrom3: string = '';
gpReplaceTo3: string = '';
gpPattern: string = '[{num}] {title} ({published})'; //num, title, published, year, month, day
gpPlaylistPattern: string = '';
gpChannelPattern: string = '';
gpDopVideo: string = 'off';
gpDopVideoPattern: string = '{num} {title} ({published})';
gpDopVideoMaxResults: Integer = 25; //Максимальное кол-во доп.видео 1-50
gpDopVideoInFolder: string = 'on';
gpDelEmptyBrackets: string = 'off';
gpStarsBackup: string = 'on';
log: string = 'off';
logError: string = 'on';
procedure InitParameters;
var lmaxresults,lstartindex: integer;
ltype: string;
begin
gpMaxResults := StrToIntDef(GetPodcastParam('--maxresults', ''), gpMaxResults); //25
gpSafeSearch := GetPodcastParam('--safesearch', gpSafeSearch); // moderate (none | moderate | strict)
gpOrderBy := GetPodcastParam('--orderby', gpOrderBy); // date (date | rating | relevance | title | viewCount)
gpPublishedAfter := GetPodcastParam('--publishedafter', gpPublishedAfter); //Найти видео до указанной даты '2014-02-23T00:00:00Z'
gpPublishedBefore := GetPodcastParam('--publishedbefore', gpPublishedBefore); //Найти видео после указанной даты '2015-03-01T00:00:00Z'
gpRelevanceLanguage := GetPodcastParam('--relevancelanguage', gpRelevanceLanguage); // Язык роликов ('ru')
gpVideoDimension := GetPodcastParam('--videodimension', gpVideoDimension); // any | 2d | 3d
gpVideoDefinition := GetPodcastParam('--videodefinition', gpVideoDefinition); // Качество (any | high | standard)
gpVideoDuration := GetPodcastParam('--videoduration', gpVideoDuration); // Длина видео (any | long | medium | short)
gpReplaceFrom:= GetPodcastParam('--replacefrom', gpReplaceFrom); // ''
gpReplaceTo := GetPodcastParam('--replaceto', gpReplaceTo); // ''
gpReplaceFrom2:= GetPodcastParam('--replacefrom2', gpReplaceFrom2); // ''
gpReplaceTo2 := GetPodcastParam('--replaceto2', gpReplaceTo2); // ''
gpReplaceFrom3:= GetPodcastParam('--replacefrom3', gpReplaceFrom3); // ''
gpReplaceTo3 := GetPodcastParam('--replaceto3', gpReplaceTo3); // ''
gpPattern := GetPodcastParam('--pattern', gpPattern); // '[{num}] {title} {published}' (pubyear,pubmonth,pubday)
gpPlaylistPattern := GetPodcastParam('--playlistpattern', gpPlaylistPattern); // ''
gpChannelPattern := GetPodcastParam('--channelpattern', gpPlaylistPattern); // ''
gpDopVideo := GetPodcastParam('--dopvideo', gpDopVideo); // off (on | off)
gpDopVideoPattern := GetPodcastParam('--dopvideopattern', gpDopVideoPattern); // '[{parentnum}] {parenttitle,10} {num} {title}'
gpDelEmptyBrackets := GetPodcastParam('--delemptybrackets', gpDelEmptyBrackets); // off (on | off)
gpDopVideoInFolder := GetPodcastParam('--dopvideoinfolder', gpDopVideoInFolder); // on (on | off)
gpDopVideoMaxResults := StrToIntDef(GetPodcastParam('--dopvideomaxresults', ''), gpDopVideoMaxResults); //25
gpStarsBackup := GetPodcastParam('--starsbackup', gpStarsBackup); // on (on | off)
log := GetPodcastParam('--log',log); //off (on | off)
logError := GetPodcastParam('--logerror',logError); //off (on | off)
end;
//============= Общие функции ================================================//
function GetTimeLength(const aValue: string): string;
var
eDuration: Extended;
begin
eDuration := StrToFloatDef(aValue, 0);
if eDuration > 0 then
Result := FormatDateTime('HH:NN:SS.ZZZ', eDuration / (24 * 60 * 60))
else
Result := ''
end;
function GetPublishedDate(const aValue: string): string;
begin
Result:=Copy(aValue,9,2)+'.'+Copy(aValue,6,2)+'.'+Copy(aValue,1,4);
end;
//Заменяет в шаблоне параметр в фигурных скобках {title}. Если параметр {title,10}, то укорачивает до 10 символов
function ReplacePattern(inPattern, inParamName, inParamValue: string): string;
var mparam, mparamcount_str: string;
mparamcount: Integer;
pvshort: string;
res: string;
lParamValue: string;
begin
//Если в шаблоне используется ограничение по размеру текста {title,10}
if HmsRegExMatch2('({'+inParamName+',\s*(\d+)})', inPattern, mparam, mparamcount_str) then
begin
res := inPattern;
lParamValue := inParamValue;
mparamcount := StrToInt(mparamcount_str);
if (mparamcount>=0) and (length(lParamValue)>mparamcount) then
lParamValue := Copy(lParamValue,1,mparamcount)+'...';
if (gpDelEmptyBrackets='on') then
res := ReplaceStr(res, '['+mparam+']', lParamValue);
res := ReplaceStr(res, mparam, lParamValue);
end
else
begin
res := inPattern;
lParamValue := inParamValue;
//Замена параметра в фигурных скобках
res := ReplaceStr(res, '{'+inParamName+'}', lParamValue);
//Если в настройках стоит Удалять пустые квадратные скобки, то удаляем их
if (gpDelEmptyBrackets='on') then
res := ReplaceStr(res, '[]', '');
end;
Result := res;
end;
function GetPodcastParam(const aParamName, aDefaultValue: string): string;
begin
Result := ExtractParam(mpPodcastParameters, aParamName);
if Result = '' then Result := aDefaultValue
end;
//Удаляет двойные пробелы и переводы строк (заменяет пробелами)
function trimex(inText: string): string;
begin
if (pos(' ',inText)>0) or (pos(#13,inText)>0) or (pos(#10,inText)>0) then
begin
Result := ReplaceStr(inText, ' ', ' ');
Result := ReplaceStr(Result, #13, ' ');
Result := ReplaceStr(Result, #10, ' ');
Result := trimex(Result);
end
else
Result := trim(inText);
end;
function Ceil(inVal: Extended): Integer;
begin
Result:=Int(inVal);
if (Int(inVal)<inVal) then
Result := Int(inVal)+1;
end;
function DownloadUrl(const aUrl: string): string;
var
iPort: Integer;
sHeader, sReferer, sServer, sObject, sProtocol: string;
begin
aUrl := HmsUtf8Encode(aUrl); //Преобразование ссылки в UTF-8
if HmsRegExMatch3('http(.?)://([^/]*)(/.*)?', aUrl, sProtocol, sServer, sObject) then
begin
if sObject = '' then sObject := '/';
if sProtocol = 's' then iPort := 443 else iPort := 80;
sReferer := csSiteLink + #13#10 + 'Accept: */*'#13#10'Accept-Encoding: gzip,deflate';
Result := HmsSendRequestEx(sServer, sObject, 'GET', '', sReferer, '', iPort,
INTERNET_FLAG_NO_COOKIES or INTERNET_FLAG_RELOAD, sHeader, True);
if (Result <> '') and (Ord(Result[1]) = 31) then
Result := HmsDecompressString(Result);
end
else if Pos('http', aUrl) = 1 then
Result := HmsDownloadUrl(aUrl)
else
Result := '';
Result := HmsUtf8Decode(Result); //Преобразование результата из UTF-8
end;
function ReplaceStrI(const cStr1, cSrch, cReplace: String): String;
var sLowerSrch, sTempStr, sResultStr: string;
i: integer;
begin
//HmsRegExReplace(cSrch, cStr1, cReplace, sResultStr, 1, PCRE_CASELESS);
sResultStr := '';
sLowerSrch := Lowercase(cSrch);
sTempStr := cStr1;
while Pos(sLowerSrch, Lowercase(sTempStr))>0 do
begin
i := Pos(sLowerSrch, Lowercase(sTempStr));
sResultStr := sResultStr+Copy(sTempStr, 1, i-1)+cReplace;
Delete(sTempStr,1, i-1+Length(sLowerSrch));
end;
sResultStr := sResultStr+sTempStr;
Result := sResultStr;
end;
procedure addLog(inMsg: string; inTimeON: boolean = true);
var TimeStr: string = '';
begin
if (log='on') then
begin
if inTimeON then
TimeStr := FormatDateTime('HH:NN:SS.ZZZ',Now())+' ';
HmsLogMessage(1, TimeStr+' '+inMsg);
end;
end;
procedure addLogError(inMsg: string; inTimeON: boolean = true);
var TimeStr: string = '';
begin
if (logError='on') then
begin
if inTimeON then
TimeStr := FormatDateTime('HH:NN:SS.ZZZ',Now())+' ';
HmsLogMessage(2, TimeStr+' '+inMsg);
end;
end;
//============= Ф-ции для работы с подкастами ================================//
//Получение списка видео по параметрам
procedure CreateVideoItems_By_Json(inParentFolder: THmsScriptMediaItem; inUrl, inParentTitle, inParentNum, inPattern, inDopVideo: string; inType: string = ''; inCode: string = '');
var MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lurl: string;
lYtCode, lYtLink, lTitle, lPublishedDate, lDuration, lThumbnail, lViewCount,
lNumLikes, lNumDislikes, lEpisodeNum, lChannelTitle, lChannelId, lNumRaters, lDescription,
lFirstReleased, lYear: string;
lRatingF: double;
lRating: string;
lShowNum: string = '';
lShowDate: string = '';
lShowEpisodeNum: string = '';
MediaItem: THmsScriptMediaItem;
lPattern: string;
lComment: string;
lTitleFormat: string;
mtitle,mtitlecount: string;
lParentFolder: THmsScriptMediaItem;
lCountVideo: Integer;
ldownloadStr: string;
lNextFolder: THmsScriptMediaItem;
lNextPageToken: string;
lItemsPerPage,lItemsCount,lPageCount: integer;
DopVideoFolder: THmsScriptMediaItem;
lYtCodes: string = '';
lStarsBackupText: string;
lNum, lPosition: integer;
lPublishedDateFormat: string;
begin
//Временно
//gpMaxResults:=10;
//inChannel:='thisishorosho';
// RaiseException(IntToStr(1));
if gpStarsBackup='on' then
begin
lStarsBackupText := HmsStringFromFile(csStarsBackupFileName);
end;
MainObj := TJsonObject.Create();
lurl := inUrl;
try
//ldownloadStr := HmsUtf8Decode(DownloadUrl(HmsUtf8Encode(lurl)));
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
//RaiseException(lurl);
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
if lNextPageToken<>'' then
begin
lNextFolder := inParentFolder.AddFolder(mpFilePath+'-'+IntToStr(lPageCount)); //Если AddFolder('') то папка не создается. Одинаковые имена типа '-' не подходят для создания более одной папки
lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiTitle] := 'Следующая страница 2/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
//lNextFolder[mpiPartNo] := 2;
//lNextFolder[mpiPartTotal] := lPageCount;
lNextFolder[mpiThumbnail] := '';
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := inType;
lNextFolder[mpiYoutubeCode] := inCode;
lNextFolder[mpiYoutubeUrl] := inUrl;
lNextFolder[mpiYoutubeCurPage] := 2; //2 страница
if (log='on') then
lNextFolder[mpiComment] := VarToStr(lNextFolder[mpiYoutubeType])+'#'+VarToStr(lNextFolder[mpiYoutubeCode])+'#'+VarToStr(lNextFolder[mpiYoutubePageToken]);
end;
if (gpDopVideo='on') and (gpDopVideoInFolder='on') then
begin
DopVideoFolder := FolderItem.AddFolder('Дополнительные видео');
DopVideoFolder[mpiYoutubeCurPage] := 1;
DopVideoFolder[mpiFolderSortOrder] := 'mpPartNo';
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
lYtCode := ItemObj.S['videoId'];
if lYtCode<>'' then
begin
lYtCodes:=lYtCodes+','+lYtCode;
addLog('Добавлено видео: '+lYtCode);
lYtLink := 'http://www.youtube.com/watch?v='+lYtCode;
lPublishedDate := ItemObj.S['publishedAt'];
lPublishedDateFormat := GetPublishedDate(lPublishedDate);
lThumbnail := ItemObj.S['thumbnail'];
lChannelTitle := ItemObj.S['channelTitle'];
lChannelId := ItemObj.S['channelId'];
lDescription := ItemObj.S['description'];
lDuration := ItemObj.S['duration'];
lYear := Copy(ItemObj.S['publishedAt'],1,4);
lViewCount := ItemObj.S['viewCount'];
lComment := lDescription+#13#10+'Канал: '+lChannelTitle;
if lViewCount<>'' then
lComment := lComment+#13#10+'Кол-во просмотров на Youtube: '+lViewCount;
lNum := i+1;
lPosition := i+1;
lShowNum := PadLeft(IntToStr(i+1),length(gpMaxResults),'0'); //lShowNum := FormatFloat('000',i+1)+' ';
lTitle := ItemObj.S['title'];
lTitleFormat := GetTitleByPattern(lTitle, inPattern, lNum, lPosition, lPublishedDate);
MediaItem := HmsCreateMediaItem(lYtLink, inParentFolder.ItemID);
MediaItem.Properties[mpiTitle] := lTitleFormat;
MediaItem.Properties[mpiCreateDate] := lPublishedDateFormat;
MediaItem.Properties[mpiComment] := lComment;
MediaItem.Properties[mpiThumbnail] := lThumbnail;
MediaItem.Properties[mpiTimeLength] := GetTimeLength(lDuration);
MediaItem.Properties[mpiPartNo] := i+1;
MediaItem.Properties[mpiPartTotal] := lItemsCount;
MediaItem.Properties[mpiYear] := lYear;
MediaItem.Properties[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(lChannelTitle));
MediaItem.Properties[mpiProgramID] := lViewCount;
MediaItem.Properties[mpiYoutubeChannelTitle] := HmsUtf8Decode(HmsHttpDecode(lChannelTitle));
MediaItem.Properties[mpiYoutubeChannelId] := lChannelId;
MediaItem.Properties[mpiYoutubeDescription] := lDescription;
MediaItem.Properties[mpiYoutubeDuration] := StrToIntDef(lDuration,0);
MediaItem.Properties[mpiYoutubeViewCount] := StrToIntDef(lViewCount,0);
MediaItem.Properties[mpiYoutubeVideoID] := lYtCode;
if lStarsBackupText<>'' then
MediaItem.Properties[mpiRatingInStars] := GetStarsFromBackup(lYtCode, lStarsBackupText);
//MediaItem.Properties[mpiSeriesEpisodeNo] := i+1;
//MediaItem.Properties[mpiFileSize] := ;
//MediaItem.RetrieveProperties; //Получение свойств видеофайла (размер, длительность) ОЧЕНЬ МЕДЛЕННО!
end; //lYtCode<>''
end; //for
//DopVideoFolder[mpiFilePath]:=lYtCodes;
DopVideoFolder[mpiComment]:=lYtCodes;
finally
MainObj.Free;
end;
end;
function AddDopVideo(inParentFolder: THmsScriptMediaItem; inYtCode, inParentTitle, inParentNum: string):Integer;
var MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lUrl: string;
lEpisodeNum: string;
lDescription: string;
lYtCode, lYtCodes: string;
lTitle, lPublishedDate, lDuration, lThumbnail, lViewCOunt: string;
MediaItem: THmsScriptMediaItem;
downloadStr: string;
re: TRegExpr;
begin
MainObj := TJsonObject.Create();
try
lurl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [inYtCode, VER]);
downloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(downloadStr);
EntryObj := MainObj.O['items'];
ItemObj := EntryObj.AsArray.O[0];
lDescription := ItemObj.S['description'];
lYtCodes := '';
n := 0;
re := TRegExpr.Create('youtube\.com\/watch\?v\=(\S{11})|youtu\.be\/(\S{11})');
try
if re.Search(lDescription) then
repeat
n := n+1;
lYtCode := re.Match(1);
if (lYtCode='') then
lYtCode := re.Match(2);
lYtCodes := lYtCodes+','+lYtCode; //Собираем все коды доп.видео, чтобы получить сразу их все
if (n>=gpDopVideoMaxResults) then
break;
until not re.SearchAgain
finally
re.Free;
end;
addLog('Получение доп. видео: '+lYtCodes+' ('+inYtCode+')');
if (lYtCodes<>'') then
begin
lUrl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [lYtCodes, VER]);
CreateVideoItems_By_Json(inParentFolder, lUrl, inParentTitle, inParentNum, gpDopVideoPattern, 'off');
end;
finally
MainObj.Free;
Result:=n;
end;
end;
function CheckApp(inParentFolder: THmsScriptMediaItem):Integer;
var MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lUrl, downloadStr: string;
MediaItem: THmsScriptMediaItem;
lYtCode, lYtLink, lLink, lTitle, lComment, lPublishedDate, lThumbnail: string;
begin
lUrl :=Format('http://storvild.ru/yt.php?appcheck=1&app=%s', [VER]);
MainObj := TJsonObject.Create();
try
downloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(downloadStr);
if (MainObj.I['result']<=0) then
begin
Result:=MainObj.I['result'];
EntryObj := MainObj.O['items'];
ItemObj := EntryObj.AsArray.O[0];
lLink := ItemObj.S['url'];
lYtCode := ItemObj.S['videoId'];
lTitle := ItemObj.S['title'];
lPublishedDate := ItemObj.S['publishedAt'];
lComment := ItemObj.S['description'];
lThumbnail := ItemObj.S['thumbnail'];
MediaItem := HmsCreateMediaItem(lLink, inParentFolder.ItemID);
MediaItem.Properties[mpiTitle] := lTitle;
MediaItem.Properties[mpiCreateDate] := lPublishedDate; //Now;
MediaItem.Properties[mpiComment] := lComment;
MediaItem.Properties[mpiThumbnail] := lThumbnail;
end
else
begin
Result:= MainObj.I['result'];
end;
finally
MainObj.Free;
end;
end;
function GetStarsFromBackup(inYtCode, inText: string): integer;
var lExistStar: string;
begin
Result := NULL;
if HmsRegExMatch(inYtCode+'=(\d+)', inText, lExistStar) then
begin
Result := StrToInt(lExistStar);
end;
end;
procedure BackupStarsToFile();
var lStarsBackupTextOrig: string;
lStarsBackupTextNew: string;
begin
if gpStarsBackup='on' then
begin
if not FileExists(csStarsBackupFileName) then
HmsStringToFile('', csStarsBackupFileName); //Создаем файл если его не было
lStarsBackupTextOrig := HmsStringFromFile(csStarsBackupFileName);
lStarsBackupTextNew := CopyStarsToStringRec(FolderItem, lStarsBackupTextOrig);
if lStarsBackupTextOrig<>lStarsBackupTextNew then
HmsStringToFile(lStarsBackupTextNew, csStarsBackupFileName);
end;
end;
function CopyStarsToStringRec(inFolder: THmsScriptMediaItem; var inExistCodes: string): string;
var i: integer;
lMediaItem: THmsScriptMediaItem;
lYtCode: string;
s: string;
lExistStar: string;
lExistRpl: string;
lSeparate: string = chr(13)+chr(10);
begin
s := inExistCodes;
for i:=0 to inFolder.ChildCount-1 do
begin
lMediaItem := inFolder.ChildItems[i];
if lMediaItem.isFolder then
begin
if lMediaItem.ChildCount>0 then
begin
s := CopyStarsToStringRec(lMediaItem, s);
end;
end
else
begin
// Это не папка
if lMediaItem.Properties[mpiRatingInStars] <> NULL then
begin
//Здесь мы убираем существующие коды из s и добавляем в s новые
lYtCode := VarToStr(lMediaItem.Properties[mpiYoutubeVideoID]);
// Если нашли код, то проверяем совпадает ли оценка
if HmsRegExMatch(lYtCode+'=(\d+)', s, lExistStar) then //, PCRE_DOTALL+PCRE_MULTILINE
begin
if lMediaItem.Properties[mpiRatingInStars]<>lExistStar then
begin
if Pos(lSeparate+lYtCode+'='+lExistStar, s)>0 then
s := ReplaceStr(s, lSeparate+lYtCode+'='+lExistStar, '')
else
s := ReplaceStr(s, lYtCode+'='+lExistStar, '');
s := s+lSeparate+lYtCode+'='+ VarToStr(lMediaItem.Properties[mpiRatingInStars]);
end
end
else
s := s+lSeparate+lYtCode+'='+ VarToStr(lMediaItem.Properties[mpiRatingInStars]);
end;
end;
end;
Result := s;
end;
procedure CreatePlaylists(inFolder: THmsScriptMediaItem; inFilePath: string; inPageToken: string);
var playlistsFolder: THmsScriptMediaItem;
lfilepath, lcode, lcodeex: string;
lurl: string;
i: integer;
MainObj, EntryObj, ItemObj: TJsonObject;
ldownloadStr: string;
itemTitle, itemPlaylistId, itemChannelId, itemDescription, itemChannelTitle, itemPublished, itemThumbnail: string;
itemPosition: integer;
lNextPageToken: string;
lItemsPerPage, lItemsCount, lPageCount, lNextPage, lCurPage: integer;
lNextFolder: THmsScriptMediaItem;
lYear: string;
lTitleFormat: string;
lNum, lPosition: integer;
begin
lurl := '';
lfilepath := inFilePath;
lcode := '';
if HmsRegExMatch('channel\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'channel/'+lcode;
end
else if Pos('UC',lfilepath)=1 then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'channel/'+lfilepath;
end
else if HmsRegExMatch('user\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channel=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'user/'+lcode;
end
else if HmsRegExMatch('search\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else if HmsRegExMatch('search_query=([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lfilepath;
end;
MainObj := TJsonObject.Create();
try
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
lNextPage := 2;
lCurPage := 1;
if lNextPageToken<>'' then
begin
lNextFolder := inFolder.AddFolder(mpFilePath+'-'+IntToStr(lPageCount)); //Если AddFolder('') то папка не создается. Одинаковые имена типа '-' не подходят для создания более одной папки
//lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiFilePath] := lcodeex;
lNextFolder[mpiTitle] := 'Следующая страница '+IntToStr(lNextPage)+'/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
lNextFolder[mpiThumbnail] := '';
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := 'playlists';
lNextFolder[mpiYoutubeCode] := lcodeex;
lNextFolder[mpiYoutubeUrl] := inFilePath;
lNextFolder[mpiYoutubeCurPage] := IntToStr(lNextPage);
if log='on' then
lNextFolder[mpiComment] := VarToStr(lNextFolder[mpiYoutubeType])+'#'+VarToStr(lNextFolder[mpiYoutubeCode])+'#'+VarToStr(lNextFolder[mpiYoutubePageToken]);
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
itemTitle := ItemObj.S['title'];
itemPlaylistId := ItemObj.S['playlistId'];
itemChannelId := ItemObj.S['channelId'];
itemDescription := ItemObj.S['description'];
itemChannelTitle := ItemObj.S['channelTitle'];
itemThumbnail := ItemObj.S['thumbnail'];
itemPosition := ItemObj.I['position'];
itemPublished := ItemObj.S['publishedAt'];
lYear := Copy(itemPublished,1,4);
lNum := i+1+(lCurPage-1)*lItemsPerPage;
lPosition := itemPosition;
lTitleFormat := GetTitleByPattern(itemTitle, gpPlaylistPattern, lNum, lPosition, itemPublished);
playlistsFolder := inFolder.AddFolder(itemPlaylistId);
playlistsFolder[mpiFilePath] := 'http://www.youtube.com/playlist?list='+itemPlaylistId; //'http://www.youtube.com/playlist?list=PLIw_h2Az1xWYQjB3csaArQGjhTU3wbCbN';
//playlistsFolder := inFolder.AddFolder('http://www.youtube.com/playlist?list='+itemPlaylistId);
playlistsFolder[mpiTitle] := lTitleFormat;
playlistsFolder[mpiComment] := itemDescription;
playlistsFolder[mpiYoutubeCurPage] := 1;
playlistsFolder[mpiFolderSortOrder] := 'mpPartNo';
playlistsFolder[mpiYoutubeType] := 'playlist';
playlistsFolder[mpiYoutubeCode] := itemPlaylistId;
playlistsFolder[mpiYoutubePageToken] := '';
playlistsFolder[mpiThumbnail] := itemThumbnail;
playlistsFolder[mpiYoutubeChannelTitle] := itemChannelTitle;
playlistsFolder[mpiYoutubeChannelId] := itemChannelId;
playlistsFolder[mpiYoutubeDescription] := itemDescription;
playlistsFolder[mpiPartNo] := lNum;
playlistsFolder[mpiPartTotal] := lItemsCount;
playlistsFolder[mpiYear] := lYear;
playlistsFolder[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(itemChannelTitle));
playlistsFolder[mpiCreateDate] := GetPublishedDate(itemPublished);
end; //for
finally
MainObj.Free;
end;
end;
procedure CreateChannels(inFolder: THmsScriptMediaItem; inFilePath: string; inPageToken: string);
var channelsFolder: THmsScriptMediaItem;
lfilepath, lcode, lcodeex: string;
lurl: string;
i: integer;
MainObj, EntryObj, ItemObj: TJsonObject;
ldownloadStr: string;
itemTitle, itemChannelId, itemDescription, itemChannelTitle, itemPublished, itemThumbnail: string;
itemPosition: integer;
lNextPageToken: string;
lItemsPerPage, lItemsCount, lPageCount, lNextPage, lCurPage: integer;
lNextFolder: THmsScriptMediaItem;
lYear: string;
lTitleFormat: string;
lNum, lPosition: integer;
begin
lurl := '';
lfilepath := inFilePath;
lcode := '';
if HmsRegExMatch('search\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else if HmsRegExMatch('search_query=([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lfilepath;
end;
MainObj := TJsonObject.Create();
try
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
lNextPage := 2;
lCurPage := 1;
if lNextPageToken<>'' then
begin
lNextFolder := inFolder.AddFolder(mpFilePath+'-'+IntToStr(lPageCount)); //Если AddFolder('') то папка не создается. Одинаковые имена типа '-' не подходят для создания более одной папки
//lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiFilePath] := lcodeex;
lNextFolder[mpiTitle] := 'Следующая страница '+IntToStr(lNextPage)+'/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
lNextFolder[mpiThumbnail] := '';
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := 'channels';
lNextFolder[mpiYoutubeCode] := lcodeex;
lNextFolder[mpiYoutubeUrl] := inFilePath;
lNextFolder[mpiYoutubeCurPage] := IntToStr(lNextPage);
if log='on' then
lNextFolder[mpiComment] := VarToStr(lNextFolder[mpiYoutubeType])+'#'+VarToStr(lNextFolder[mpiYoutubeCode])+'#'+VarToStr(lNextFolder[mpiYoutubePageToken]);
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
itemTitle := ItemObj.S['title'];
itemChannelId := ItemObj.S['channelId'];
itemDescription := ItemObj.S['description'];
itemChannelTitle := ItemObj.S['channelTitle'];
itemThumbnail := ItemObj.S['thumbnail'];
itemPosition := ItemObj.I['position'];
itemPublished := ItemObj.S['publishedAt'];
lYear := Copy(itemPublished,1,4);
lNum := i+1+(lCurPage-1)*lItemsPerPage;
lPosition := itemPosition;
lTitleFormat := GetTitleByPattern(itemTitle, gpChannelPattern, lNum, lPosition, itemPublished);
channelsFolder := inFolder.AddFolder(itemChannelId);
channelsFolder[mpiFilePath] := 'http://www.youtube.com/channel/'+itemChannelId;
channelsFolder[mpiTitle] := lTitleFormat;
channelsFolder[mpiComment] := itemDescription;
channelsFolder[mpiYoutubeCurPage] := 1;
channelsFolder[mpiFolderSortOrder] := 'mpPartNo';
channelsFolder[mpiYoutubeType] := 'channelid';
channelsFolder[mpiYoutubeCode] := itemChannelId;
channelsFolder[mpiYoutubePageToken] := '';
channelsFolder[mpiThumbnail] := itemThumbnail;
channelsFolder[mpiYoutubeChannelTitle] := itemChannelTitle;
channelsFolder[mpiYoutubeChannelId] := itemChannelId;
channelsFolder[mpiYoutubeDescription] := itemDescription;
channelsFolder[mpiPartNo] := lNum;
channelsFolder[mpiPartTotal] := lItemsCount;
channelsFolder[mpiYear] := lYear;
channelsFolder[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(itemChannelTitle));
channelsFolder[mpiCreateDate] := GetPublishedDate(itemPublished);
end; //for
finally
MainObj.Free;
end;
end;
function GetTitleByPattern(inTitle, inPattern: string; inNum, inPosition: integer; inPublishedDate: string): string;
var lPattern: string;
lNum0, lPosition0: string;
lTitleFormat: string;
lPublishedDate: string;
begin
lTitleFormat := inTitle;
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom, gpReplaceTo);
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom2, gpReplaceTo2);
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom3, gpReplaceTo3);
lPattern := inPattern;
if trim(lPattern)<>'' then
begin
lNum0 := PadLeft(IntToStr(inNum),length(gpMaxResults),'0'); //lShowNum := FormatFloat('000',inNum+1)+' ';
lPosition0 := PadLeft(IntToStr(inPosition),length(gpMaxResults),'0');
lPattern := ReplacePattern(lPattern, 'title', lTitleFormat);
lPublishedDate := GetPublishedDate(inPublishedDate);
lPattern := ReplaceStr(lPattern, '{published}', Copy(lPublishedDate,1,10));
lPattern := ReplaceStr(lPattern, '{pubyear}', Copy(lPublishedDate,7,4));
lPattern := ReplaceStr(lPattern, '{pubmonth}', Copy(lPublishedDate,4,2));
lPattern := ReplaceStr(lPattern, '{pubday}', Copy(lPublishedDate,1,2));
lPattern := ReplaceStr(lPattern, '{num0}', lNum0);
lPattern := ReplaceStr(lPattern, '{num}', IntToStr(inNum));
lPattern := ReplaceStr(lPattern, '{position0}', lPosition0);
lPattern := ReplaceStr(lPattern, '{position}', IntToStr(inPosition));
lPattern := trimex(lPattern);
end
else
lPattern := lTitleFormat;
Result := lPattern;
end;
//=================== Главная программа =======================================//
var s: string;
lurl: string;
lfilepath: string;
reSearch1: TRegExpr;
b: boolean;
desc: string;
lYtCode: string;
ltype: string;
lcode: string;
lStarsBackupText: string;
TempFolder: THmsScriptMediaItem;
begin
//if log = 'on' then
// HmsLogMessage(1,'TEST'); //Лог
//RaiseException('RaiseTEST'); //Исключение
//Exit; //Выход из программы
InitParameters;
//Перед удалением сохраняем пользовательские рейтинги видео
BackupStarsToFile();
FolderItem.DeleteChildItems; //Удаление всех элементов
if (CheckApp(FolderItem)<=0) then
Exit;
if (mpTitle='') then
begin
addLogError('Ошибка: Заголовок (mpTitle) не должен быть пустым');
Exit;
end;
ltype := '';
lcode := '';
lfilepath:=mpFilePath;
//Ищем код по указанному пользователем типу в mpComment
if (SameText(mpComment,'channel') or SameText(mpComment,'user') or SameText(mpComment,'канал')) then
begin
if not HmsRegExMatch('user\/([^& \/]+)', lfilepath, lcode) then
lcode := lfilepath;
ltype := 'channel';
end
else if (SameText(mpComment,'channelid')) then
begin
if not HmsRegExMatch('channel\/([^& \/]+)', lfilepath, lcode) then
lcode := lfilepath;
ltype := 'channelid';
end
else if (SameText(mpComment,'playlist') or SameText(mpComment,'плейлист')) then
begin
if not HmsRegExMatch('list=([^& \/]+)', lfilepath, lcode) then
lcode := lfilepath;
ltype := 'playlist';
end
else if (SameText(mpComment,'video') or SameText(mpComment,'видео')) then
begin
//if not HmsRegExMatch('\/watch\?v\=(\S{11})|youtu\.be\/(\S{11})', lfilepath, lcode) then
if not HmsRegExMatch('\/watch\?v\=(\S{11})', lfilepath, lcode) then
if not HmsRegExMatch('youtu\.be\/(\S{11})', lfilepath, lcode) then
lcode := lfilepath;
ltype := 'video';
end
else if (SameText(mpComment,'q') or SameText(mpComment,'search') or SameText(mpComment,'поиск')) then
begin
if not HmsRegExMatch('search_query=([^& \/]+)', lfilepath, lcode) then
lcode := lfilepath;
ltype := 'search';
end
else if (SameText(mpComment,'playlists') or SameText(mpComment,'плейлисты')) then
begin
CreatePlaylists(FolderItem, mpFilePath, '');
Exit;
end
else if (SameText(mpComment,'channels') or SameText(mpComment,'каналы')) then
begin
CreateChannels(FolderItem, mpFilePath, '');
Exit;
end
else // Если тип не заполнен
begin
// Пытаемся определить тип и код из ссылки
if HmsRegExMatch('list=([^& \/]+)', lfilepath, lcode) then begin
ltype := 'playlist';
end
else if Pos('PL', lfilepath) then begin
lcode := lfilepath;
ltype := 'playlist';
end
else if HmsRegExMatch('channel\/([^& \/]+)', lfilepath, lcode) then begin
ltype := 'channelid';
end
else if HmsRegExMatch('user\/([^& \/]+)', lfilepath, lcode) then begin
ltype := 'channel';
end
else if Pos('UC', lfilepath)=1 then begin
lcode := lfilepath;
ltype := 'channel';
end
else if (HmsRegExMatch('youtube.*v=(\S{11})', lfilepath, lcode)) then begin
ltype := 'video';
end
else if HmsRegExMatch('youtu\.be\/(\S{11})', lfilepath, lcode) then begin //([^& \/]+)
ltype := 'video';
end
else if HmsRegExMatch('search_query=([^&]+)', lfilepath, lcode) then begin
ltype := 'search';
end
else if HmsRegExMatch('search\/([^&]+)', lfilepath, lcode) then begin
ltype := 'search';
end
else begin
//Если пользователь не указал тип, и по ссылке тип невозможно определить, то считаем что это канал с названием из mpTitle
lcode := mpTitle;
ltype := 'channel';
end;
end;
addLog('Получение списка видео: '+ltype+' с кодом: '+lcode);
if (ltype='channel') then
begin
lurl := Format('http://storvild.ru/yt.php?channel=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, VER]);
CreateVideoItems_By_Json(FolderItem, lurl, '', '', gpPattern, gpDopVideo, ltype, lcode);
end
else if (ltype='channelid') then
begin
lurl := Format('http://storvild.ru/yt.php?type=video&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, VER]);
CreateVideoItems_By_Json(FolderItem, lurl, '', '', gpPattern, gpDopVideo, ltype, lcode);
end
else if (ltype='playlist') then
begin
lurl := Format('http://storvild.ru/yt.php?playlistId=%s&maxResults=%d&app=%s', [lcode, gpMaxResults, VER]);
CreateVideoItems_By_Json(FolderItem, lurl, '', '', gpPattern, gpDopVideo, ltype, lcode);
end
else if (ltype='video') then
begin
lYtCode := lfilepath;
lurl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [lcode, VER]);
CreateVideoItems_By_Json(FolderItem, lurl, '', '', gpPattern, gpDopVideo, ltype, lcode);
end
else if (ltype='search') then
begin
//lcode := HmsHttpEncode(lcode); //Не работает
lcode := ReplaceStr(lcode, ' ', '+');
lcode := ReplaceStr(lcode, '&', '%26');
lcode := ReplaceStr(lcode, '/', '%2F');
lcode := ReplaceStr(lcode, '%', '%25');
//lcode := ReplaceStr(lcode, '+', '%2B');
lurl := Format('http://storvild.ru/yt.php?type=video&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, VER]);
CreateVideoItems_By_Json(FolderItem, lurl, '', '', gpPattern, gpDopVideo, ltype, lcode);
end
else
begin
addLogError('Ошибка: Не определен тип ссылки...');
end;
end.
531
PascalScript
550
// [GetLink] Скрипт получения ссылки на видео, а также "Следующая страница", "Дополнительные видео"
// Made By Vadim_S, http://storvild.ru
const
VER = 'HMSL.3.0.19.beta'; //Версия скрипта. Передается в запросах.
csSiteLink = 'HMS'; //Приложение. Передается как http_referer
INTERNET_FLAG_NO_COOKIES = $00080000; { no automatic cookie handling }
INTERNET_FLAG_NO_AUTO_REDIRECT = $00200000;
INTERNET_FLAG_RELOAD = $80000000;
mpiYoutubePageToken = 141206;
mpiYoutubeType = 141207;
mpiYoutubeCode = 141208;
mpiYoutubeUrl = 141209;
mpiYoutubeCurPage = 141210;
mpiYoutubeTTSUrl = 141211;
mpiYoutubeVideoHeight = 141212;
mpiYoutubeVideoID = 141213;
mpiYoutubeViewCount = 141214;
mpiYoutubeDuration = 141215;
mpiYoutubeDescription = 141216;
mpiYoutubeChannelTitle= 141217;
mpiYoutubeChannelId = 141218;
mpiYoutubeRating = 141219;
var
// Глобальные переменные
csStarsBackupFileName: string = HmsDataDirectory+'\hms_stars.backup';
gpSafeSearch: string = 'moderate'; //Показывать ли закрытый контент. none | moderate | strict
gpMaxResults: Integer = 25; //Кол-во результатов на страницу 1-50
gpOrderBy: string = 'date'; // date | rating | relevance | title | viewCount
gpPublishedAfter: string = ''; //Найти видео до указанной даты '2014-02-23T00:00:00Z'
gpPublishedBefore: string = ''; //Найти видео после указанной даты '2015-03-01T00:00:00Z'
gpRelevanceLanguage: string = ''; // Язык роликов ('ru', 'en')
gpVideoDimension: string = 'any'; // any | 2d | 3d
gpVideoDefinition: string = 'any'; // Качество (any | high | standard)
gpVideoDuration: string = 'any'; // Длина видео (any | long | medium | short)
gpReplaceFrom: string = '';
gpReplaceTo: string = '';
gpReplaceFrom2: string = '';
gpReplaceTo2: string = '';
gpReplaceFrom3: string = '';
gpReplaceTo3: string = '';
gpPattern: string = '[{num}] {title} ({published})'; //num, title, published, year, month, day
gpPlaylistPattern: string = '';
gpChannelPattern: string = '';
gpDopVideo: string = 'off';
gpDopVideoPattern: string = '{num} {title} ({published})';
gpDopVideoMaxResults: Integer = 25; //Максимальное кол-во доп.видео 1-50
gpDopVideoInFolder: string = 'on';
gpDelEmptyBrackets: string = 'off';
gpMaxHeight: string = '1080'; //Без этого значения неправильно получается ссылка субтитров от WendyH
gpSubtitles: string = 'off';
gpSubLanguage: string = 'ru';
gpAdaptive: string = 'off';
gpGetFileSize: string = 'off';
gpGetTimeLength: string = 'on';
gpStarsBackup: string = 'on';
log: string = 'off';
logError: string = 'on';
// Инициализация глобальных переменных из mpPodcastParameters
procedure InitParameters;
begin
gpMaxResults := StrToIntDef(GetPodcastParam('--maxresults', ''), gpMaxResults); //25
gpSafeSearch := GetPodcastParam('--safesearch', gpSafeSearch); // moderate (none | moderate | strict)
gpOrderBy := GetPodcastParam('--orderby', gpOrderBy); // date (date | rating | relevance | title | viewCount)
gpPublishedAfter := GetPodcastParam('--publishedafter', gpPublishedAfter); //Найти видео до указанной даты '2014-02-23T00:00:00Z'
gpPublishedBefore := GetPodcastParam('--publishedbefore', gpPublishedBefore); //Найти видео после указанной даты '2015-03-01T00:00:00Z'
gpRelevanceLanguage := GetPodcastParam('--relevancelanguage', gpRelevanceLanguage); // Язык роликов ('ru')
gpVideoDimension := GetPodcastParam('--videodimension', gpVideoDimension); // any | 2d | 3d
gpVideoDefinition := GetPodcastParam('--videodefinition', gpVideoDefinition); // Качество (any | high | standard)
gpVideoDuration := GetPodcastParam('--videoduration', gpVideoDuration); // Длина видео (any | long | medium | short)
gpReplaceFrom:= GetPodcastParam('--replacefrom', gpReplaceFrom); // ''
gpReplaceTo := GetPodcastParam('--replaceto', gpReplaceTo); // ''
gpReplaceFrom2:= GetPodcastParam('--replacefrom2', gpReplaceFrom2); // ''
gpReplaceTo2 := GetPodcastParam('--replaceto2', gpReplaceTo2); // ''
gpReplaceFrom3:= GetPodcastParam('--replacefrom3', gpReplaceFrom3); // ''
gpReplaceTo3 := GetPodcastParam('--replaceto3', gpReplaceTo3); // ''
gpPattern := GetPodcastParam('--pattern', gpPattern); // '[{num}] {title} {published}' (pubyear,pubmonth,pubday)
gpPlaylistPattern := GetPodcastParam('--playlistpattern', gpPlaylistPattern); // ''
gpChannelPattern := GetPodcastParam('--channelpattern', gpPlaylistPattern); // ''
gpDopVideo := GetPodcastParam('--dopvideo', gpDopVideo); // off (on | off)
gpDopVideoPattern := GetPodcastParam('--dopvideopattern', gpDopVideoPattern); // '[{parentnum}] {parenttitle,10} {num} {title}'
gpDelEmptyBrackets := GetPodcastParam('--delemptybrackets', gpDelEmptyBrackets); // off (on | off)
gpDopVideoInFolder := GetPodcastParam('--dopvideoinfolder', gpDopVideoInFolder); // on (on | off)
gpDopVideoMaxResults := StrToIntDef(GetPodcastParam('--dopvideomaxresults', ''), gpDopVideoMaxResults); //25
gpMaxHeight := GetPodcastParam('--maxheight', gpMaxHeight);
gpSubLanguage := GetPodcastParam('--sublanguage', gpSubLanguage);
gpSubtitles := GetPodcastParam('--subtitles', gpSubLanguage);
gpAdaptive := GetPodcastParam('--adaptive', gpAdaptive);
gpGetFileSize := GetPodcastParam('--getfilesize', gpGetFileSize);
gpGetTimeLength := GetPodcastParam('--gettimelength', gpGetTimeLength);
gpStarsBackup := GetPodcastParam('--starsbackup', gpStarsBackup); // on (on | off)
log := GetPodcastParam('--log', log); //off (on | off)
logError := GetPodcastParam('--logerror',logError); //on (on | off)
end;
//=========================== Общие функции ==================================
//
// Получение параметра aParamName, а если его нет то подставляется значение по умолчанию aDefaultValue
function GetPodcastParam(const aParamName, aDefaultValue: string): string;
begin
Result := ExtractParam(mpPodcastParameters, aParamName);
if Result = '' then Result := aDefaultValue
end;
//Загрузка контента по указанному URL. Запрос преобразуется в Utf8, Ответ из Utf8
function DownloadUrl(const aUrl: string): string;
var
iPort: Integer;
sHeader, sReferer, sServer, sObject, sProtocol: string;
begin
aUrl := HmsUtf8Encode(aUrl); //Преобразование ссылки в UTF-8
if HmsRegExMatch3('http(.?)://([^/]*)(/.*)?', aUrl, sProtocol, sServer, sObject) then
begin
if sObject = '' then sObject := '/';
if sProtocol = 's' then iPort := 443 else iPort := 80;
sReferer := csSiteLink + #13#10 + 'Accept: */*'#13#10'Accept-Encoding: gzip,deflate';
Result := HmsSendRequestEx(sServer, sObject, 'GET', '', sReferer, '', iPort,
INTERNET_FLAG_NO_COOKIES or INTERNET_FLAG_RELOAD, sHeader, True);
if (Result <> '') and (Ord(Result[1]) = 31) then
Result := HmsDecompressString(Result);
end
else if Pos('http', aUrl) = 1 then
Result := HmsDownloadUrl(aUrl)
else
Result := '';
Result := HmsUtf8Decode(Result); //Преобразование результата из UTF-8
end;
//Регистронезависимая замена текста в строке
function ReplaceStrI(const cStr1, cSrch, cReplace: String): String;
var sLowerSrch, sTempStr, sResultStr: string;
i: integer;
begin
sResultStr := '';
sLowerSrch := Lowercase(cSrch);
sTempStr := cStr1;
while Pos(sLowerSrch, Lowercase(sTempStr))>0 do
begin
i := Pos(sLowerSrch, Lowercase(sTempStr));
sResultStr := sResultStr+Copy(sTempStr, 1, i-1)+cReplace;
Delete(sTempStr,1, i-1+Length(sLowerSrch));
end;
sResultStr := sResultStr+sTempStr;
Result := sResultStr;
end;
// Получение даты в форомате 31.12.2015 из 2015-12-31T00:00:00Z
function GetPublishedDate(const aValue: string): string;
begin
Result:=Copy(aValue,9,2)+'.'+Copy(aValue,6,2)+'.'+Copy(aValue,1,4);
end;
//Заменяет в шаблоне параметр в фигурных скобках {title}. Если параметр {title,10}, то укорачивает до 10 символов
function ReplacePattern(inPattern, inParamName, inParamValue: string): string;
var mparam, mparamcount_str: string;
mparamcount: Integer;
pvshort: string;
res: string;
lParamValue: string;
begin
//Если в шаблоне используется ограничение по размеру текста {title,10}
if HmsRegExMatch2('({'+inParamName+',\s*(\d+)})', inPattern, mparam, mparamcount_str) then
begin
res := inPattern;
lParamValue := inParamValue;
mparamcount := StrToInt(mparamcount_str);
if (mparamcount>=0) and (length(lParamValue)>mparamcount) then
lParamValue := Copy(lParamValue,1,mparamcount)+'...';
if (gpDelEmptyBrackets='on') then
res := ReplaceStr(res, '['+mparam+']', lParamValue);
res := ReplaceStr(res, mparam, lParamValue);
end
else
begin
res := inPattern;
lParamValue := inParamValue;
//Замена параметра в фигурных скобках
res := ReplaceStr(res, '{'+inParamName+'}', lParamValue);
//Если в настройках стоит Удалять пустые квадратные скобки, то удаляем их
if (gpDelEmptyBrackets='on') then
res := ReplaceStr(res, '[]', '');
end;
Result := res;
end;
//Удаляет двойные пробелы и переводы строк (заменяет пробелами)
function trimex(inText: string): string;
begin
if (pos(' ',inText)>0) or (pos(#13,inText)>0) or (pos(#10,inText)>0) then
begin
Result := ReplaceStr(inText, ' ', ' ');
Result := ReplaceStr(Result, #13, ' ');
Result := ReplaceStr(Result, #10, ' ');
Result := trimex(Result);
end
else
Result := trim(inText);
end;
// Округление в большую сторону
function Ceil(inVal: Extended): Integer;
begin
Result:=Int(inVal);
if (Int(inVal)<inVal) then
Result := Result+1;
end;
//Округление до нужного знака
function RoundTo(inVal: Extended; inPrecision: Integer): Extended;
var lPow: Extended;
begin
// Result := Exp(Y*Ln(X)); // X^Y
lPow := Exp(inPrecision*Ln(10));
Result := Round(inVal*lPow)/lPow;
end;
//Преобразование секунд во время в формате: 00:01:31.000
function GetTimeLength(const aValue: string): string;
var
eDuration: Extended;
begin
eDuration := StrToFloatDef(aValue, 0);
if eDuration > 0 then
Result := FormatDateTime('HH:NN:SS.ZZZ', eDuration / (24 * 60 * 60))
else
Result := '';
end;
procedure addLog(inMsg: string; inTimeON: boolean = true);
var TimeStr: string = '';
begin
if (log='on') then
begin
if inTimeON then
TimeStr := FormatDateTime('HH:NN:SS.ZZZ',Now())+' ';
HmsLogMessage(1, TimeStr+' '+inMsg);
end;
end;
procedure addLogError(inMsg: string; inTimeON: boolean = true);
var TimeStr: string = '';
begin
if (logError='on') then
begin
if inTimeON then
TimeStr := FormatDateTime('HH:NN:SS.ZZZ',Now())+' ';
HmsLogMessage(2, TimeStr+' '+inMsg);
end;
end;
//======================= Фукции обработки папок и видео =====================//
// Получение реальной ссылки на видео и добавление субтитров // By WendyH
function GetLinkYoutube3: string;
var sData, sSubtitlesUrl, sFile, sVal, sMsg: string;
sVideoID: string = '';
sAudio: string = '';
JSON: TJsonObject;
bNotDE: boolean;
sLink: string;
sHeight: string;
begin
Result := '';
sLink := mpFilePath; //PodcastItem[mpiFilePath];
addLog('Начало получения: '+PodcastItem[mpiTitle]);
//Получаем VideoId из переданной ссылки sLink (mpFilePath)
if (not HmsRegExMatch('[\\?&]v=([^&]+)' , sLink, sVideoID)) then
HmsRegExMatch('/(?:embed|v)/([^\\?]+)', sLink, sVideoID);
if (sVideoID = '') then
begin
addLogError('Невозможно получить Video ID в ссылке Youtube');
Exit;
end;
//Быстрое получение, без настроек
//Result := HmsDownloadUrl('http://hms.lostcut.net/youtube/g.php?link_only=1&v='+sVideoID);
//Exit;
bNotDE := (Pos('notde=1', sLink)>0);
sLink := 'http://hms.lostcut.net/youtube/g.php?v='+sVideoID;
if (gpMaxHeight<>'' ) then sLink := sLink+'&max_height='+gpMaxHeight;
if (Trim(mpPodcastMediaFormats )<>'') then sLink := sLink+'&media_formats='+mpPodcastMediaFormats;
if (gpAdaptive='on' ) then sLink := sLink+'&adaptive=1';
if (bNotDE ) then sLink := sLink+'¬de=1';
sData := HmsDownloadUrl(sLink);
// При ошибке в json - выдавать
if (HmsRegExMatch('"reason":"(.*?)"' , sData, sMsg)) then
begin
addLog(sMsg);
Exit;
end;
JSON := TJsonObject.Create();
try
JSON.LoadFromString(sData);
Result := JSON.S['url'];
sSubtitlesUrl := JSON.S['ttsUrl'];
sAudio := JSON.S['audio'];
sHeight := JSON.S['height'];
PodcastItem[mpiYoutubeTTSUrl] := sSubtitlesUrl;
PodcastItem[mpiYoutubeVideoHeight] := StrToIntDef(sHeight,0);
if (sAudio<>'') then
Result := Format('-i "%s" -i "%s"', [Result, sAudio]);
finally
JSON.Free();
end;
if (Pos('m3u8', Result)>0) then
Result := ' '+Trim(Result);
addLog('Получено видео: '+sHeight+'p url:'+Result);
// Если есть субтитры и в дополнительных параметрах указано их показывать - загружаем
if ((gpSubtitles='on') and (sSubtitlesUrl<>'')) then
begin
sFile := HmsSubtitlesDirectory+'\Youtube\'+PodcastItem.ItemID+'.'+gpSubLanguage+'.srt';
sLink := sSubtitlesUrl+'&format=srt&lang=';
addLog('Субтитры: '+sLink+gpSubLanguage);
if (not HmsDownloadURLToFile(sLink+gpSubLanguage, sFile, 'Accept-Encoding: gzip, deflate')) then
begin
//Если не найдены субтитры с необходимым языком загружать английские
HmsDownloadURLToFile(sLink+'en', sFile, 'Accept-Encoding: gzip, deflate');
end;
addLog('Субтитры сохранены в : '+sFile);
PodcastItem[mpiSubtitleLanguage] := sFile;
end;
end;
function GetStarsFromBackup(inYtCode, inText: string): integer;
var lExistStar: string;
begin
Result := NULL;
if HmsRegExMatch(inYtCode+'=(\d+)', inText, lExistStar) then
begin
Result := StrToInt(lExistStar);
end;
end;
//Создание списка видео в указанной папке по параметрам
// inType, inCode используются для занесения в раздел "Следующая страница"
procedure CreateVideoItems_By_Json(inParentFolder: THmsScriptMediaItem; inUrl, inPattern: string; inType: string = ''; inCode: string = '');
var MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lurl: string;
lYtCode, lYtLink, lTitle, lPublishedDate, lDuration, lThumbnail, lViewCount,
lChannelTitle, lChannelId, lNumRaters, lDescription, lFirstReleased, lYear: string;
lShowNum: string = '';
MediaItem: THmsScriptMediaItem;
lPattern: string;
lComment: string;
lTitleFormat: string;
ldownloadStr: string;
lNextFolder: THmsScriptMediaItem;
lNextPageToken: string;
lItemsPerPage, lItemsCount, lPageCount, lNextPage, lCurPage: integer;
lStarsBackupText: string;
lNum, lPosition: integer;
lPublishedDateFormat: string;
begin
MainObj := TJsonObject.Create();
lurl := inUrl;
if gpStarsBackup='on' then
begin
lStarsBackupText := HmsStringFromFile(csStarsBackupFileName);
end;
try
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
lNextPage := inParentFolder[mpiYoutubeCurPage]+1;
lCurPage := inParentFolder[mpiYoutubeCurPage];
if lNextPageToken<>'' then
begin
lNextFolder := inParentFolder.AddFolder(mpFilePath+'_');
lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiTitle] := 'Следующая страница '+IntToStr(lNextPage)+'/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
lNextFolder[mpiPartNo] := 1;
lNextFolder[mpiThumbnail] := '';
if log='on' then
lNextFolder[mpiComment] := mpComment+' --pageToken='+lNextPageToken;
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := inType;
lNextFolder[mpiYoutubeCode] := inCode;
lNextFolder[mpiYoutubeUrl] := inUrl;
lNextFolder[mpiYoutubeCurPage] := IntToStr(lNextPage);
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
lYtCode := ItemObj.S['videoId'];
if lYtCode<>'' then
begin
lYtLink := 'http://www.youtube.com/watch?v='+lYtCode;
lPublishedDate := ItemObj.S['publishedAt'];
lPublishedDateFormat := GetPublishedDate(lPublishedDate);
lThumbnail := ItemObj.S['thumbnail'];
lChannelTitle := ItemObj.S['channelTitle'];
lChannelId := ItemObj.S['channelId'];
lDescription := ItemObj.S['description'];
lDuration := ItemObj.S['duration'];
lYear := Copy(ItemObj.S['publishedAt'],1,4);
lViewCount := ItemObj.S['viewCount'];
lComment := lDescription+#13#10+'Канал: '+lChannelTitle;
if lViewCount<>'' then
lComment := lComment+#13#10+'Кол-во просмотров на Youtube: '+lViewCount;
lNum := (lCurPage-1)*lItemsPerPage+i+1;
lPosition := i+1;
lShowNum := PadLeft(IntToStr(i+1),length(gpMaxResults),'0'); //lShowNum := FormatFloat('000',i+1)+' ';
lTitle := ItemObj.S['title'];
lTitleFormat := GetTitleByPattern(lTitle, inPattern, lNum, lPosition, lPublishedDate);
MediaItem := HmsCreateMediaItem(lYtLink, inParentFolder.ItemID);
MediaItem.Properties[mpiTitle] := lTitleFormat;
MediaItem.Properties[mpiCreateDate] := lPublishedDateFormat; //Now;
MediaItem.Properties[mpiComment] := lComment;
MediaItem.Properties[mpiThumbnail] := lThumbnail;
MediaItem.Properties[mpiTimeLength] := GetTimeLength(lDuration);
MediaItem.Properties[mpiPartNo] := lNum;
MediaItem.Properties[mpiPartTotal] := lItemsCount;
MediaItem.Properties[mpiYear] := lYear;
MediaItem.Properties[mpiProducer] := lChannelTitle;
MediaItem.Properties[mpiProgramID] := lViewCount;
MediaItem.Properties[mpiYoutubeChannelTitle] := lChannelTitle;
MediaItem.Properties[mpiYoutubeChannelId] := lChannelId;
MediaItem.Properties[mpiYoutubeDescription] := lDescription;
MediaItem.Properties[mpiYoutubeDuration] := StrToIntDef(lDuration,0);
MediaItem.Properties[mpiYoutubeViewCount] := StrToIntDef(lViewCount,0);
MediaItem.Properties[mpiYoutubeVideoID] := lYtCode;
if lStarsBackupText<>'' then
begin
MediaItem.Properties[mpiRatingInStars] := GetStarsFromBackup(lYtCode, lStarsBackupText);
end;
addLog('Добавлено видео: '+lYtCode);
end; //lYtCode<>''
end; //for
finally
MainObj.Free;
end;
end;
// Создание Доп.видео при нажатии на папку с этим дополнительным видео
procedure CreateDopVideo(inFolder: THmsScriptMediaItem);
var MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lUrl: string;
lEpisodeNum: string;
lDescription: string;
lCurYtCode, lYtCode, lYtCodes: string;
lTitle, lPublishedDate, lDuration, lThumbnail, lViewCOunt: string;
MediaItem: THmsScriptMediaItem;
downloadStr: string;
re: TRegExpr;
begin
HmsRegExMatch('youtube.*v=([^& ]+)', VarToStr(inFolder[mpiFilePath]), lCurYtCode);
MainObj := TJsonObject.Create();
try
lurl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [lCurYtCode, VER]);
downloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(downloadStr);
EntryObj := MainObj.O['items'];
ItemObj := EntryObj.AsArray.O[0];
lDescription := ItemObj.S['description'];
lYtCodes := '';
n := 0;
re := TRegExpr.Create('youtube\.com\/watch\?v\=(\S{11})|youtu\.be\/(\S{11})');
try
if re.Search(lDescription) then
repeat
n := n+1;
lYtCode := re.Match(1);
if (lYtCode='') then
lYtCode := re.Match(2);
lYtCodes := lYtCodes+','+lYtCode; //Собираем все коды доп.видео, чтобы получить сразу их все
if (n>=gpDopVideoMaxResults) then
break;
until not re.SearchAgain
finally
re.Free;
end;
addLog('Получение доп. видео: '+lYtCodes+' ('+lCurYtCode+')');
if (lYtCodes<>'') then
begin
lUrl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [lYtCodes, VER]);
CreateVideoItems_By_Json(inFolder, lUrl, gpDopVideoPattern, 'video', lYtCodes);
end;
finally
MainObj.Free;
end;
end;
// Создание папок для Доп.видео (без самих видео)
procedure CreateDopVideoFolders(inFolder: THmsScriptMediaItem);
var lDopFolder: THmsScriptMediaItem;
MainObj, EntryObj, ItemObj: TJsonObject;
i,j,k,n: integer;
lUrl: string;
downloadStr: string;
re: TRegExpr;
lDescription: string;
lCurYtVideos, lYtCode, lYtCodes: string;
lTitle: string;
lParentFolder: THmsScriptMediaItem;
lMediaItem, newFolder: THmsScriptMediaItem;
begin
lParentFolder := inFolder.ItemParent;
for i:=0 to lParentFolder.ChildCount-1 do
begin
if not lParentFolder.ChildItems[i].IsFolder then
begin
lMediaItem := lParentFolder.ChildItems[i];
if (gpDopVideoInFolder='on') then
begin
newFolder := inFolder.AddFolder(lMediaItem[mpiFilePath]);
newFolder[mpiTitle] := lMediaItem[mpiTitle];
//newFolder[mpiComment] := '#dopvideo#';
newFolder[mpiYoutubeCurPage] := '1';
newFolder[mpiYoutubeType] := 'dopvideo';
end;
end;
end;
end;
// Создание списка видео в указанной папке в зависимости от типа и кода
procedure CreateVideos(inFolder: THmsScriptMediaItem; inType, inCode, inPageToken: string);
var lurl: string;
lDopFolder: THmsScriptMediaItem;
begin
addLog('Получение списка видео: '+inType+' с кодом: '+inCode+' pageToken='+inPageToken);
if inCode=NULL then
inCode := '';
if (inType='channel') then
begin
lurl := Format('http://storvild.ru/yt.php?channel=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[inCode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, inPageToken, VER]);
CreateVideoItems_By_Json(inFolder, lurl, gpPattern, inType, inCode);
end
else if (inType='channelid') then
begin
lurl := Format('http://storvild.ru/yt.php?type=video&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[inCode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, inPageToken, VER]);
CreateVideoItems_By_Json(inFolder, lurl, gpPattern, inType, inCode);
end
else if (inType='playlist') then
begin
lurl := Format('http://storvild.ru/yt.php?playlistId=%s&maxResults=%d&pageToken=%s&app=%s',
[inCode, gpMaxResults, inPageToken, VER]);
CreateVideoItems_By_Json(inFolder, lurl, gpPattern, inType, inCode);
end
else if (inType='video') then
begin
lurl := Format('http://storvild.ru/yt.php?videoId=%s&pageToken=%s&app=%s',
[inCode, inPageToken, VER]);
CreateVideoItems_By_Json(inFolder, lurl, gpPattern, inType, inCode);
end
else if (inType='search') then
begin
lurl := Format('http://storvild.ru/yt.php?type=video&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&videoDimension=%s&gpVideoDefinition=%s&videoDuration=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[inCode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpVideoDimension, gpVideoDefinition, gpVideoDuration, gpRelevanceLanguage, inPageToken, VER]);
CreateVideoItems_By_Json(inFolder, lurl, gpPattern, inType, inCode);
end
else
begin
addLogError('Ошибка: Не определен тип ссылки...');
end;
//Создание папки Домолнительные материалы
if (gpDopVideo='on') then
begin
lDopFolder := inFolder.AddFolder('Дополнительные видео '+IntToStr(inFolder[mpiYoutubeCurPage]));
lDopFolder[mpiFolderSortOrder] := 'mpPartNo';
//lDopFolder[mpiYoutubeCurPage] := inFolder[mpiYoutubeCurPage];
end;
end;
// Получение размера файла //By WendyH
function UpdateVideoFileSize: integer;
var
sServ, sLink, sHeaders: string; iPort: Integer;
begin
iPort := 80;
if LeftCopy(Trim(MediaResourceLink), 5)='https' then
iPort := 443;
if HmsRegExMatch2('//(.*?)(/.*)', MediaResourceLink, sServ, sLink) then
begin
HmsSendRequestEx(sServ, sLink, 'HEAD', '', '', '', iPort, 0, sHeaders, true);
HmsRegExMatch('Content-Length: (\d+)' , sHeaders, PodcastItem[mpiFileSize]);
HmsRegExMatch('Content-Type: (.*?)'#13, sHeaders, PodcastItem[mpiMimeType]);
Result := StrToIntDef(PodcastItem[mpiFileSize],0);
end;
end;
function GetVideoId(inPodcastItem: THmsScriptMediaItem): string;
var sVideoId: string;
begin
sVideoId := VarToStr(inPodcastItem[mpiYoutubeVideoID]);
if (sVideoId = '') and (HmsRegExMatch('/watch\?v=([^&]+)', inPodcastItem[mpiFilePath], sVideoID)) then
inPodcastItem[mpiYoutubeVideoID] := sVideoID;
Result := sVideoId;
end;
// Получение информации о видео в виде строки
function GetVideoInfo(inVideoId: string): string;
var csMobileUserAgent, csGetVideoInfoLink: string;
sVideoInfo: string;
begin
csMobileUserAgent := 'Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25';
csGetVideoInfoLink := 'https://www.youtube.com/get_video_info?eurl=%s&video_id=%s&el=embedded&sts=16100&has_verified=1';
sVideoInfo := DownloadUrl(Format(csGetVideoInfoLink, [HmsHttpEncode('http://m.youtube.com/watch?v='+inVideoId), inVideoId]));
Result := sVideoInfo;
end;
// Обновление доп.полей из информации inVideoInfo (viewCount, Rating, Author, ChannelId)
function UpdateFromVideoInfo(inVideoInfo: string): boolean;
var lViewCount, lAvgRating, lChannelTitle, lChannelId: string;
begin
if HmsRegExMatch('view_count=([^&]*)', inVideoInfo, lViewCount) then
PodcastItem[mpiYoutubeViewCount] := StrToIntDef(lViewCount,0);
if HmsRegExMatch('avg_rating=([^&]*)', inVideoInfo, lAvgRating) then
PodcastItem[mpiYoutubeRating] := RoundTo(StrToFloatDef(lAvgRating,0),2);
if HmsRegExMatch('author=([^&]*)', inVideoInfo, lChannelTitle) then
PodcastItem[mpiYoutubeChannelTitle] := HmsUtf8Decode(HmsHttpDecode(lChannelTitle));
if HmsRegExMatch('ucid=([^&]*)', inVideoInfo, lChannelId) then
PodcastItem[mpiYoutubeChannelId] := HmsHttpDecode(lChannelId);
//PodcastItem.Properties[mpiRatingInStars] := Round(PodcastItem[mpiYoutubeRating]); //Рейтинг может проставлять пользователь
PodcastItem.Properties[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(lChannelTitle));
PodcastItem.Properties[mpiProgramID] := lViewCount;
end;
//Обновление времени ролика из VideoInfo
function UpdateVideoTimeLength(inVideoInfo: string): integer;
var sTimeLength: string;
begin
if HmsRegExMatch('length_seconds=([^&]*)', inVideoInfo, sTimeLength) then
sTimeLength := HmsHttpDecode(sTimeLength);
if sTimeLength<>'' then
PodcastItem[mpiTimeLength] := GetTimeLength(sTimeLength);
Result := StrToIntDef(sTimeLength,0);
end;
//Обновление времени с сайта storvild.ru
function UpdateVideoTimeLength2: integer;
var MainObj, EntryObj, ItemObj: TJsonObject;
lurl, downloadStr: string;
lYtCode, lTimeLength: string;
begin
MainObj := TJsonObject.Create();
try
HmsRegExMatch('youtube.*v=([^& ]+)', PodcastItem[mpiFilePath], lYtCode);
lurl := Format('http://storvild.ru/yt.php?videoId=%s&app=%s', [lYtCode, VER]);
downloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(downloadStr);
EntryObj := MainObj.O['items'];
ItemObj := EntryObj.AsArray.O[0];
lTimeLength := ItemObj.S['duration'];
PodcastItem[mpiTimeLength] := GetTimeLength(lTimeLength);
Result := StrToIntDef(lTimeLength, 0);
finally
MainObj.Free;
end;
end;
procedure CreatePlaylists(inFolder: THmsScriptMediaItem; inFilePath: string; inPageToken: string);
var playlistsFolder: THmsScriptMediaItem;
lfilepath, lcode, lcodeex: string;
lurl: string;
i: integer;
MainObj, EntryObj, ItemObj: TJsonObject;
ldownloadStr: string;
playlistId: string;
itemTitle, itemPlaylistId, itemChannelId, itemDescription, itemChannelTitle, itemPublished, itemThumbnail: string;
itemPosition: integer;
lNextPageToken: string;
lItemsPerPage, lItemsCount, lPageCount, lNextPage, lCurPage: integer;
lNextFolder: THmsScriptMediaItem;
lYear: string;
lTitleFormat: string;
lNum, lPosition: integer;
begin
lurl := '';
lfilepath := inFilePath;
lcode := '';
if HmsRegExMatch('channel\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'channel/'+lcode;
end
else if Pos('UC',lfilepath)=1 then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channelId=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'channel/'+lfilepath;
end
else if HmsRegExMatch('user\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&channel=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'user/'+lcode;
end
else if HmsRegExMatch('search\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else if HmsRegExMatch('search_query=([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else
begin
lurl := Format('http://storvild.ru/yt.php?type=playlist&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lfilepath;
end;
MainObj := TJsonObject.Create();
try
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
lNextPage := inFolder[mpiYoutubeCurPage]+1;
lCurPage := inFolder[mpiYoutubeCurPage];
if lNextPageToken<>'' then
begin
lNextFolder := inFolder.AddFolder(mpFilePath+'-'+IntToStr(lPageCount)); //Если AddFolder('') то папка не создается. Одинаковые имена типа '-' не подходят для создания более одной папки
lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiTitle] := 'Следующая страница '+IntToStr(lNextPage)+'/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
lNextFolder[mpiThumbnail] := '';
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := 'playlists';
lNextFolder[mpiYoutubeCode] := lcodeex;
lNextFolder[mpiYoutubeUrl] := inFilePath;
lNextFolder[mpiYoutubeCurPage] := IntToStr(lNextPage);
if log='on' then
lNextFolder[mpiComment] := VarToStr(lNextFolder[mpiYoutubeType])+'#'+VarToStr(lNextFolder[mpiYoutubeCode])+'#'+VarToStr(lNextFolder[mpiYoutubePageToken]);
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
itemTitle := ItemObj.S['title'];
itemPlaylistId := ItemObj.S['playlistId'];
itemChannelId := ItemObj.S['channelId'];
itemDescription := ItemObj.S['description'];
itemChannelTitle := ItemObj.S['channelTitle'];
itemThumbnail := ItemObj.S['thumbnail'];
itemPosition := ItemObj.I['position'];
itemPublished := ItemObj.S['publishedAt'];
lYear := Copy(itemPublished,1,4);
lNum := i+1+(lCurPage-1)*lItemsPerPage;
lPosition := itemPosition;
lTitleFormat := GetTitleByPattern(itemTitle, gpPlaylistPattern, lNum, lPosition, itemPublished);
playlistsFolder := inFolder.AddFolder(itemPlaylistId);
playlistsFolder[mpiFilePath] := 'http://www.youtube.com/playlist?list='+itemPlaylistId; //'http://www.youtube.com/playlist?list=PLIw_h2Az1xWYQjB3csaArQGjhTU3wbCbN';
//playlistsFolder := inFolder.AddFolder('http://www.youtube.com/playlist?list='+itemPlaylistId);
playlistsFolder[mpiTitle] := lTitleFormat;
playlistsFolder[mpiComment] := itemDescription;
playlistsFolder[mpiYoutubeCurPage] := 1;
playlistsFolder[mpiFolderSortOrder] := 'mpPartNo';
playlistsFolder[mpiYoutubeType] := 'playlist';
playlistsFolder[mpiYoutubeCode] := itemPlaylistId;
playlistsFolder[mpiYoutubePageToken] := '';
playlistsFolder[mpiThumbnail] := itemThumbnail;
playlistsFolder[mpiYoutubeChannelTitle] := itemChannelTitle;
playlistsFolder[mpiYoutubeChannelId] := itemChannelId;
playlistsFolder[mpiYoutubeDescription] := itemDescription;
playlistsFolder[mpiPartNo] := lNum;
playlistsFolder[mpiPartTotal] := lItemsCount;
playlistsFolder[mpiYear] := lYear;
playlistsFolder[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(itemChannelTitle));
playlistsFolder[mpiCreateDate] := GetPublishedDate(itemPublished);
end; //for
finally
MainObj.Free;
end;
end;
procedure CreateChannels(inFolder: THmsScriptMediaItem; inFilePath: string; inPageToken: string);
var channelsFolder: THmsScriptMediaItem;
lfilepath, lcode, lcodeex: string;
lurl: string;
i: integer;
MainObj, EntryObj, ItemObj: TJsonObject;
ldownloadStr: string;
itemTitle, itemChannelId, itemDescription, itemChannelTitle, itemPublished, itemThumbnail: string;
itemPosition: integer;
lNextPageToken: string;
lItemsPerPage, lItemsCount, lPageCount, lNextPage, lCurPage: integer;
lNextFolder: THmsScriptMediaItem;
lYear: string;
lTitleFormat: string;
lNum, lPosition: integer;
begin
lurl := '';
lfilepath := inFilePath;
lcode := '';
if HmsRegExMatch('search\/([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else if HmsRegExMatch('search_query=([^& \/]+)', lfilepath, lcode) then
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lcode, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lcode;
end
else
begin
lurl := Format('http://storvild.ru/yt.php?type=channel&q=%s&maxResults=%d&order=%s&safeSearch=%s&publishedBefore=%s&publishedAfter=%s&relevanceLanguage=%s&pageToken=%s&app=%s',
[lfilepath, gpMaxResults, gpOrderBy, gpSafeSearch, gpPublishedBefore, gpPublishedAfter, gpRelevanceLanguage, inPageToken, VER]);
lcodeex := 'search/'+lfilepath;
end;
MainObj := TJsonObject.Create();
try
ldownloadStr := DownloadUrl(lurl);
MainObj.LoadFromString(ldownloadStr);
EntryObj := MainObj.O['items'];
//Папка "Следующая страница"
lNextPageToken := MainObj.S['nextPageToken'];
lItemsPerPage := MainObj.I['itemsPerPage'];
lItemsCount := MainObj.I['itemsCount'];
lPageCount := Ceil(lItemsCount/lItemsPerPage);
lNextPage := 2;
lCurPage := 1;
if lNextPageToken<>'' then
begin
lNextFolder := inFolder.AddFolder(mpFilePath+'-'+IntToStr(lPageCount)); //Если AddFolder('') то папка не создается. Одинаковые имена типа '-' не подходят для создания более одной папки
//lNextFolder[mpiFilePath] := mpFilePath;
lNextFolder[mpiFilePath] := lcodeex;
lNextFolder[mpiTitle] := 'Следующая страница '+IntToStr(lNextPage)+'/'+IntToStr(lPageCount);
lNextFolder[mpiFolderSortOrder] := 'mpPartNo';
lNextFolder[mpiThumbnail] := '';
lNextFolder[mpiYoutubePageToken] := lNextPageToken;
lNextFolder[mpiYoutubeType] := 'channels';
lNextFolder[mpiYoutubeCode] := lcodeex;
lNextFolder[mpiYoutubeUrl] := inFilePath;
lNextFolder[mpiYoutubeCurPage] := IntToStr(lNextPage);
if log='on' then
lNextFolder[mpiComment] := VarToStr(lNextFolder[mpiYoutubeType])+'#'+VarToStr(lNextFolder[mpiYoutubeCode])+'#'+VarToStr(lNextFolder[mpiYoutubePageToken]);
end;
for i:=0 to EntryObj.AsArray.Length-1 do
begin
ItemObj := EntryObj.AsArray.O[i];
itemTitle := ItemObj.S['title'];
itemChannelId := ItemObj.S['channelId'];
itemDescription := ItemObj.S['description'];
itemChannelTitle := ItemObj.S['channelTitle'];
itemThumbnail := ItemObj.S['thumbnail'];
itemPosition := ItemObj.I['position'];
itemPublished := ItemObj.S['publishedAt'];
lYear := Copy(itemPublished,1,4);
lNum := i+1+(lCurPage-1)*lItemsPerPage;
lPosition := itemPosition;
lTitleFormat := GetTitleByPattern(itemTitle, gpChannelPattern, lNum, lPosition, itemPublished);
channelsFolder := inFolder.AddFolder(itemChannelId);
channelsFolder[mpiFilePath] := 'http://www.youtube.com/channel/'+itemChannelId;
channelsFolder[mpiTitle] := lTitleFormat;
channelsFolder[mpiComment] := itemDescription;
channelsFolder[mpiYoutubeCurPage] := 1;
channelsFolder[mpiFolderSortOrder] := 'mpPartNo';
channelsFolder[mpiYoutubeType] := 'channelid';
channelsFolder[mpiYoutubeCode] := itemChannelId;
channelsFolder[mpiYoutubePageToken] := '';
channelsFolder[mpiThumbnail] := itemThumbnail;
channelsFolder[mpiYoutubeChannelTitle] := itemChannelTitle;
channelsFolder[mpiYoutubeChannelId] := itemChannelId;
channelsFolder[mpiYoutubeDescription] := itemDescription;
channelsFolder[mpiPartNo] := lNum;
channelsFolder[mpiPartTotal] := lItemsCount;
channelsFolder[mpiYear] := lYear;
channelsFolder[mpiProducer] := HmsUtf8Decode(HmsHttpDecode(itemChannelTitle));
channelsFolder[mpiCreateDate] := GetPublishedDate(itemPublished);
end; //for
finally
MainObj.Free;
end;
end;
function GetTitleByPattern(inTitle, inPattern: string; inNum, inPosition: integer; inPublishedDate: string): string;
var lPattern: string;
lNum0, lPosition0: string;
lTitleFormat: string;
lPublishedDate: string;
begin
lTitleFormat := inTitle;
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom, gpReplaceTo);
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom2, gpReplaceTo2);
lTitleFormat := ReplaceStrI(lTitleFormat, gpReplaceFrom3, gpReplaceTo3);
lPattern := inPattern;
if trim(lPattern)<>'' then
begin
lNum0 := PadLeft(IntToStr(inNum),length(gpMaxResults),'0'); //lShowNum := FormatFloat('000',inNum+1)+' ';
lPosition0 := PadLeft(IntToStr(inPosition),length(gpMaxResults),'0');
lPattern := ReplacePattern(lPattern, 'title', lTitleFormat);
lPublishedDate := GetPublishedDate(inPublishedDate);
lPattern := ReplaceStr(lPattern, '{published}', Copy(lPublishedDate,1,10));
lPattern := ReplaceStr(lPattern, '{pubyear}', Copy(lPublishedDate,7,4));
lPattern := ReplaceStr(lPattern, '{pubmonth}', Copy(lPublishedDate,4,2));
lPattern := ReplaceStr(lPattern, '{pubday}', Copy(lPublishedDate,1,2));
lPattern := ReplaceStr(lPattern, '{num0}', lNum0);
lPattern := ReplaceStr(lPattern, '{num}', IntToStr(inNum));
lPattern := ReplaceStr(lPattern, '{position0}', lPosition0);
lPattern := ReplaceStr(lPattern, '{position}', IntToStr(inPosition));
lPattern := trimex(lPattern);
end
else
lPattern := lTitleFormat;
Result := lPattern;
end;
//=================== Главная программа ======================================//
var
i: integer;
lDopFolder, lNextFolder: THmsScriptMediaItem;
sVideoInfo, sVideoId: string;
begin
InitParameters;
MediaResourceLink := '';
if PodcastItem.IsFolder then begin
PodcastItem.DeleteChildItems;
if (Pos('Дополнительные видео', mpTitle)=1) then
begin
CreateDopVideoFolders(PodcastItem);
end
else if (Pos('Следующая страница', mpTitle)=1) and (VarToStr(PodcastItem[mpiYoutubeType])='playlists') then
begin
CreatePlaylists(PodcastItem, VarToStr(PodcastItem[mpiYoutubeCode]), VarToStr(PodcastItem[mpiYoutubePageToken]));
end
else if (Pos('Следующая страница', mpTitle)=1) and (VarToStr(PodcastItem[mpiYoutubeType])='channels') then
begin
CreateChannels(PodcastItem, VarToStr(PodcastItem[mpiYoutubeCode]), VarToStr(PodcastItem[mpiYoutubePageToken]));
end
else if (Pos('Следующая страница', mpTitle)=1) then
begin
CreateVideos(PodcastItem, VarToStr(PodcastItem[mpiYoutubeType]), VarToStr(PodcastItem[mpiYoutubeCode]), VarToStr(PodcastItem[mpiYoutubePageToken]));
end
else if (PodcastItem[mpiYoutubeType] = 'dopvideo') then
begin
CreateDopVideo(PodcastItem);
end
else if (PodcastItem[mpiYoutubeType] = 'playlist') then
begin
CreateVideos(PodcastItem, VarToStr(PodcastItem[mpiYoutubeType]), VarToStr(PodcastItem[mpiYoutubeCode]), VarToStr(PodcastItem[mpiYoutubePageToken]));
end
else if (PodcastItem[mpiYoutubeType] = 'channelid') then
begin
CreateVideos(PodcastItem, VarToStr(PodcastItem[mpiYoutubeType]), VarToStr(PodcastItem[mpiYoutubeCode]), VarToStr(PodcastItem[mpiYoutubePageToken]));
end
else
begin
addLogError('Не определен тип папки...');
end;
end
else
begin
//Если не папка, выдать ссылку
// Получение кода видео
sVideoId := GetVideoId(PodcastItem);
MediaResourceLink := GetLinkYoutube3;
//Если ссылка уже была определена, используем ее
//if (PodcastItem[mpiMediaResourceLink] = NULL) then
//begin
// MediaResourceLink := GetLinkYoutube3;
// PodcastItem[mpiMediaResourceLink] := MediaResourceLink;
//end
//else
// MediaResourceLink := PodcastItem[mpiMediaResourceLink];
if (gpGetTimeLength='on') and (PodcastItem[mpiTimeLength] = NULL) then
begin
addLog('Получение VideoInfo');
if sVideoInfo='' then
sVideoInfo := GetVideoInfo(sVideoId);
addLog('Начало получения времени ролика');
UpdateVideoTimeLength(sVideoInfo); //Обновление времени
UpdateFromVideoInfo(sVideoInfo); //Обновление другой информации
addLog('Время ролика = '+PodcastItem[mpiTimeLength]);
end;
if (gpGetFileSize='on') and ((PodcastItem[mpiFileSize] = NULL) or (PodcastItem[mpiMimeType] = NULL)) then
begin
addLog('Начало получения размера файла');
UpdateVideoFileSize; // By WendyH
addLog('Размер файла = '+IntToStr(PodcastItem[mpiFileSize])+'. MimeType = '+PodcastItem[mpiMimeType]);
end;
end;
end.
551
PascalScript
-
53
88b45b34-0bbb-4684-af39-dbca963bc4e9
thisishorosho
fe329d86-741f-4816-a195-57c0a4e876dc
515
2
512
2
532
2
700
2
553
2
42
3
4
This is Хорошо
527
--maxresults=10 --dopvideomaxresults=10 --pattern='[{num}] {title} ({published})' --dopvideo=on --dopvideopattern='{num} {title}' --replacefrom='This is Хорошо -' --replaceto=''
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
522
0
245
88b45b34-0bbb-4684-af39-dbca963bc4e9
93
41831,035234537
41
channel
215
mpPartNo
525
42264,9864183218
-
53
5ff0c429-e8ed-4398-8a18-57fe55625d7e
Enjoykin
fe329d86-741f-4816-a195-57c0a4e876dc
515
2
512
2
532
2
700
2
553
2
42
3
4
Enjoykin
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
522
0
245
5ff0c429-e8ed-4398-8a18-57fe55625d7e
93
41832,7940734954
527
--dopvideo=on --safesearch=none --maxheight=1080 --maxresults=50 --orderby=viewCount --pattern='{title} ({published})' --replacefrom='—' --replaceto='-'
215
-35
525
42264,9864296528
-
53
eb1d4543-46af-4662-bfdb-c97461681ca3
http://youtube.com/user/simonscat
fe329d86-741f-4816-a195-57c0a4e876dc
515
2
512
2
532
2
700
2
553
2
42
3
4
Simon's Cat
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
522
0
245
eb1d4543-46af-4662-bfdb-c97461681ca3
93
41831,8209654051
527
--maxresults=50 --dopvideo=off --pattern='[{num}] {title} ({published})'
525
42264,9864414699
-
53
8c3f4a0f-9624-4ef0-8271-8a6d54ac8b72
http://www.youtube.com/watch?v=HFyiZpI-ToQ&list=PLf_21QvXdOgNkYvBZbNPTg8B9-r9S7cTJ
fe329d86-741f-4816-a195-57c0a4e876dc
515
2
512
2
532
2
700
2
553
2
42
3
4
Магазинчик Бо (Плейлист)
527
--maxresults=50 --pattern='{num} {title} ({published})' --replacefrom='Магазинчик Бо. ' --replacefrom2='Магазинчик БО. '
701
-1
702
-1
517
578-720,722-1080,482-576,402-480,322-400,202-320,0-200
518
0
522
0
245
8c3f4a0f-9624-4ef0-8271-8a6d54ac8b72
93
41832,9017881366
41
playlist
215
mpPartNo
525
42264,9864519097