Code: Select all
// ------------------ Универсальная функция подготовки к приёму потока HDS ----
char PrepareHDSLink(char sManifest, char sReferer='') {
char sHtml, sVideoId, sBitrates, sBitrate, sIndex, sHeight, sDuration, sAvaliable, sSelectedHeight, sSelectedBitr='', sTime;
int i, nCount, iHeight, iPriority, iMinPriority=99;
bool bManifestDownloaded = false;
char sTranscodingParams = '--manifest "'+sManifest+'"';
if (sReferer!='') sTranscodingParams += ' --referer "'+sReferer+'"';
if (HmsRegExMatch('--quality=(\\w+)', PodcastItem.ItemParent[mpiComment], sSelectedBitr)) sTranscodingParams += ' --quality '+sSelectedBitr;
// Если включена приоритетность форматов видео - смотрим список битрейтов, и НЕ берём инденкс media (спасибо tarzann5!)
if (mpPodcastMediaFormats != '') {
sSelectedHeight = ''; sAvaliable='Доступно качество (высота кадра): '; sVideoId='';
// Смотрим в манифест и вытаскиваем значение битрейта по выбранной высоте кадра
sHtml = LoadUrl(sManifest);
bManifestDownloaded = true;
TRegExpr re = TRegExpr.Create('(<media.*?>)', 1);
if (re.Search(sHtml)) do {
HmsRegExMatch('height="(.*?)"', re.Match, sHeight );
HmsRegExMatch('bitrate="(.*?)"', re.Match, sBitrate);
iHeight = StrToIntDef(sHeight, 0);
iPriority = HmsMediaFormatPriority(iHeight, mpPodcastMediaFormats);
if ((iPriority>=0)&&(iPriority<iMinPriority)) {iMinPriority=iPriority; sSelectedHeight=sHeight; sSelectedBitr=sBitrate;}
sAvaliable += sBitrate+' ('+sHeight+'), ';
} while (re.SearchAgain);
re.Free();
sAvaliable = LeftCopy(sAvaliable, Length(sAvaliable)-2); // Избавляемся от последней зяпятой
if (HmsRegExMatch('--quality=(\\w+)', PodcastItem.ItemParent[mpiComment], sSelectedBitr)) {
sAvaliable += '. Установлено параметром: '+sSelectedBitr;
} else {
sAvaliable += '. Выбрано: '+sSelectedBitr+' ('+sSelectedHeight+')';
if (sSelectedBitr == '') HmsLogMessage(1, 'HDSDUMP: В манифесте не указана высота кадра, выбор качества только через параметр --quality=');
else sTranscodingParams += ' --quality '+sSelectedBitr;
}
if (gbQualityLog) HmsLogMessage(1, mpTitle+': '+sAvaliable);
}
// Если не установлена длительность - уточняем из манифеста
if ((Trim(PodcastItem[mpiTimeLength])=='')||(PodcastItem[mpiTimeLength]=='01:40:00.000')) {
if (!bManifestDownloaded) sHtml = LoadUrl(sManifest);
if (HmsRegExMatch('<duration>(\\d+).*?</duration>', sHtml, sDuration)) {
sTime = HmsTimeFormat(StrToIntDef(sDuration, 6000));
if (sTime != '') PodcastItem[mpiTimeLength] = sTime+'.000';
}
}
PodcastItem[mpiTranscodingParams ] = sTranscodingParams;
//PodcastItem[mpiTranscodingProfile] = 'Фильмы - HDS (ремуксирование)';
if (mpTimeStart != '') sTranscodingParams = sTranscodingParams + ' --skip ' + mpTimeStart;
return 'cmd://"' + ProgramPath + '\\Transcoders\\HdsDump.Exe" ' + sTranscodingParams + ' --play >"<OUTPUT FILE>"';
}
// ------------------------------------------ Получение ссылки с rutube.ru ----
bool GetLink_RuTube(char sLink) {
char sHtml, sVideoId, sBaseUrl, sApp, sPlaypath;
if (LeftCopy(sLink, 4)!='http') sLink = 'http://' + Trim(sLink);
if (HmsRegExMatch('rutube.ru/video/\\w+', sLink, sVideoId)) {
sHtml = LoadUrl(sLink);
HmsRegExMatch('(video.rutube.ru/[\\d]+)', sHtml, sLink);
}
if (!HmsRegExMatch('video.rutube.ru/([\\d]+)', sLink, sVideoId))
if (!HmsRegExMatch('rutube.ru/tracks/([\\d]+)', sLink, sVideoId))
if (!HmsRegExMatch('rutube.ru/.*?track_id=([\\d]+)', sLink, sVideoId))
if (!HmsRegExMatch('rutube.ru/compat/tracks/([\\d]+)', sLink, sVideoId)) return true;
sLink = Format('http://rutube.ru/api/play/trackinfo/%s/?_=%g&format=json&referer=%s', [sVideoId, Random, HmsHttpEncode(sLink)]);
sHtml = LoadUrl(sLink);
if (!HmsRegExMatch('"video_balancer".*?"([^"]+f4m)"', sHtml, sLink)) {HmsLogMessage(2, mpTitle+' Не могу найти ссылку на манифест по ссылке '+sLink); return true;}
sHtml = LoadUrl(sLink);
// И смотрим, если в baseURL протокол rtmp - то наша ссылка будет представлять команду с rtmpdump.exe...
if (HmsRegExMatch2('<baseURL>(rtmp://.*?/)(.*?)</baseURL>', sHtml, sBaseUrl, sApp)) {
// rtmp
if (!HmsRegExMatch('<media url="(.*?)"', sHtml, sPlaypath)) {HmsLogMessage(2, mpTitle+' Не могу найти Playpath по ссылке '+sLink); return true;}
if (Pos('.f4f', sPlaypath)>0) {HmsLogMessage(2, mpTitle+' Шифрованный поток не умеем показывать.'); return true;}
if (RightCopy(sApp, 1)!='/') sApp+='/';
sPlaypath = HmsHtmlDecode(sPlaypath);
if (LeftCopy(sPlaypath, 1)=='/') sPlaypath=Copy(sPlaypath, 2, Length(sPlaypath)-1);
sLink = 'rtmpdump.exe --swfUrl "http://rutube.ru/player.swf" -r "'+sBaseUrl+'" --app "'+sApp+'" --playpath "'+sPlaypath+'"';
if (sApp=='vod/') sLink+= ' --live';
// HmsLogMessage(1, mpTitle+': Это rtmp!');
} else if (HmsRegExMatch('<baseURL>(.*?)</baseURL>', sHtml, sBaseUrl)) {
// Если есть тег media да и ещё с ссылкой на манифест, то это, должно быть, HDS
if (HmsRegExMatch('<media[^>]+href="(.*?.f4m)"', sHtml, sPlaypath)) {
sLink = sPlaypath;
if (LeftCopy(sLink, 1)=='/') sLink = sBaseUrl + Trim(sLink);
} else if (HmsRegExMatch('<media[^>]+url="(.*?)"', sHtml, sPlaypath)) {
// Значит sLink уже ссылка на манифест - ничего не делаем
} else {HmsLogMessage(2, mpTitle+' Не умею обрабатывать ссылку rutube '+sLink); return true;}
// Указываем использования конкретного профиля
PodcastItem[mpiTranscodingProfile] = 'Фильмы - HDS (ремуксирование)';
MediaResourceLink = PrepareHDSLink(sLink);
//HmsLogMessage(1, mpTitle+' Это HDSdump!');
} else {
HmsLogMessage(2, mpTitle+' Не могу найти BaseUrl по ссылке '+sLink);
}
MediaResourceLink = sLink;
return true;
}