Code: Select all
int LOG = 0;
bool gbQualityLog = false; // Ключ --qualitylog включает показ выбора качества видео
char gsUrlBase, gsHeaders, gsComments;
// ------------------------------------------- Получение ссылки на Youtube ----
bool GetLink_YouTube(char sLink) {
  char sHtml, sFormatMap='', sVideoID='', sFormat, itag, sig, sQAval, sQSel, s1, s2, sQP='';
  int i, iHeight, iPriority, iMinPriority=99; bool bGotLink=false;
  if (HmsRegExMatch('(\\w{4,5}://.*/video.3gp)', sLink, MediaResourceLink)) return true;
  if (LeftCopy(sLink, 4)!='http') sLink = 'http://' + Trim(sLink);
  if (Pos('%3F', sLink)>0) sLink=HmsHttpDecode(sLink);  // Если нужно - декодим
  if (!HmsRegExMatch('[\\?&]v=([^&"\\?]*)',       sLink, sVideoID))
  if (!HmsRegExMatch('youtube.com/v/([^&"\\?]*)', sLink, sVideoID))
  if (!HmsRegExMatch('youtu.be/([^&"\\?]*)',      sLink, sVideoID))
       HmsRegExMatch('/embed/([^&"\\?]*)',        sLink, sVideoID); // Внимательно - ИФы выполняются, если предыдующий нет!
  if (sVideoID=='') {
    sHtml = LoadUrl(sLink);
    HmsRegExMatch('/watch[^&"\']v=([^&"]*)', sHtml, sVideoID);
  }
  if (sVideoID=='') {
    HmsLogMessage(2, mpTitle+' Немогу найти VideoID в ссылке на youtube.com ('+sLink+')');
    MediaResourceLink = 'http://wonky.lostcut.net/vids/error_getlink.avi';
    return true;
  }
  char aGUrl[2]; // Несколько способов искать stream_map
  aGUrl[0] = '/watch?has_verified=1&v=';
  aGUrl[1] = '/get_video_info?video_id=';
  // aGUrl[2] = '/api_video_info?video_id=';
  sHtml = HmsDownLoadUrl('http://www.youtube.com'+aGUrl[0]+sVideoID);
  if (!HmsRegExMatch('fmt_stream_map=(.*?)&', sHtml, sFormatMap))
  if (!HmsRegExMatch('fmt_stream_map"\\s*?:\\s*?"(.*?)"', sHtml, sFormatMap))
  if (!HmsRegExMatch('fmt_url_map=(.*?)&', sHtml, sFormatMap)) {
    // Попытка сделать это немного по-другому
    sHtml = HmsSendRequestEx('www.youtube.com', aGUrl[1]+sVideoID, 'GET', 'application/x-www-form-urlencoded; Charset=UTF-8', gsHeaders, '', 80, 0, '', true);
    if (!HmsRegExMatch('fmt_stream_map=(.*?)&', sHtml, sFormatMap))
    if (!HmsRegExMatch('fmt_stream_map"\\s*?:\\s*?"(.*?)"', sHtml, sFormatMap))
         HmsRegExMatch('fmt_url_map=(.*?)&', sHtml, sFormatMap);
  }
  HmsRegExMatch('--quality=(\\d+)', gsComments, sQP);
  if (sFormatMap!='') {
    sQAval = '';
    if (Pos(',', sFormatMap)<1) sFormatMap = HmsHttpDecode(sFormatMap);
    for (i=1; i<=WordCount(sFormatMap, ','); i++) {
      sFormat = ExtractWord(i, sFormatMap, ',');
      sFormat = ReplaceStr(sFormat, '\\u0026', '&');
      HmsRegExMatch('itag=(\\d+)', sFormat, itag );
      HmsRegExMatch('url=(.*?)[&$]',  sFormat, sLink);
      sLink = HmsHttpDecode(sLink);
      if (HmsRegExMatch('sig=(.*?)&', sFormat, sig)) sLink+= '&signature=' + sig;
      iHeight=0;
      if      (IsWordPresent(itag, '13,17',           ',')) iHeight=144;
      else if (IsWordPresent(itag, '5,83',            ',')) iHeight=240;
      else if (IsWordPresent(itag, '6',               ',')) iHeight=270;
      else if (IsWordPresent(itag, '18,34,43,82,100', ',')) iHeight=360;
      else if (IsWordPresent(itag, '35,44,101',       ',')) iHeight=480;
      else if (IsWordPresent(itag, '22,45,84,102',    ',')) iHeight=720;
      else if (IsWordPresent(itag, '37,46',           ',')) iHeight=1080;
      else if (IsWordPresent(itag, '38',              ',')) iHeight=3072;
      s1 = IntToStr(iHeight); if (Pos(s1, sQAval)<1) sQAval += s1+'  ';
      if (sQP==s1) {iMinPriority=0; MediaResourceLink=sLink; sQSel=IntToStr(iHeight); bGotLink=true;}
      if (mpPodcastMediaFormats=='') {
        if (bGotLink) continue;
        MediaResourceLink = sLink; bGotLink=true; sQSel=IntToStr(iHeight); continue;
      }
      iPriority = HmsMediaFormatPriority(iHeight, mpPodcastMediaFormats);
      if ((iPriority>=0)&&(iPriority<iMinPriority)) {
        iMinPriority=iPriority; MediaResourceLink=sLink; sQSel=IntToStr(iHeight);
      }
    }
    if (gbQualityLog) {
      if (sQAval=='') HmsLogMessage(2, Format('%s: Нет выбора доступного качества у этого видео', [mpTitle]));
      else HmsLogMessage(2, Format('%s: Доступно качество: %s Выбрано: %s', [mpTitle ,sQAval, sQSel]));
    }
  } else {
    // Если нет stream_map, пробуем тупо взять ссылку по API
    if (HmsRegExMatch('reason=(.*?)(?:&|$)', sHtml, sQP)) {
      sQP = HmsHtmlToText(HmsUtf8Decode(HmsHttpDecode(sQP)));
      HmsLogMessage(2, mpTitle+': Видео на youtube.com недоступно ('+sQP+')');
      VideoMessage(mpTitle, 'YOUTUBE.COM СООБЩАЕТ:\n\n'+sQP);
    } else {
      sHtml = LoadUrl('http://gdata.youtube.com/feeds/api/videos/'+sVideoID+'?v=2');
      HmsRegExMatch('<media:content[^>]+url=\'([^>]+)\'[^>]+type=\'video[^>]+yt:format=\'6', sHtml, MediaResourceLink);
    }
  }
  if (MediaResourceLink=='') {
    HmsLogMessage(2, mpTitle+': Видео на youtube.com недоступно ('+sLink+')');
    MediaResourceLink = 'http://wonky.lostcut.net/vids/error3d_3.avi';
  }
  return true;
}
// -------------------------------- Вывод вместо видео заданного сообщения ----
bool VideoMessage(char sCaption, char sMessage, int nTime=30) {
  char tmpImg = HmsTempDirectory+'\\videomessage.jpg'; char sCmd;
  sCaption = HmsHttpEncode(ReplaceStr(sCaption, '\n', '|'));
  sMessage = HmsHttpEncode(ReplaceStr(sMessage, '\n', '|'));
  HmsDownloadURLToFile('http://wonky.lostcut.net/videomessage.php?caption='+sCaption+'&msg='+sMessage, tmpImg);
  sCmd = Format('cmd://"%s\\hmsmpeg.exe" -loop 1 -f image2 -i "%s" -t %d -r 25 %s "<OUTPUT FILE>"', [ProgramPath, tmpImg, nTime, HmsTranscodingVideoParams]);
  MediaResourceLink = sCmd;
}
// ------------------------------------------- Загрузка страницы по ссылке ----
char LoadUrl(char sLink, char sMethod='GET', char sHeaders='') {
  char sHtml, sUrlServer, sRequestPage='/', sPostData='', sAnswHeaders='';
  if (!HmsRegExMatch('^http://(.*)', sLink, sUrlServer)) return '';
  HmsRegExMatch2('^(.*?)(/.*)', sUrlServer, sUrlServer, sRequestPage);
  if (sMethod=='POST') HmsRegExMatch2('^(.*?)\\?(.*)', sRequestPage, sRequestPage, sPostData);
  if (sHeaders=='') sHeaders = gsHeaders;
  sHtml = HmsSendRequestEx(sUrlServer, sRequestPage, sMethod, 'application/x-www-form-urlencoded; Charset=UTF-8', sHeaders, sPostData, 80, 0, sAnswHeaders, true);
  sHtml = HmsRemoveLineBreaks(HmsUtf8Decode(sHtml));
  return sHtml;
}
// ------------------ Проверка переданных параметров в полях "Комментарий" ----
void CheckParameters() {
  char sValue;
  gsComments = mpComment;
  THmsScriptMediaItem TempFolderItem = PodcastItem;
  while ((TempFolderItem.ItemParent != HmsDatabaseRootItem) &&
         (TempFolderItem.ItemParent != nil)) {
    gsComments    += ' '+TempFolderItem.ItemParent[mpiComment];
    TempFolderItem = TempFolderItem.ItemParent;
  }
  if (Pos('--log',          gsComments)>0) LOG = 1;
  if (Pos('--qualitylog',   gsComments)>0) gbQualityLog = true;
}
// ---------------------  M A I N   P R O C E D U R E  ------------------------
{
  //mpFilePath = 'http://www.youtube.com/watch?v=g0SUG6Fv15Y&feature=youtube_gdata'; //4testing
  gsHeaders = 'http://google.com/\r\n';
  if (HmsRegExMatch('(http://.*?)/', mpFilePath+'/', gsUrlBase)) gsHeaders = gsUrlBase+'\r\n';
  gsHeaders+= 'Accept-Encoding: gzip, deflate\r\n';
  gsHeaders+= 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0\r\n';
  gsHeaders+= 'Connection: Keep-Alive\r\n';
  gsHeaders+= 'Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n';
  gsHeaders+= 'Accept-Language: ru-RU,ru;q=0.9,en;q=0.8\r\n';
  CheckParameters();
  GetLink_YouTube(mpFilePath);
}