Страница 3 из 7

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Чт фев 15, 2018 9:53 pm
directman66
Победил!!!!

Сценарий запрос M-SEARCH обновления данных устройств Upnp
СпойлерПоказать

Код: Выделить всё

//error_reporting(E_ALL);
//ini_set('display_errors', 1);

$timeout=2;
        $msg  = 'M-SEARCH * HTTP/1.1' . "\r\n";
        $msg .= 'HOST: 239.255.255.250:1900' . "\r\n";
        $msg .= 'MAN: "ssdp:discover"' . "\r\n";
        $msg .= "MX: 3\r\n";
        $msg .= "ST: upnp:rootdevice\r\n";
        $msg .= '' . "\r\n";

        $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
        socket_sendto($socket, $msg, strlen($msg), 0, '239.255.255.250', 1900);

        socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));

        $response = array();
        do {
            $buf = null;
            @socket_recvfrom($socket, $buf, 1024, MSG_WAITALL, $from, $port);

            if (!is_null($buf)) {
//echo  $buf."<br>";
                $response[] = discoveryReponse2Array($buf);
            }
        } while (!is_null($buf));
        socket_close($socket);
//echo "<br>------------------<br>";
//print_r($response);
//echo "<br>------------------<br>";
//echo "<br>------------------<br>";

foreach ($response as $obj)
{
 $LOCATION="";
$usn=$obj[USN];
$CACHECONTROL=$obj['CACHE-CONTROL']; 
$DATE=$obj[DATE];
$LOCATION=$obj[LOCATION];
$SERVER=$obj[SERVER];
$ST=$obj[ST]; 
$NLS=$obj['01-NLS']; 
$boot=$obj['BOOTID.UPNP.ORG']; 
$conf=$obj['CONFIGID.UPNP.ORG']; 
$xuser=$obj['X-USER-AGENT'];  
$ext=$obj[EXT];
$opt=$obj[OPT]; 
 
  
 $obj=explode (":",$usn);
// print_r($obj);
$objn=$obj[1]; 
// $objn=$LOCATION;
//echo '<br>$objn:'.$objn.'<br>';
addClassObject('dnla',$objn); 
sg($objn.".USN",$usn);
sg($objn.".CACHECONTROL",$CACHECONTROL);
sg($objn.".LOCATION",$LOCATION);
sg($objn.".SERVER",$SERVER);
sg($objn.".NLS",$NLS);
sg($objn.".EXT",$ext); 
sg($objn.".OPT",$opt);  
sg($objn.".BOOTIDUPNPORG",$boot); 
sg($objn.".CONFIGIDUPNPORG",$conf); 
sg($objn.".XUSERAGENT",$xuser);  
sg($objn.".DATE",$DATE);   
sg($objn.".ST",$ST);  
sg($objn.".timestamp",time());  

 
//SQLUpdate('objects', array("ID"=>$this->id, "DESCRIPTION"=>$SERVER);  
//echo "id:".get_id($objn);
 
//SQLUpdate('objects', array("ID"=>get_id($objn), "DESCRIPTION"=>$LOCATION));   
 
//if ($prop=='0' ) echo 'name:'.$NAME."<br>"; 
//скачиваем LOCATION
 
$url=$LOCATION;
$answ=file_get_contents($url);
sg($objn.".LOCATIONXML",$answ); 
// echo $answ."<br>";
 //$xml = new SimpleXMLElement($answ);
 
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;  
  $xml->loadXML( $answ ); 
//print_r($xml);
$books = $xml->getElementsByTagName('friendlyName');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
sg($objn.".friendlyName",$book->nodeValue); 

}

$books = $xml->getElementsByTagName('manufacturer');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
sg($objn.".manufacturer",$book->nodeValue); 
} 
 
$books = $xml->getElementsByTagName('manufacturerURL');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
sg($objn.".manufacturerURL",$book->nodeValue); }
 
$books = $xml->getElementsByTagName('manufacturerURL');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
sg($objn.".manufacturerURL",$book->nodeValue); }

