<?xml version="1.0" encoding="utf-8"?>
<HmsMediaItem>
  <MediaType>3</MediaType>
  <ClassID>51</ClassID>
  <ItemID>84b3cae1-8df9-48f3-b688-b44ed7e3943f</ItemID>
  <ItemPath>http://hdserials.club</ItemPath>
  <ParentID>234DF17B-418C-4FDC-9DFE-CD0C586D2E76</ParentID>
  <Properties>
    <Property>
      <ID>4</ID>
      <Value>hdserials.club</Value>
    </Property>
    <Property>
      <ID>515</ID>
      <Value>1</Value>
    </Property>
    <Property>
      <ID>700</ID>
      <Value>0</Value>
    </Property>
    <Property>
      <ID>701</ID>
      <Value>-1</Value>
    </Property>
    <Property>
      <ID>702</ID>
      <Value>-1</Value>
    </Property>
    <Property>
      <ID>517</ID>
      <Value>578-720,722-1080,482-576,402-480,322-400,202-320,0-200</Value>
    </Property>
    <Property>
      <ID>518</ID>
      <Value>0</Value>
    </Property>
    <Property>
      <ID>512</ID>
      <Value>0</Value>
    </Property>
    <Property>
      <ID>532</ID>
      <Value>1</Value>
    </Property>
    <Property>
      <ID>553</ID>
      <Value>1</Value>
    </Property>
    <Property>
      <ID>522</ID>
      <Value>0</Value>
    </Property>
    <Property>
      <ID>570</ID>
      <Value>0</Value>
    </Property>
    <Property>
      <ID>245</ID>
      <Value>84b3cae1-8df9-48f3-b688-b44ed7e3943f</Value>
    </Property>
    <Property>
      <ID>93</ID>
      <Value>43474,5132682986</Value>
    </Property>
    <Property>
      <ID>530</ID>
      <Value>string    gsUrlBase    = &apos;http://hdserials.club&apos;; // База для относительных ссылок
int       gnTotalItems = 0;                       // Счётчик созданных элементов
TDateTime gStart       = Now;                     // Время начала запуска скрипта
int gnMaxPages=10, gnMaxInGroup=100; bool gbYearInTitle=false; char gsGroupMode=&apos;&apos;;

// Регулярные выражения для поиска на странице блоков с информацией о видео
string
  gsPatternBlock  = &apos;"short-item"(.*?)&lt;/div&gt;&apos;       , // Искомые блоки
  gsCutPage       = &apos;&lt;fromCut&gt;(.*?)&lt;toCut&gt;&apos;         , // Обрезка загруженной страницы
  gsPatternTitle  = &apos;alt="(.*?)"&apos;                   , // Название
  gsPatternLink   = &apos;&lt;a[^&gt;]+href="(.*?)"&apos;           , // Ссылка
  gsPatternImg    = &apos;&lt;img src="(.*?)"&apos;              , // Картинка
  gsPatternYear   = &apos;shortinfo.*?&gt;(\\d{4})&lt;&apos;        , // Год
  gsPatternAudio  = &apos;&apos;                              , // Озвучка / Перевод
  gsPatternPages  = &apos;.*/page/\\d+/"&gt;(\\d+)&apos;         , // Регулярное выражение для поиска максимального номера страницы для дозагрузки
  gsPagesParams   = &apos;page/&lt;PN&gt;/&apos;                    , // Параметр с номером страницы, который добавляется к ссылке
  ;

///////////////////////////////////////////////////////////////////////////////
// Создание папки или подкаста
THmsScriptMediaItem CreateFolder(THmsScriptMediaItem ParentFolder, string sName, string sLink, string sImg=&apos;&apos;) {
  THmsScriptMediaItem Item = ParentFolder.AddFolder(sLink); // Создаём папку с указанной ссылкой
  Item[mpiTitle     ] = sName; // Присваиваем наименование
  Item[mpiThumbnail ] = sImg;  // Картинка
  Item[mpiCreateDate] = DateTimeToStr(IncTime(gStart, 0, -gnTotalItems, 0, 0)); // Для обратной сортировки по дате создания

  gnTotalItems++;             // Увеличиваем счетчик созданных элементов
  return Item;                // Возвращаем созданный объект
}

