///////////////////////////////////////////////////////////////////////////////
// Создание ссылки на Youtube
bool GetLink_Youtube31(string sLink) {
string sData, sVideoID='', sMaxHeight='', sAudio='', sSubtitlesLanguage='ru',
sSubtitlesUrl, sFile, sVal, sMsg, sConfig, sHeaders;
TJsonObject JSON; TRegExpr RegEx;
sHeaders = 'Referer: '+sLink+#13#10+
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'+#13#10+
'Origin: http://www.youtube.com'+#13#10;
HmsRegExMatch('--maxheight=(\\d+)' , mpPodcastParameters, sMaxHeight);
HmsRegExMatch('--sublanguage=(\\w{2})', mpPodcastParameters, sSubtitlesLanguage);
bool bSubtitles = (Pos('--subtitles' , mpPodcastParameters)>0);
bool bAdaptive = (Pos('--adaptive' , mpPodcastParameters)>0);
bool bNotDE = (Pos('notde=1' , sLink)>0);
if (!HmsRegExMatch('[\\?&]v=([^&]+)' , sLink, sVideoID))
HmsRegExMatch('/(?:embed|v)/([^\\?]+)', sLink, sVideoID);
sLink = 'http://www.youtube.com/watch?v='+sVideoID+'';
sData = HmsDownloadURL(sLink, sHeaders, true);
sData = HmsRemoveLineBreaks(sData);
if('') {
} else {
sData = HmsJsonDecode(sData);
HmsRegExMatch('"url"\\s*:\\s*"(.*?)"', sData, MediaResourceLink);
return true;
}
String hlsUrl, ttsUrl, flp, jsUrl, dashMpdLink, streamMap, playerId, algorithm;
String sType, itag, sig, alg, s;
String UrlBase = "";
int i, n, w, num, height, priority, minPriority = 90, selHeight, maxHeight = 1080;
bool is3D;
TryStrToInt(sMaxHeight, maxHeight);
JSON = TJsonObject.Create();
try {
JSON.LoadFromString(sConfig);
hlsUrl = HmsExpandLink(JSON.S['args\\hlsvp' ], UrlBase);
ttsUrl = HmsExpandLink(JSON.S['args\\ttsurl'], UrlBase);
flp = HmsExpandLink(JSON.S['url' ], UrlBase);
jsUrl = HmsExpandLink(JSON.S['assets\\js' ], UrlBase);
streamMap = JSON.S['args\\url_encoded_fmt_stream_map'];
if (bAdaptive && JSON.B['args\\adaptive_fmts'])
streamMap = JSON.S['args\\adaptive_fmts'];
if ((streamMap=='') && (hlsUrl=='')) {
sMsg = "Невозможно найти данные для воспроизведения на странице видео.";
if (HmsRegExMatch('(]+class="message".*?)', sData, sMsg)) sMsg = HmsUtf8Decode(HmsHtmlToText(sMsg));
HmsLogMessage(2, sMsg);
return;
}
} finally { JSON.Free; }
if (Copy(jsUrl, 1, 2)=='//') jsUrl = 'http:'+Trim(jsUrl);
HmsRegExMatch('/player-([\\w_-]+)/', jsUrl, playerId);
algorithm = HmsDownloadURL('https://hms.lostcut.net/youtube/getalgo.php?jsurl='+HmsHttpEncode(jsUrl));
if (hlsUrl!='') {
MediaResourceLink = ' '+hlsUrl;
sData = HmsDownloadUrl(sLink, sHeaders, true);
RegEx = TRegExpr.Create('BANDWIDTH=(\\d+).*?RESOLUTION=(\\d+)x(\\d+).*?(http[^#]*)', PCRE_SINGLELINE);
try {
if (RegEx.Search(sData)) do {
sLink = '' + RegEx.Match(4);
height = StrToIntDef(RegEx.Match(3), 0);
if (mpPodcastMediaFormats!='') {
priority = HmsMediaFormatPriority(height, mpPodcastMediaFormats);
if ((priority>=0) && (priority>minPriority)) {
MediaResourceLink = sLink; minPriority = priority;
}
} else if ((height > selHeight) && (height <= maxHeight)) {
MediaResourceLink = sLink; selHeight = height;
}
} while (RegEx.SearchAgain());
} finally { RegEx.Free(); }
} else if (streamMap!='') {
i=1; while (i<=Length(streamMap)) {
sData = Trim(ExtractStr(streamMap, ',', i));
sType = HmsHttpDecode(ExtractParam(sData, 'type', '', '&'));
itag = ExtractParam(sData, 'itag' , '', '&');
is3D = ExtractParam(sData, 'stereo3d', '', '&') == '1';
sLink = '';
if (Pos('url=', sData)>0) {
sLink = ' ' + HmsHttpDecode(ExtractParam(sData, 'url', '', '&'));
if (Pos('&signature=', sLink)==0) {
sig = HmsHttpDecode(ExtractParam(sData, 'sig', '', '&'));
if (sig=='') {
sig = HmsHttpDecode(ExtractParam(sData, 's', '', '&'));
for (w=1; w<=WordCount(algorithm, ' '); w++) {
alg = ExtractWord(w, algorithm, ' ');
if (Length(alg)<1) continue;
if (Length(alg)>1) TryStrToInt(Copy(alg, 2, 4), num);
if (alg[1]=='r') {s=''; for(n=Length(sig); n>0; n--) s+=sig[n]; sig = s; } // Reverse
if (alg[1]=='s') {sig = Copy(sig, num+1, Length(sig)); } // Clone
if (alg[1]=='w') {n = (num-Trunc(num/Length(sig)))+1; Swap(sig[1], sig[n]);} // Swap
}
}
if (sig!='') sLink += '&signature=' + sig;
}
}
if (itag in ([139,140,141,171,172])) { sAudio = sLink; continue; }
if (sLink!='') {
height = 0; //http://www.genyoutube.net/formats-resolution-youtube-videos.html
if (itag in ([13,17,160 ])) height = 144;
else if (itag in ([5,36,92,132,133,242 ])) height = 240;
else if (itag in ([6 ])) height = 270;
else if (itag in ([18,34,43,82,100,93,134,243 ])) height = 360;
else if (itag in ([35,44,83,101,94,135,244,43 ])) height = 480;
else if (itag in ([22,45,84,102,95,136,298,247])) height = 720;
else if (itag in ([37,46,85,96,137,248,299 ])) height = 1080;
else if (itag in ([264,271 ])) height = 1440;
else if (itag in ([266,138 ])) height = 2160;
else if (itag in ([272 ])) height = 2304;
else if (itag in ([38 ])) height = 3072;
else continue;
if (mpPodcastMediaFormats!='') {
priority = HmsMediaFormatPriority(height, mpPodcastMediaFormats);
if ((priority>=0) || (priorityselHeight) && (height<= maxHeight)) {
MediaResourceLink = sLink; selHeight = height;
}
}
}
if (bAdaptive && (sAudio!='')) MediaResourceLink = '-i "'+Trim(MediaResourceLink)+'" -i "'+Trim(sAudio)+'"';
}
// Если есть субтитры и в дополнительных параметрах указано их показывать - загружаем
if (bSubtitles && (ttsUrl!='')) {
sFile = HmsSubtitlesDirectory+'\\Youtube\\'+PodcastItem.ItemID+'.'+sSubtitlesLanguage+'.srt';
sLink = ttsUrl+'&fmt=srt&lang=';
if (!HmsDownloadURLToFile(sLink+sSubtitlesLanguage, sFile, 'Accept-Encoding: gzip, deflate')) {
HmsDownloadURLToFile(sLink+'en' , sFile, 'Accept-Encoding: gzip, deflate');
}
PodcastItem[mpiSubtitleLanguage] = sFile;
}
}