$books = $xml->getElementsByTagName('controlURL');
foreach ($books as $book) {
    echo $book->nodeValue, PHP_EOL;
//sg($objn.".controlURL",substr($LOCATION,0,-1).$book->nodeValue);
 sg($objn.".controlURL",$book->nodeValue); 
} 
 
$url=gg($objn.".controlURL");
$answ=file_get_contents($url);
sg($objn.".controlURLXML",$answ); 
//if (filter_var($url, FILTER_VALIDATE_URL) ) {$answ=file_get_contents($url); sg($objn.".controlURLXML",$answ); }
 
 
SQLUpdate('objects', array("ID"=>get_id($objn), "DESCRIPTION"=>gg($objn.".friendlyName")."        ".gg($objn.".LOCATION")."\n".$DATE));     
  echo "<br>"; 
 
 
  


 
 //foreach ($node as $val)
 //{echo $val."<>";}
 
 
//$url=gg($objn.".SCPDURL");
//if ($url<>"") {$answ=file_get_contents($url);} else {$answ="";}
//sg($objn.".SCPDURL_XML",$answ); 
//$url=gg($objn.".CONTROL_URL");
//if ($url<>"") {$answ=file_get_contents($url);} else {$answ="";}
//sg($objn.".CONTROL_URL_XML",$answ); 
//$url=gg($objn.".eventSubURL");
//if ($url<>"") {$answ=file_get_contents($url);} else {$answ="";}
//sg($objn.".eventSubURL_XML",$answ);  
 
 
echo "**************<br>"; 
}



   
//////////////////////////////   
//////////////////////////////   
//////////////////////////////   
//////////////////////////////


function discoveryReponse2Array($res)
    {
        $result = array();
        $lines  = explode("\n", trim($res));

        if (trim($lines[0]) == 'HTTP/1.1 200 OK') {
            array_shift($lines);
        }

        foreach ($lines as $line) {
            $tmp = explode(':', trim($line));
            $key   = strtoupper(array_shift($tmp));
            $value = (count($tmp) > 0 ? trim(join(':', $tmp)) : null);
            $result[$key] = $value;
        }

//        return (Object)$result;
         return $result;
    }

function get_id($prop)
{
$sql='SELECT id   FROM `objects`  WHERE TITLE ="'.$prop.'"';
$rec = SQLSelect($sql); 
return $rec[0][id];
}
Сценарий отправки файла на телевизор:
СпойлерПоказать

Код: Выделить всё

//вызов rs(dnlaplay, array('fn' =>$path);
$fn=$params['fn'];
if ($fn==""){$fn="http://192.168.1.31:32469/object/df4b8e517919aa1f643c/file.mkv";}

$luts=gg("9732d18b-48f1-7f50-2b02-463b0f37e9a7.timestamp");
$diff=(gmdate('i',trim(time()-$luts)));

$pattern = "|\b[0]+([1-9][\d]*)|is"; 
$diff2= preg_replace($pattern, "\\1", $diff); 
echo  "Информация  была обновлена  "  .$diff2 . " минут назад.";

if ($diff2>60) { echo "Запускаю обновление данных!"; rs('dnlasearch');}

$url=gg('9732d18b-48f1-7f50-2b02-463b0f37e9a7.LOCATION');
//$host=explode(":",$url)[0].explode(":",$url)[1];
$host=str_replace('/','',explode(":",$url)[1]);
//$host="192.168.1.41";
$port=str_replace('/','',explode(":",$url)[2]);
$controlURL=gg('9732d18b-48f1-7f50-2b02-463b0f37e9a7.controlURL');
echo 'host:'.$host."<br>";
echo 'port:'.$port."<br>";
echo 'controlURL:'.$controlURL."<br>";


//command:
//SetAVTransportURI
//Stop
//Play

