2013-08-15 12:05:58 +02:00
< ? php
/**
2016-07-08 19:06:35 +02:00
* RssBridgeYoutube
2013-08-15 12:05:58 +02:00
* Returns the newest videos
2015-11-01 12:17:36 +01:00
* WARNING : to parse big playlists ( over ~ 90 videos ), you need to edit simple_html_dom . php :
2014-05-14 14:34:06 +02:00
* change : define ( 'MAX_FILE_SIZE' , 600000 );
* into : define ( 'MAX_FILE_SIZE' , 900000 ); ( or more )
2013-08-15 12:05:58 +02:00
*/
2015-11-01 12:17:36 +01:00
class YoutubeBridge extends BridgeAbstract {
public function loadMetadatas () {
2016-05-03 23:45:32 +02:00
$this -> name = 'YouTube Bridge' ;
2016-08-11 21:42:49 +02:00
$this -> uri = 'https://www.youtube.com/' ;
2016-05-03 23:45:32 +02:00
$this -> description = 'Returns the 10 newest videos by username/channel/playlist or search' ;
$this -> maintainer = 'mitsukarenai' ;
2016-08-17 14:45:08 +02:00
$this -> update = '2016-08-17' ;
2015-11-01 12:17:36 +01:00
2016-05-03 23:45:32 +02:00
$this -> parameters [ 'By username' ] =
2015-11-01 12:17:36 +01:00
' [
{
" type " : " text " ,
" identifier " : " u " ,
" name " : " username " ,
2015-11-11 22:45:24 +01:00
" exampleValue " : " test " ,
2016-08-15 01:19:16 +02:00
" required " : true
2015-11-01 12:17:36 +01:00
}
] ' ;
$this -> parameters [ 'By channel id' ] =
' [
{
2016-05-21 11:45:09 +02:00
" type " : " text " ,
2015-11-01 12:17:36 +01:00
" identifier " : " c " ,
" name " : " channel id " ,
2016-05-03 23:45:32 +02:00
" exampleValue " : " 15 " ,
2016-08-15 01:19:16 +02:00
" required " : true
2015-11-01 12:17:36 +01:00
}
] ' ;
$this -> parameters [ 'By playlist Id' ] =
' [
{
2016-05-21 11:45:09 +02:00
" type " : " text " ,
" identifier " : " p " ,
2015-11-01 12:17:36 +01:00
" name " : " playlist id " ,
" exampleValue " : " 15 "
}
] ' ;
2016-05-03 23:45:32 +02:00
$this -> parameters [ 'Search result' ] =
2015-11-01 12:17:36 +01:00
' [
{
" type " : " text " ,
" identifier " : " s " ,
" name " : " search keyword " ,
" exampleValue " : " test "
},
{
" type " : " number " ,
" identifier " : " pa " ,
" name " : " page " ,
" exampleValue " : " 1 "
}
] ' ;
}
2016-05-03 23:45:32 +02:00
private function ytBridgeQueryVideoInfo ( $vid , & $author , & $desc , & $time ) {
2016-07-08 19:06:35 +02:00
$html = $this -> getSimpleHTMLDOM ( $this -> uri . " watch?v= $vid " );
2016-05-03 23:45:32 +02:00
$author = $html -> innertext ;
$author = substr ( $author , strpos ( $author , '"author=' ) + 8 );
$author = substr ( $author , 0 , strpos ( $author , '\u0026' ));
$desc = $html -> find ( 'div#watch-description-text' , 0 ) -> innertext ;
$time = strtotime ( $html -> find ( 'meta[itemprop=datePublished]' , 0 ) -> getAttribute ( 'content' ));
}
2014-06-20 16:41:51 +02:00
2016-05-03 23:45:32 +02:00
private function ytBridgeAddItem ( $vid , $title , $author , $desc , $time ) {
$item = new \Item ();
$item -> id = $vid ;
$item -> title = $title ;
$item -> author = $author ;
$item -> timestamp = $time ;
2016-08-09 20:01:21 +02:00
$item -> uri = $this -> uri . 'watch?v=' . $vid ;
$thumbnailUri = str_replace ( '/www.' , '/img.' , $this -> uri ) . 'vi/' . $vid . '/0.jpg' ;
2016-08-09 15:50:25 +02:00
$item -> content = '<a href="' . $item -> uri . '"><img src="' . $thumbnailUri . '" /></a><br />' . $desc ;
2016-05-03 23:45:32 +02:00
$this -> items [] = $item ;
}
2014-06-20 16:41:51 +02:00
2016-05-03 23:45:32 +02:00
private function ytBridgeParseXmlFeed ( $xml ) {
foreach ( $xml -> find ( 'entry' ) as $element ) {
2016-05-21 11:45:09 +02:00
$title = $this -> ytBridgeFixTitle ( $element -> find ( 'title' , 0 ) -> plaintext );
2016-05-03 23:45:32 +02:00
$author = $element -> find ( 'name' , 0 ) -> plaintext ;
$desc = $element -> find ( 'media:description' , 0 ) -> innertext ;
$vid = str_replace ( 'yt:video:' , '' , $element -> find ( 'id' , 0 ) -> plaintext );
$time = strtotime ( $element -> find ( 'published' , 0 ) -> plaintext );
$this -> ytBridgeAddItem ( $vid , $title , $author , $desc , $time );
}
2016-05-21 11:45:09 +02:00
$this -> request = $this -> ytBridgeFixTitle ( $xml -> find ( 'feed > title' , 0 ) -> plaintext );
2016-05-03 23:45:32 +02:00
}
2014-05-14 12:39:12 +02:00
2016-05-03 23:45:32 +02:00
private function ytBridgeParseHtmlListing ( $html , $element_selector , $title_selector ) {
$limit = 10 ; $count = 0 ;
foreach ( $html -> find ( $element_selector ) as $element ) {
if ( $count < $limit ) {
$author = '' ; $desc = '' ; $time = 0 ;
$vid = str_replace ( '/watch?v=' , '' , $element -> find ( 'a' , 0 ) -> href );
2016-05-21 11:45:09 +02:00
$title = $this -> ytBridgeFixTitle ( $element -> find ( $title_selector , 0 ) -> plaintext );
if ( $title != '[Private Video]' ) {
$this -> ytBridgeQueryVideoInfo ( $vid , $author , $desc , $time );
$this -> ytBridgeAddItem ( $vid , $title , $author , $desc , $time );
$count ++ ;
}
2014-06-20 17:00:36 +02:00
}
}
2016-05-03 23:45:32 +02:00
}
2016-05-21 11:45:09 +02:00
private function ytBridgeFixTitle ( $title ) {
// convert both Ӓ and " to UTF-8
2016-06-25 10:08:06 +02:00
return html_entity_decode ( $title , ENT_QUOTES , 'UTF-8' );
2016-05-21 11:45:09 +02:00
}
2016-05-03 23:45:32 +02:00
public function collectData ( array $param ) {
$xml = '' ;
$html = '' ;
$url_feed = '' ;
$url_listing = '' ;
2014-05-14 12:39:12 +02:00
2016-05-03 23:45:32 +02:00
if ( isset ( $param [ 'u' ])) { /* User and Channel modes */
$this -> request = $param [ 'u' ];
2016-08-09 20:01:21 +02:00
$url_feed = $this -> uri . 'feeds/videos.xml?user=' . urlencode ( $this -> request );
$url_listing = $this -> uri . 'user/' . urlencode ( $this -> request ) . '/videos' ;
2016-05-03 23:45:32 +02:00
} else if ( isset ( $param [ 'c' ])) {
2014-08-19 21:35:56 +02:00
$this -> request = $param [ 'c' ];
2016-08-09 20:01:21 +02:00
$url_feed = $this -> uri . 'feeds/videos.xml?channel_id=' . urlencode ( $this -> request );
$url_listing = $this -> uri . 'channel/' . urlencode ( $this -> request ) . '/videos' ;
2016-05-03 23:45:32 +02:00
}
if ( ! empty ( $url_feed ) && ! empty ( $url_listing )) {
2016-07-08 19:06:35 +02:00
if ( $xml = $this -> getSimpleHTMLDOM ( $url_feed )) {
2016-05-03 23:45:32 +02:00
$this -> ytBridgeParseXmlFeed ( $xml );
2016-07-08 19:06:35 +02:00
} else if ( $html = $this -> getSimpleHTMLDOM ( $url_listing )) {
2016-05-03 23:45:32 +02:00
$this -> ytBridgeParseHtmlListing ( $html , 'li.channels-content-item' , 'h3' );
2016-08-17 14:45:08 +02:00
} else $this -> returnServerError ( " Could not request YouTube. Tried: \n - $url_feed\n - $url_listing " );
2014-08-19 21:35:56 +02:00
}
2016-05-03 23:45:32 +02:00
else if ( isset ( $param [ 'p' ])) { /* playlist mode */
2014-06-20 17:00:36 +02:00
$this -> request = $param [ 'p' ];
2016-08-09 20:01:21 +02:00
$url_listing = $this -> uri . 'playlist?list=' . urlencode ( $this -> request );
2016-07-08 19:06:35 +02:00
$html = $this -> getSimpleHTMLDOM ( $url_listing ) or $this -> returnServerError ( " Could not request YouTube. Tried: \n - $url_listing " );
2016-05-03 23:45:32 +02:00
$this -> ytBridgeParseHtmlListing ( $html , 'tr.pl-video' , '.pl-video-title a' );
2016-05-21 11:45:09 +02:00
$this -> request = 'Playlist: ' . str_replace ( ' - YouTube' , '' , $html -> find ( 'title' , 0 ) -> plaintext );
2014-06-20 17:04:27 +02:00
}
2013-08-15 12:05:58 +02:00
2016-05-03 23:45:32 +02:00
else if ( isset ( $param [ 's' ])) { /* search mode */
2016-07-08 19:06:35 +02:00
$this -> request = $param [ 's' ]; $page = 1 ; if ( isset ( $param [ 'pa' ])) $page = ( int ) preg_replace ( " /[^0-9]/ " , '' , $param [ 'pa' ]);
2016-08-09 20:01:21 +02:00
$url_listing = $this -> uri . 'results?search_query=' . urlencode ( $this -> request ) . '&page=' . $page . '&filters=video&search_sort=video_date_uploaded' ;
2016-07-08 19:06:35 +02:00
$html = $this -> getSimpleHTMLDOM ( $url_listing ) or $this -> returnServerError ( " Could not request YouTube. Tried: \n - $url_listing " );
2016-05-03 23:45:32 +02:00
$this -> ytBridgeParseHtmlListing ( $html , 'div.yt-lockup' , 'h3' );
$this -> request = 'Search: ' . str_replace ( ' - YouTube' , '' , $html -> find ( 'title' , 0 ) -> plaintext );
2014-06-20 17:00:36 +02:00
}
2016-05-03 23:45:32 +02:00
else { /* no valid mode */
2016-08-17 14:45:08 +02:00
$this -> returnClientError ( " You must either specify either: \n - YouTube username (?u=...) \n - Channel id (?c=...) \n - Playlist id (?p=...) \n - Search (?s=...) " );
2016-05-03 23:45:32 +02:00
}
}
2014-06-20 17:00:36 +02:00
public function getName (){
2016-05-03 23:45:32 +02:00
return ( ! empty ( $this -> request ) ? $this -> request . ' - ' : '' ) . 'YouTube Bridge' ;
2014-06-20 17:00:36 +02:00
}
2013-08-15 12:05:58 +02:00
2014-06-20 17:00:36 +02:00
public function getCacheDuration (){
return 10800 ; // 3 hours
}
2013-08-15 12:05:58 +02:00
}