///////////////////////////////////////////////////////////////////////////////
// Получение имени группировки по имени видео (первая буква, "A..Z" или "#")
string GetGroupName(string sName) {
  string sGrp = &apos;#&apos;;
  if (HmsRegExMatch(&apos;([A-ZА-Я0-9])&apos;, sName, sGrp, 1, PCRE_CASELESS)) sGrp = UpperCase(sGrp);
  if (HmsRegExMatch(&apos;[A-Z]&apos;, sGrp, sGrp)) sGrp = &apos;A..Z&apos;;
  if (HmsRegExMatch(&apos;[0-9]&apos;, sGrp, sGrp)) sGrp = &apos;#&apos;;
  return sGrp;
}

///////////////////////////////////////////////////////////////////////////////
// Загрузка страниц и парсинг 
void LoadAndParse() {
  string sHtml, sData, sName, sLink, sImg, sYear, sPage, sVal, sPost, sServ; // Объявляем переменные
  THmsScriptMediaItem Item, Folder = FolderItem; TRegExpr RegEx;
  int i, n, nPages=0, iCnt=0, nGrp=0; char sGrp=""; bool bGroup=false;

  if (HmsRegExMatch(&apos;--maxingroup=(\\d+)&apos;, mpPodcastParameters, sVal)) gnMaxInGroup = StrToInt(sVal);
  if (HmsRegExMatch(&apos;--maxpages=(\\d+)&apos;  , mpPodcastParameters, sVal)) gnMaxPages   = StrToInt(sVal);
  HmsRegExMatch(&apos;--group=(\\w+)&apos;, mpPodcastParameters, gsGroupMode);
  gbYearInTitle = (Pos(&apos;--yearintitle&apos;, mpPodcastParameters)&gt;0); 

  if (LeftCopy(mpFilePath, 4) != "http") {
    // Если нет ссылки - делаем поиск названия
    if (Length(mpTitle)&lt;4) mpTitle += " :::";    // Фишка обхода ограничения на минимальную длину в 4 символа (двоеточие при самом поиске не учитывается)
      HmsRegExMatch(&apos;//(.*)&apos;, gsUrlBase, sServ); // получаем доменное имя из gsUrlBase в sServ
    sPost = &apos;do=search&amp;subaction=search&amp;search_start=0&amp;full_search=0&amp;result_from=1&amp;story=&apos;+HmsPercentEncode(HmsUtf8Encode(mpTitle));
    sHtml = HmsSendRequestEx(sServ, &apos;/index.php?do=search&apos;, &apos;POST&apos;,
    &apos;application/x-www-form-urlencoded; Charset=UTF-8&apos;, 
    gsUrlBase+&apos;/\r\nAccept-Encoding: gzip, deflate\r\nOrigin: &apos;+gsUrlBase, 
    sPost, 80, 0, &apos;&apos;, true);
    gnMaxPages = 1;
    
  } else {
    // Иначе просто, загружаем страницу по ссылке
    sHtml = HmsDownloadURL(mpFilePath, &apos;Referer: &apos;+gsUrlBase, true);
    
  }
  sHtml = HmsUtf8Decode(sHtml);       // Декодируем страницу из UTF-8
  sHtml = HmsRemoveLineBreaks(sHtml); // Удаляем переносы строк, для облегчения работы с регулярными выражениями

  // Если указан шаблон поиска максимального номера страницы - применяем
  if ((gsPatternPages!=&apos;&apos;) &amp;&amp; HmsRegExMatch(gsPatternPages, sHtml, sVal)) nPages = StrToIntDef(sVal, 0);

  // Вырезаем только нужный участок текста HTML, где будем искать блоки.
  // Вместо &lt;fromCut&gt; и &lt;toCut&gt; вставляем начало и конец участка HTML, между которыми
  // будем искать блоки текста с сылкой, наименованием и проч.
  HmsRegExMatch(gsCutPage, sHtml, sHtml); // ищем в sHtml, результат кладём обратно в sHtml

  // =========================================================================
  // Дозагрузка страниц
  if ((gnMaxPages!=0) &amp;&amp; (nPages&gt;gnMaxPages)) nPages = gnMaxPages;
  for (i=2; i&lt;=nPages; i++) {
    HmsSetProgress(Trunc(i*100/nPages));
    HmsShowProgress(Format(&apos;%s: Загрузка страницы %d из %d&apos;, [mpTitle, i, nPages]));
    sLink = mpFilePath + ReplaceStr(gsPagesParams, &apos;&lt;PN&gt;&apos;, IntToStr(i));
    sPage = HmsDownloadURL(sLink, &apos;Referer: &apos;+gsUrlBase, true);
    sPage = HmsUtf8Decode(sPage);
    if (gsCutPage!=&apos;&apos;) HmsRegExMatch(gsCutPage, sPage, sPage);
    sHtml += sPage;
    if (HmsCancelPressed) break;
  }
  HmsHideProgress();                                                                                                   
  // =========================================================================
      
  // Создаём объект для поиска блоков текста по регулярному выражению,
  // в которых есть информация: ссылка, наименование, ссылка на картинку и проч.
  // Обычно, определяем начало и конец блока и вставляем их вместо &lt;section&gt; и &lt;/section&gt;
  RegEx = TRegExpr.Create(gsPatternBlock, PCRE_SINGLELINE);
  try {
    // Определяем, если блоков в загруженном более чем gnMaxInGroup, включаем группировку
    i=0; if (RegEx.Search(sHtml)) do i++; while (RegEx.SearchAgain());
    bGroup = (i &gt; gnMaxInGroup);
    // Главный цикл поиска блоков
    if (RegEx.Search(sHtml)) do {
      sLink=&apos;&apos;; sImg=&apos;&apos;; sYear=&apos;&apos;; sName=&apos;&apos;;
      HmsRegExMatch(gsPatternTitle, RegEx.Match, sName);
      HmsRegExMatch(gsPatternLink , RegEx.Match, sLink);
      HmsRegExMatch(gsPatternImg  , RegEx.Match, sImg );
      HmsRegExMatch(gsPatternYear , RegEx.Match, sYear);
      if (Trim(sLink)=="") continue;
    
      sName = ReplaceStr(HmsHtmlToText(sName), "/", "-");
      sLink = HmsExpandLink(sLink, gsUrlBase);

      if (sImg!=&apos;&apos;) sImg = HmsExpandLink(sImg, gsUrlBase);

      // Если в ссылках встречаются русские символы - делаем их безопасными
      if (HmsRegExMatch(&apos;^.*?([а-яА-Я].*)&apos;, sImg, sVal)) sImg = ReplaceStr(sImg, sVal, HmsPercentEncode(HmsUtf8Encode(sVal)));

      // Если указано добавлять год вназвание и в названии его нет, добавляем
      if (gbYearInTitle &amp;&amp; (sYear!=&apos;&apos;) &amp;&amp; (Pos(sYear, sName)&lt;1)) sName += &apos; (&apos;+sYear+&apos;)&apos;;

      // Контроль группировки (создаём папку с именем группы)
      if (gsGroupMode==&apos;alph&apos;) {
        Folder = FolderItem.AddFolder(GetGroupName(sName)); 
        Folder[mpiFolderSortOrder] = "mpTitle";
      } else if (gsGroupMode==&apos;year&apos;) {
        Folder = FolderItem.AddFolder(sYear); 
        Folder[mpiFolderSortOrder] = "mpTitle";
        Folder[mpiYear           ] = sYear;
      } else if (bGroup) {
        iCnt++; if (iCnt&gt;=gnMaxInGroup) { nGrp++; iCnt=0; }
        Folder = FolderItem.AddFolder(Format(&apos;%.2d&apos;, [nGrp])); 
      }

      CreateFolder(Folder, sName, sLink, sImg); // Создание ссылки (папки с фильмом)

    } while (RegEx.SearchAgain);
  } finally { RegEx.Free(); }
  if      (gsGroupMode==&apos;alph&apos;) FolderItem.Sort(&apos;mpTitle&apos;);
  else if (gsGroupMode==&apos;year&apos;) FolderItem.Sort(&apos;-mpYear&apos;);

  HmsLogMessage(1, mpTitle+&apos;: создано элементов - &apos;+IntToStr(gnTotalItems));
}

///////////////////////////////////////////////////////////////////////////////
//                    Г Л А В Н А Я    П Р О Ц Е Д У Р А                     //
{
  FolderItem.DeleteChildItems(); // Удаляем созданные ранее элементы в текущей папке
  LoadAndParse();                // Запускаем загрузку страниц и создание папок видео
}
</Value>
    </Property>
    <Property>
      <ID>531</ID>
      <Value>C++Script</Value>
    </Property>
    <Property>
      <ID>550</ID>
      <Value>string    gsUrlBase    = "http://hdserials.club"; // База для относительных ссылок
int       gnTotalItems = 0;                       // Счётчик созданных элементов
TDateTime gStart       = Now;                     // Время начала запуска скрипта
string    gsTime       = "00:35:00.000";          // Продолжительность видео
int       mpiCountry   = 10012;                   // Идентификаторы для хранения дополнительной
int       mpiTranslate = 10013;                   // информации в свойствах подкаста
int       mpiQuality   = 10014;

///////////////////////////////////////////////////////////////////////////////
// Создание информационной ссылки
void CreateInfoItem(string sName, string sVal) {
  THmsScriptMediaItem Item; sVal = Trim(sVal);
  if (sVal=="") return;
  Item = HmsCreateMediaItem(&apos;Info&apos;+IntToStr(PodcastItem.ChildCount), PodcastItem.ItemID);
  Item[mpiTitle     ] = sName+&apos;: &apos;+sVal;
  Item[mpiThumbnail ] = &apos;http://wonky.lostcut.net/vids/info.jpg&apos;;
  Item[mpiTimeLength] = 7;
  Item[mpiCreateDate] = VarToStr(IncTime(gStart,0,-gnTotalItems,0,0));
  gnTotalItems++;
}

///////////////////////////////////////////////////////////////////////////////
// Создание ссылки-ошибки
void CreateErrorItem(string sMsg) {
  THmsScriptMediaItem Item = HmsCreateMediaItem(&apos;Err&apos;+IntToStr(PodcastItem.ChildCount), PodcastItem.ItemID);
  Item[mpiTitle     ] = sMsg;
  Item[mpiThumbnail ] = &apos;http://wonky.lostcut.net/icons/symbol-error.png&apos;;
}

///////////////////////////////////////////////////////////////////////////////
// Создание ссылки на видео
THmsScriptMediaItem CreateMediaItem(THmsScriptMediaItem Folder, string sTitle, string sLink=&apos;&apos;, string sGrp=&apos;&apos;) {
  THmsScriptMediaItem Item = HmsCreateMediaItem(sLink, Folder.ItemID, sGrp);
  Item[mpiTitle     ] = sTitle;
  Item[mpiCreateDate] = VarToStr(IncTime(gStart,0,-gnTotalItems,0,0));
  Item[mpiTimeLength] = gsTime;
  Item.CopyProperties(PodcastItem, [mpiThumbnail,mpiYear,mpiActor,mpiDirector,mpiProducer,mpiGenre]);
  gnTotalItems++;
  return Item;
}

///////////////////////////////////////////////////////////////////////////////
// Создание папки подкаста
THmsScriptMediaItem CreateFolder(THmsScriptMediaItem ParentFolder, string sName, string sLink, string sImg=&apos;&apos;) {
  if (sImg==&apos;&apos;) sImg = mpThumbnail;
  THmsScriptMediaItem Item = ParentFolder.AddFolder(sLink); // Создаём папку с указанной ссылкой
  Item[mpiTitle     ] = sName; // Присваиваем наименование
  Item[mpiThumbnail ] = sImg;  // Картинка
  Item[mpiCreateDate] = DateTimeToStr(IncTime(gStart, 0, -gnTotalItems, 0, 0)); // Для обратной сортировки по дате создания
  gnTotalItems++;             // Увеличиваем счетчик созданных элементов
  return Item;                // Возвращаем созданный объект
}

///////////////////////////////////////////////////////////////////////////////
// Создание ссылок видео
void CreateLinks() {
  string sHtml, sData, sLink, sName, sTime, sImg, sVal, sSeason;
  THmsScriptMediaItem Item; TRegExpr RegEx; TRegExpr re;
    
  sHtml = HmsDownloadURL(mpFilePath, &apos;Referer: &apos;+mpFilePath, true);
  sHtml = HmsUtf8Decode(sHtml);
  sHtml = HmsRemoveLineBreaks(sHtml);
    
  if ((&apos;&apos;)) {
      
  } else {
            
  }
  
  sHtml = HmsUtf8Decode(HmsDownloadURL(mpFilePath));
  
  // Ищем плейлист в зангуженном html
  if (HmsRegExMatch(&apos;var autoplaylist = new Playerjs(.*?)}]&apos;, sHtml, sData, 1, PCRE_SINGLELINE)) {
    // Найден плейлист, значит это сериал. Его содержимое помещено в sData.
    
    // Создаём объект TRegExpr для поиска блоков по регулярному выражению
    RE = TRegExpr.Create(&apos;"comment":"(.*?)","file":"(.*?)"},&apos;, PCRE_SINGLELINE);
    // Ищем элементы li и ссылки в них
    if (RE.Search(sData)) do {
      sLink = RE.Match(0); // Первая группировка в скобках регулярного выражения
      sName = RE.Match(1); // Целиком найденный блок всего регулярного выражения
      sName = HmsHtmlToText(sName); // Превращаем html в текст
      sLink = ReplaceStr(sLink, &apos;"comment":"&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;,"file":"&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;:hls:manifest.m3u8"},&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;"&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;},&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;1 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;2 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;3 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;4 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;5 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;6 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;7 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;8 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;9 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;10 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;1http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;20 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;2http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;30 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;3http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;40 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;4http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;50 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;5http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;60 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;6http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;70 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;7http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;80 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;8http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
      sLink = ReplaceStr(sLink, &apos;90 серия&apos;, &apos;&apos;);
      sLink = ReplaceStr(sLink, &apos;9http:&apos;, &apos;&apos;);
      if (LeftCopy(mpFilePath, 2)==&apos;//&apos;) mpFilePath = &apos;http:&apos;+Trim(mpFilePath);
                        
      // Если ссылка указана без протокола, добавляем его
      if (LeftCopy(sLink, 2)=="//") sLink = "http:"+Trim(sLink);
      
      // Создаём ссылку на серию
      Item = CreateMediaItem(PodcastItem, sName, sLink);
      Item[mpiTitle] = sName;
      
    } while (RE.SearchAgain);
    RE.Free;
    
  } else if (HmsRegExMatch(&apos;&apos;, sHtml, sLink)) {
    // Найден ссылка на iframe, просто создаём ссылку на видео
    
    if (LeftCopy(sLink, 2)=="//") sLink = "http:"+Trim(sLink);
    
    Item = CreateMediaItem(PodcastItem, sName, sLink);
    Item[mpiTitle] = mpTitle;
    
  } else {
    HmsLogMessage(1, "В загруженной странице не найдена ссылка на видео.");
  }
  
}
 