//AVTransport
///AVTransport/9732d18b-48f1-7f50-2b02-463b0f37e9a7/control.xml
echo 'Stop<br>';
//Stop
$xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:Stop xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></u:Stop></s:Body></s:Envelope>
';
$asnw=sendpacket($host,$port,$controlURL,'Stop', $xml);
echo $asnw;
echo 'SetAVTransportURI<br>' ;
sleep(1);
//SetAVTransportURI
$xml = '<?xml version="1.0" encoding="utf-8" standalone="yes"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>'.$fn.'</CurrentURI><CurrentURIMetaData><DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/" xmlns:sec="http://www.sec.co.kr/" xmlns:pv="http://www.pv.com/pvns/"><item id="df4b8e517919aa1f643c" parentID="c104054e5a4c8c3c046e" restricted="1"><upnp:class>object.item.videoItem</upnp:class><dc:title>Aritmija Web Dl</dc:title><dc:creator>Unknown</dc:creator><upnp:artist>Unknown</upnp:artist><upnp:albumArtURI>http://192.168.1.31:32469/proxy/c9ccea0d9cf75f43c34b/albumart.jpg</upnp:albumArtURI><upnp:genre>Unknown</upnp:genre><res protocolInfo="http-get:*:video/x-matroska:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01500000000000000000000000000000" bitrate="692000" nrAudioChannels="6" size="4810724267" resolution="1920x1038" duration="1:55:52.000">'.$fn.'</res></item></DIDL-Lite></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>
';
$asnw=sendpacket($host,$port,$controlURL,'SetAVTransportURI', $xml);
echo $asnw;
echo 'Play<br>';
sleep(1);
//Play
$xml= '<?xml version="1.0" encoding="utf-8" standalone="yes"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>
';
$asnw=sendpacket($host,$port,$controlURL,'Play', $xml);
echo $asnw;




function sendpacket($host,$port,$AVTransport, $command, $xml){
///play
$body=$xml;
$headers = 'POST '.$AVTransport.' HTTP/1.1
Soapaction: "urn:schemas-upnp-org:service:AVTransport:1#'.$command.'"
CONTENT-TYPE: text/xml; charset="utf-8"
HOST: '.$host.':'.$port;
$content=$headers . '
Content-Length: '. strlen($body) .'

'. $body;
echo $host.":". $port;
$fp = fsockopen($host, $port , $errno, $errstr, 10);
        if (!$fp)
        {echo "Error opening socket: ".$errstr." (".$errno.")<br>";} else 
        {            
$ret = "";
$buffer = "";
         
//        fputs ($fp, $content);
//        while (!feof($fp)) {
//            $buffer = fgets($fp,128);
//            echo "\n;" . $buffer . ";\n"; 
//            $ret.= $buffer;

fwrite($fp, $content);
//while (!feof($fp)) {
//$buffer = fgets($fp,128);
//echo fgets($fp, 128);
//$ret.= $buffer; 
//    }
    fclose($fp);
        }

// echo "\n\nReturn:" . $ret . "!!\n";

fclose($fp); 
 return $ret;
 }
Тут есть конечно минус, по самбе и ftp поток не отдается. Все равно нужно что-то поднимать, вэб сервер или dnla сервер (сервис)

Телик LG 47LA662 (NETCAST) - подключено в MD! Плюсуйте!

Следующим этапом будет Youtube!

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 2:20 am
Gelezako
Хоть и вывалило кучу ошибок, но сканер нашёл несколько устройств и добавил их в виде объектов. Ещё вопрос: вы уверены что для работы нужно создавать все эти свойства с мало полезными значениями?
Далее что бы послать команду я так понял нужно подредактировать путь к нему в переменной $fn. Но я заметил что этот же путь потом встречается в хмл файле ниже. Для меня загадка почему там не используется переменная $fn?

Ещё в файле отправки команды вы делаете:

Код: Выделить всё

$luts=gg("9732d18b-48f1-7f50-2b02-463b0f37e9a7.timestamp"); 
и

Код: Выделить всё

