viktar, спасибо, ваши подсказки работают.
viktar wrote:Может все-таки кто-нибудь просветит как загрузить свойства файла из скрипта (нужна длительность)? Мой Sony Blue-ray не парится по поводу запроса длительности с веб-сайта а пытается проиграть 40 минут указанные в скрипте по умолчанию.
Там на сайте или в плейлисте длительность взять абсолютно негде. Значит, есть два варианта.
Вариант №1: Прочитать MediaInfo.
У
Eugene есть
замечательный пост по поводу команды "HmsCreateMediaItemTags".
Так вот на основе того поста можно, например, добавить новую функцию
- [+] GetDurationFromMediaInfo
Code: Select all
// ----------------------------- Получение длительности видео из MeiaInfo ----
Function GetDurationFromMediaInfo(var MediaItem: THmsScriptMediaItem): string;
var
FileTags: THmsScriptFileTags; nTimeInSec: Integer;
begin
Result := '00:45:00.000';
FileTags := HmsCreateMediaItemTags('MediaInfo', MediaItem);
if FileTags <> nil then try
//Result := FileTags.GetTagValue('Duration/String3');
nTimeInSec := FileTags.GetTagValue('Duration')/1000;
Result := HmsTimeFormat(nTimeInSec)+'.000';
finally
FileTags.Free
end
end;
В нашем случае, в скрипте, там где:
Code: Select all
var
name, kat,id,pap,pap1,pl,abc_dir: string;
нужно добавить глобальную переменную gsTime, чтобы получилось
Code: Select all
var
name, kat,id,pap,pap1,pl,abc_dir,gsTime: string;
а там где создаётся ссылка
Code: Select all
Item := HmsCreateMediaItem(sItemLink, FolderItem.ItemID , pap1); //ссылка
Item.Properties[mpiTitle] := Format('%.3d', [j]) + '. ' + sItemName; //название
Item.Properties[mpiThumbnail] := sItemImg; //картинка
Item.Properties[mpiTimeLength] := '00:45:00.000'; //длительность
добавить пару строк:
Code: Select all
Item := HmsCreateMediaItem(sItemLink, FolderItem.ItemID , pap1); //ссылка
Item.Properties[mpiTitle] := Format('%.3d', [j]) + '. ' + sItemName; //название
Item.Properties[mpiThumbnail] := sItemImg; //картинка
//Item.Properties[mpiTimeLength] := '00:45:00.000'; //длительность
if Trim(gsTime)="" then gsTime := GetDurationFromMediaInfo(Item);
Item.Properties[mpiTimeLength] := gsTime; //длительность
(Комадна Trim нам компенсирует беспроблемность неициализированной переменной)
Будет делаться всего одна попытка получения длительности первой серии, а потом эта длительность будет устанавливаться на всех остальных сериях. Как правило, серии примерно одинаковой длительности обычно. Правда не всегда, но в основном. А для вашего случая с Sony Blue-ray я бы к переменной nTimeInSec добавил бы ещё пару минут, ибо чтобы не получалось что в конце обрезает.
Вариант №2: Вместо нашей функции "GetDurationFromMediaInfo" можно попробовать мой экспериментальный подход для получения длительности flv и вставить функцию
- [+] GetFlvDuration
Code: Select all
// ----------------------------- Получение длительности видео из файла flv ----
Function GetFlvDuration(var sLink: string; sReferer: string = ''): string;
var
s, sHeaders, sHeadersOut, sServ: string; nLastBlockSize, n1, n2, n3: Integer;
begin
sHeadersOut := ''; Result := '00:45:00.000';
// Преобразуем ссылку в часть сервер / объект загрузки
if (not HmsRegExMatch2('//(.*?)(/.*)', sLink, sServ, sLink)) then Exit;
if (sReferer='') then sReferer := 'http://'+sServ+'/';
// Проверяем, flv ли это файл и поддерживается ли Range (докачка)
HmsSendRequestEx(sServ, sLink, 'HEAD', '', sHeaders, '', 80, 0, sHeadersOut, true);
if (not HmsRegExMatch('Content-Type: video/x-flv.*?Accept-Ranges: bytes', sHeadersOut, '', 1, PCRE_SINGLELINE)) then Exit;
// Берём последние 4 байта flv файла - это размер последнего блока
sHeaders := sReferer+#10#13+'Range: bytes=-4'+#10#13;
s := HmsSendRequestEx(sServ, sLink, 'GET', '', sHeaders, '', 80, 0, sHeadersOut, true);
if (Length(s) <> 4) then Exit;
nLastBlockSize := Ord(s[3]) * 256 + Ord(s[4]);
// Берём весь последний блок flv
sHeaders := sReferer+#10#13+'Range: bytes=-'+IntToStr(nLastBlockSize)+#10#13;
s := HmsSendRequestEx(sServ, sLink, 'GET', '', sHeaders, '', 80, 0, sHeadersOut, true);
// Первые три с половиной байта (тут беру только целых три) - это длительность в миллисикундах
n1 := Ord(s[1]) * 256 * 256;
n2 := Ord(s[2]) * 256;
n3 := Ord(s[3]);
Result := HmsTimeFormat(Int((n1+n2+n3)/1000))+'.000';
end;
и в скрипте сделать вызов
Code: Select all
Item := HmsCreateMediaItem(sItemLink, FolderItem.ItemID , pap1); //ссылка
Item.Properties[mpiTitle] := Format('%.3d', [j]) + '. ' + sItemName; //название
Item.Properties[mpiThumbnail] := sItemImg; //картинка
//Item.Properties[mpiTimeLength] := '00:45:00.000'; //длительность
if Trim(gsTime)="" then gsTime := GetFlvDuration(sItemLink, 'http://serialu.net/');
//if Trim(gsTime)="" then gsTime := GetDurationFromMediaInfo(Item);
Item.Properties[mpiTimeLength] := gsTime; //длительность
Вот.
Делать вещи, наподобие
Item.Properties[mpiTimeLength] := GetFlvDuration(sItemLink, 'http://serialu.net/');
не рекомендую. Ибо это не только сильное увеличение времени получения плейлиста серий (ведь для каждой ссылки будет делаться запросы на сервер), но и закидывание множеством мелких, но запросов самого сервера. А ведь подкастом могут пользоваться тысячи людей, шквал запросов на сервер обеспечен. Нужно делать их как можно меньше.
С фильмами это вообще проблема, как раз. Получать для каждого фильма длительность таким образом - это не годится.
Поэтому я обычно и предпочитаю через обновление подкаста создавать только папки с ссылками на фильмы, а при заходе в такие папки создавать уже там ссылки на видео-файлы.
Такие дела.