///////////////////////////////////////////////////////////////////////////////
// Получение ссылки на медиаресурс в переменную MediaResourceLink
void GetLink() {
  if      (LeftCopy(mpFilePath, 4)==&apos;Info&apos;);
  else if (LeftCopy(mpFilePath, 3)==&apos;Err&apos; );
  else MediaResourceLink = mpFilePath;
}

///////////////////////////////////////////////////////////////////////////////
//                     Г Л А В Н А Я   П Р О Ц Е Д У Р А                     //
{
  
  // Проверяем, при каком событии было вызвано выполнение скрипта (не папка ли это)
  if (PodcastItem.IsFolder) {
    
    PodcastItem.DeleteChildItems();

    CreateLinks(); // Это зашли в папку подкаста (фильма) - создаём ссылки

  } else {
    
    GetLink(); // Это запустили фильм - получаем ссылку на медиа-поток
    
    // Если в MediaResourceLink пусто, значит получить ссылку не получилось - выводим видео об ошибке
    if (MediaResourceLink==&apos;&apos;) MediaResourceLink = &apos;http://wonky.lostcut.net/vids/podcasterror_hd.mp4&apos;;
  }

}</Value>
    </Property>
    <Property>
      <ID>551</ID>
      <Value>C++Script</Value>
    </Property>
    <Property>
      <ID>50</ID>
      <Value>Фильмы - LIVESTREAM - FFMPEG - STREAM</Value>
    </Property>
    <Property>
      <ID>55</ID>
      <Value>http://hdserials.club/templates/hdserial/images/favicon.ico</Value>
    </Property>
    <Property>
      <ID>572</ID>
      <Value>Нет скрипта</Value>
    </Property>
  </Properties>
  <ChildItems>
    <Item>
      <ClassID>53</ClassID>
      <ItemID>f7f17318-b3e3-446e-99e2-3a1e791f449d</ItemID>
      <ItemPath>http://hdserials.club/xfsearch/ТНТ/</ItemPath>
      <ParentID>84b3cae1-8df9-48f3-b688-b44ed7e3943f</ParentID>
      <Properties>
        <Property>
          <ID>515</ID>
          <Value>2</Value>
        </Property>
        <Property>
          <ID>512</ID>
          <Value>2</Value>
        </Property>
        <Property>
          <ID>532</ID>
          <Value>2</Value>
        </Property>
        <Property>
          <ID>700</ID>
          <Value>2</Value>
        </Property>
        <Property>
          <ID>553</ID>
          <Value>2</Value>
        </Property>
        <Property>
          <ID>42</ID>
          <Value>3</Value>
        </Property>
        <Property>
          <ID>4</ID>
          <Value>ТНТ</Value>
        </Property>
        <Property>
          <ID>701</ID>
          <Value>-1</Value>
        </Property>
        <Property>
          <ID>702</ID>
          <Value>-1</Value>
        </Property>
        <Property>
          <ID>517</ID>
          <Value>578-720,722-1080,482-576,402-480,322-400,202-320,0-200</Value>
        </Property>
        <Property>
          <ID>518</ID>
          <Value>0</Value>
        </Property>
        <Property>
          <ID>522</ID>
          <Value>0</Value>
        </Property>
        <Property>
          <ID>245</ID>
          <Value>f7f17318-b3e3-446e-99e2-3a1e791f449d</Value>
        </Property>
        <Property>
          <ID>93</ID>
          <Value>43532,5933011921</Value>
        </Property>
        <Property>
          <ID>525</ID>
          <Value>43532,6031475463</Value>
        </Property>
      </Properties>
    </Item>
  </ChildItems>
  <HmsTranscodingConfig>
    <TranscoderList>
      <Transcoder>
        <Name>HMSMPEG</Name>
        <Path>hmsmpeg.exe</Path>
        <HomePage>http://www.ffmpeg.org/</HomePage>
        <Download></Download>
      </Transcoder>
      <Transcoder>
        <Name>HmsMPEG</Name>
        <Path>Hmsmpeg.exe</Path>
        <HomePage>http://www.ffmpeg.org/</HomePage>
        <Download></Download>
      </Transcoder>
      <Transcoder>
        <Name>hmsMPEG</Name>
        <Path>hmsmpeg.exe</Path>
        <HomePage>http://www.ffmpeg.org/</HomePage>
        <Download></Download>
      </Transcoder>
    </TranscoderList>
    <TranscodingProfileList>
      <Profile>
        <TranscoderName>HMSMPEG</TranscoderName>
        <TranscodingCondition></TranscodingCondition>
        <TranscodingConditionSyntaxType>PascalScript</TranscodingConditionSyntaxType>
        <TranscodingComment></TranscodingComment>
        <TranscodingFolder>Транскодирование для интернет медиа-ресурсов</TranscodingFolder>
        <TranscodingMediaType>3</TranscodingMediaType>
        <TranscodingMimeType></TranscodingMimeType>
        <TranscodingMimeTypeScript>cfgTranscodingVideoMimeType</TranscodingMimeTypeScript>
        <TranscodingMimeTypeSyntaxType>PascalScript</TranscodingMimeTypeSyntaxType>
        <TranscodingMode>1</TranscodingMode>
        <TranscodingParams>// Версия 2.02 (HMS pipe)