$url=gg('9732d18b-48f1-7f50-2b02-463b0f37e9a7.LOCATION');
и

Код: Выделить всё

$controlURL=gg('9732d18b-48f1-7f50-2b02-463b0f37e9a7.controlURL');
У каждого ИД будет разный, поэтому и скрипт работать у всех не будет. Нужно и это подредактировать.

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 4:40 am
directman66
Ssid устройства вроде не меняется. Уж думаю сами замените на свой. $fn переменная, которая передается параметром в скрипт. Если она пустая, берется значение по умолчанию. Вызов с параметром указан в 1 строке скрипта вызов rs(dnlaplay, array('fn' =>$path);

Имя файла $fn должно быть указано в xml. Я менял, но почему-то тут без переменной. Поправлю чуть позже, когда буду не с телефона.

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 6:13 am
nick7zmail
Дак это получается вообще без сторонних библиотек сделано? Чисто кодом? А то я начал просматривать что для модуля надо - так и не понял особо. Ссылок нигде никаких нет))

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 6:38 am
directman66
nick7zmail писал(а):Дак это получается вообще без сторонних библиотек сделано? Чисто кодом? А то я начал просматривать что для модуля надо - так и не понял особо. Ссылок нигде никаких нет))
Да, я старался избавиться от всех лишних библиотек. Надо поэксперементировать с xml файлом. Он от форматов видео меняется

Код: Выделить всё

 bitrate="692000" nrAudioChannels="6" size="4810724267" resolution="1920x1038" duration="1:55:52.000"&
И еще картинка обложки передается. Нужны ли они - это еще вопрос. Нужно эксперементировать. Да и модуль нужен это точно!

Заметил, что порт AVTransport меняется при включении телевизора, поэтому если обновление данных по устройству было давно, нужно обновить параметры.

Мне кажется в модуле должно быть:
1) Список устройств с определением типа (модель телевизора , модель колонки или ресивера (Google Home, Echo dot...), название медиаприставкии (MAG245/250, wr320, китайские свистки, chromecast.. ). Поиск видимо придется осуществлять несколькими алгоритмами (DIAL, M-SEARCH, HTTP REST....)
2) В зависимости от типа устройства должен меняться протокол взаимодействия.
3) Привязка к HOOK SAY для колонок (чтобы Алиса на нее вещала свои сообщения)
4) Если файл лежит где-то локально, для его воспроизведения нужно поднимать web сервер или dnla. Как вариант можно попробовать использовать виртуальный хост apache2. Если файл лежит в сети по протоколам samba или ftp - пока мне не понятно что делать.
В статье из 1 поста ( https://hms.lostcut.net/viewtopic.php?id=119 ) в исходниках чувак как раз таки поднимает простенький simple server и по нему отдает поток. В принципе примеров реализации на php полно. Думаю легко решаемо.
5) Отправка ссылки приложению Youtube на телевизоре.
6) Раскурить что за TTS используют аналогичные проекты (для google home, Alexa). В какомто коде на джите видел использование движка гугл переводчика для проговаривания текста.
7) Сделать upnp сканер ресурсов домашней сети, чтобы была БД домашнего контента, который можно отправить на телевизор/Cast устройство.
8) Организовать поиск ютуб ссылки (например на запрос Дудь алгоритм должен вернуть https://www.youtube.com/watch?v=SPauxWv1Rnk,который мы уже преобразуем в
https://r1---sn-pouxga5o-vu2l.googlevid ... mm=31%2C29

Это концепция и план работы. Но мне пока недостаточно опыта в создании плагинов.



зыж Добрался до компа, поправил путь имени файла.

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 7:09 am
directman66
Gelezako писал(а):Хоть и вывалило кучу ошибок, но сканер нашёл несколько устройств и добавил их в виде объектов. Ещё вопрос: вы уверены что для работы нужно создавать все эти свойства с мало полезными значениями?
Echo dot добавился?

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 8:19 am
directman66
Протокол запуска ютуб на телевизоре и запуска воспроизведения из приложения Ютуб для андройд. Похоже ссылка на поток не отправляется телевизору. Ютуб видимо по последнему воспрозведению определяет, что проигрывать.

Из идентификаторов только это. Кроме кода сопряжения кто знает, что это?

Код: Выделить всё

pairingCode=536ca616-98dc-4767-825c-06c7d25febeb&theme=cl&rUrl=ws%3A%2F%2F192.168.1.41%3A47090%2Ff552b1d8-052d-45d3-b6a6-e6f6ef1a4d90&rId=vttgndjj9tgna1mbdul5gmmb52HTTP/1.1 201 Created
после urldecode

Код: Выделить всё

ws://192.168.1.41:47090/f552b1d8-052d-45d3-b6a6-e6f6ef1a4d90&rId=vttgndjj9tgna1mbdul5gmmb52        
Хотя тут https://hms.lostcut.net/viewtopic.php?id=119 чувак пишет, что отправляет ссылку ютуб на телик и она вопроизводится
Также, для пущих экспериментов, сделал возможность указывать ссылку на youtube, например:
testdlna.exe sony -d -f "http://www.youtube.com/watch?v=25pzrnf8xyk"

Программка сама получить ссылку на реальный видео файл и попытается его отправиться телеку.
вот кусок его исходников:

Код: Выделить всё

static string CheckKnownLinks(string link) {
            Match m = Regex.Match(link, @"youtube.*?\?v=([\w_-]+)");
            if (m.Success) {
                string videoID = m.Groups[1].Value;
                WebClient client = new WebClient();
                link = client.DownloadString("https://hms.lostcut.net/youtube/g.php?v=" + videoID + "&link_only=1");
            }
            return link;
Насколько я понял по ссылке https://hms.lostcut.net/youtube/g.php?v ... ink_only=1
где mFsvo4Ujevg -часть адреса ютуб сервис отдает прямую ссылку для вопроизведения

Код: Выделить всё

https://r2---sn-pouxga5o-vu2l.googlevideo.com/videoplayback?fvip=3&mt=1518760387&mime=video%2Fmp4&requiressl=yes&ei=SnSGWuqbN8nI1gKbuprYCQ&ip=185.53.168.230&ratebypass=yes&key=yt6&expire=1518782635&c=WEB&signature=CF62957D4785DC1AE903E4D7864F09F602114FEC.2380B9FEFC3F09FBEBD7B11B4A32660384F6AAD5&pl=24&mn=sn-pouxga5o-vu2l%2Csn-4g5e6nzs&ipbits=0&mm=31%2C29&itag=22&ms=au%2Crdu&lmt=1487585527235265&mv=u&dur=925.895&source=youtube&id=o-AL91CchY_21AQKI2d5nTEBqODZMCys7CYDOINp3bFyBB&sparams=dur%2Cei%2Cid%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire   
Эта ссылка вопроизводится!!

Интересно, можно ли скачать скрипт https://hms.lostcut.net/youtube/g.php, чтобы не зависеть от стороннего облачного сервиса.

нашел https://github.com/WendyH/HMS-Youtube

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 8:54 am
nick7zmail
Я как то отправлял через значок трансляции в ютубе...на тв открывается ютуб и играет то, что отправил...надо трафик перехватить попробовать. Вдруг там что дельное.

Отправлено с моего Xperia XZ1 Compact через Tapatalk

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 9:05 am
directman66
nick7zmail писал(а):Я как то отправлял через значок трансляции в ютубе...на тв открывается ютуб и играет то, что отправил...надо трафик перехватить попробовать. Вдруг там что дельное.

Отправлено с моего Xperia XZ1 Compact через Tapatalk
это уже и сделано! См предыдущий пост.

Re: DNLA SHARE вывод контента на SMART телевизоры

Добавлено: Пт фев 16, 2018 9:06 am
nick7zmail
Ааа...ок...

Отправлено с моего Xperia XZ1 Compact через Tapatalk