// Профиль берет ссылку на медиаресурс через скрипт получения ссылки,
// используя: HmsGetItemProperty(mpiMediaResourceLink) и получает поток
// напрямую, минуя встроенные в livestreamer плагины, используя конструкцию:
// protocol://path [key=value]
// Например:
// livestreamer "rtmp://streaming.server.net/playpath live=1 swfVfy=http://server.net/flashplayer.swf"
// livestreamer hds://streaming.server.net/playpath/manifest.f4m
// За определение типа потока отвечает функция GetStreamType
// 04.06 - В код добавлены параметры командной строки на будущее
// Добавлен параметр --default-stream на случай пустой переменной csQuality
//
// Stream transport options
// --hds-live-edge SECONDS
// --hds-segment-attempts ATTEMPTS
// --hds-segment-threads THREADS
// --hds-segment-timeout TIMEOUT
// --hds-timeout TIMEOUT
// --hls-live-edge SEGMENTS
// --hls-segment-attempts ATTEMPTS
// --hls-segment-threads THREADS
// --hls-segment-timeout TIMEOUT
// --hls-timeout TIMEOUT
// --http-stream-timeout TIMEOUT
// --ringbuffer-size SIZE
//
// --rtmp-proxy PROXY, --rtmpdump-proxy PROXY
// --rtmp-rtmpdump FILENAME, --rtmpdump FILENAME, -r FILENAME
// --rtmp-timeout TIMEOUT
// --stream-segment-attempts ATTEMPTS
// --stream-segment-threads THREADS
// --stream-segment-timeout TIMEOUT
// --stream-timeout TIMEOUT
// HTTP PROXY
// --http-proxy HTTP_PROXY
// --https-proxy HTTPS_PROXY
// --http-cookie KEY=VALUE
// --http-header KEY=VALUE
// --http-query-param KEY=VALUE
// --http-ignore-env
// --http-no-ssl-verify
// --http-ssl-cert FILENAME
// --http-ssl-cert-crt-key CRT_FILENAME KEY_FILENAME
// --http-timeout TIMEOUT
// Plugin options
// --twitch-oauth-token TOKEN
// --twitch-oauth-authenticate
// --twitch-cookie COOKIES
// --ustream-password PASSWORD
// --crunchyroll-username USERNAME
// --crunchyroll-password [PASSWORD]
// --crunchyroll-purge-credentials
// --livestation-email EMAIL
// --livestation-password PASSWORD
// Полное описание тут: http://docs.livestreamer.io/cli.html
const
  csDumpParams = &apos;%s "%s" --default-stream "best" --hls-segment-threads 3 --hls-segment-attempts 1 -l %s -f -o "%s"&apos;;
  csQuality = "720p,480p,best";         //Предпочитаемое качество потока
  cbDebug = False;                      //Активация режима отладки
  csPathToLog = &apos;d:\tmp\livestream-ffmpeg-stream.log&apos;; //Путь в файлу для записи отладочной информации
                                        //его содержимое выслать автору
  
procedure DoDebug(const strToLog: string);
var 
  sCurrLog: String;
begin
  if cbDebug then
  begin
    if FileExists(csPathToLog) then sCurrLog := HmsStringFromFile(csPathToLog); 
    HmsStringToFile(sCurrLog+#13+VarToStr(Now)+&apos; &apos;+strToLog, csPathToLog);
    HmsLogMessage(1, strToLog);
  end;
end;

// На вход функция принимает декодированную ссылку, возвращает тип потока
function GetStreamType(const aInputLink: String): String; 
var
  sInputFileName: String;
begin
  DoDebug("Getting stream type");
  Result := &apos;&apos;;
  if EndPos(aInputLink,&apos;.m3u8&apos;) then Result := &apos;hls://&apos;
  else if EndPos(aInputLink,&apos;.f4m&apos;) then Result := &apos;hds://&apos;
end;

// На вход функция принимает ссылку и тип потока, возвращает True или False, а так же имя файла pipe
function ExecuteLivestreamer(const aCommandLine, aLinkType: string; var aInputFileName: string): boolean;
var
  sDumpParams, sReadPipeName, sWritePipeName, sDebugKey: string;
  bTest: Boolean;
begin
  Result := False;
  if (HmsCreateDualPipe(sReadPipeName, sWritePipeName)) then
    begin
      DoDebug("Executing livestreamer stage, creating pipes: for WRITE "+sWritePipeName+" and for READ "+sReadPipeName);
      bTest := HmsFileLocked(sWritePipeName);
      DoDebug("Is pipe "+sWritePipeName+" writable: "+Str(bTest));
      if bTest then
        Begin
          if cbDebug then sDebugKey := &apos;debug&apos;
          else sDebugKey := &apos;none&apos;;
          sDumpParams := Format(&apos;"%s" "%s" --default-stream "best" --hls-segment-threads 3 --hls-segment-attempts 1 -l %s -f -o "%s"&apos;, [aLinkType+aCommandLine, csQuality, sDebugKey, sWritePipeName]);
          DoDebug("Livestreamer exec params: "+sDumpParams);
          Result := HmsTranscodingExecute(&apos;LSTREAMER&apos;, sDumpParams, False);
          DoDebug("Result of execution: "+Str(Result));
          if Result then
            aInputFileName := sReadPipeName
        end;
    end
end;

// На вход принимает ссылку, возвращает True, если livestreamer может обработать ссылку или False, если не может
function CheckForValidLink(const aInputFileName: string) : boolean;

begin
  Result := False;
  //Result := HmsTranscodingExecute(&apos;LSTREAMER&apos;,&apos;--can-handle-url &apos;+InputFileName);
  DoDebug("Is link valid: "+str(Result));
end;

var 
  bSuccess, bLinkValid: Boolean;
  sLinkType, sFileType, sInputFileName, sRtmpServer, sRtmpFile, sTranscodingParams: string;  
begin
  TranscodingResult := False;
  DoDebug("Обработка для профиля устройства: "+Str(cfgDeviceType));
  if HmsGetStreamCount = 0 then  
    HmsRetrieveProperties;
  InputFileName := Trim(HmsGetItemProperty(mpiMediaResourceLink));
  if InputFileName = &apos;&apos; then InputFileName := HmsGetItemProperty(mpiFilePath);
  DoDebug("URI ресурса: "+InputFileName);
  sLinkType := GetStreamType(InputFileName);
  
  if sLinkType &lt;&gt; &apos;&apos; then
    begin
      bSuccess := ExecuteLivestreamer(InputFileName, sLinkType, sInputFileName);
      DoDebug("Livestreamer part worked, going to transcode pipe: "+sInputFileName);
    end
  else
    begin
      bSuccess := False;
      DoDebug("Livestreamer didn&apos;t found any valid stream on URL: "+InputFileName);
    end;  
  // Берем базовые параметры транскодирования из профиля Фильмы (основной)
  sTranscodingParams := HmsTranscodingProfileParams(&apos;Фильмы (основной)&apos;);
  if bSuccess then begin
    mpInternetItem := False;
    sTranscodingParams := ReplaceStr(sTranscodingParams, &apos;&lt;HMSMPEG&gt; &apos;, &apos;&apos;);
  end else
    begin
      sInputFileName := InputFileName;
      DoDebug("Transcoding without livestreamer")
    end;
  sTranscodingParams := sTranscodingParams + &apos; -strict experimental "&lt;OUTPUT FILE&gt;"&apos;;
  DoDebug("Starting transcode with commandline: "+sTranscodingParams);
  TranscodingResult := HmsTranscodingExecute(&apos;HMSMPEG&apos;, sTranscodingParams, True, sInputFileName, OutputFileName);
  DoDebug("Finishing transcode with result: "+Str(TranscodingResult));  
end.</TranscodingParams>
        <TranscodingParamsSyntaxType>PascalScript</TranscodingParamsSyntaxType>
        <TranscodingProfile>Фильмы - LIVESTREAM - FFMPEG - STREAM</TranscodingProfile>
        <TranscodingProfileActive>-1</TranscodingProfileActive>
        <TranscodingProfilePriority>52</TranscodingProfilePriority>
        <TranscodingProfileUuid>ef6d6aeb-f4d1-4f52-b3c0-ee64a7562ef3</TranscodingProfileUuid>
      </Profile>
    </TranscodingProfileList>
  </HmsTranscodingConfig>
</HmsMediaItem>
