| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- <?php
- class vimeo{
-
- public function __construct(){
-
- include "lib/backend.php";
- $this->backend = new backend("vimeo");
-
- include "lib/fuckhtml.php";
- $this->fuckhtml = new fuckhtml();
- }
-
- public function getfilters($page){
-
- return [
- "time" => [
- "display" => "Date uploaded", // &filter_uploaded=
- "option" => [
- "any" => "Any time",
- "today" => "Last 24 hours",
- "this-week" => "Last 7 days",
- "this-month" => "Last 30 days",
- "this-year" => "Last 365 days",
- ]
- ],
- "display" => [
- "display" => "Display",
- "option" => [
- "video" => "Videos",
- "ondemand" => "On-Demand ($$)",
- "people" => "People",
- "channel" => "Channels",
- "group" => "Groups"
- ]
- ],
- "sort" => [
- "display" => "Sort by",
- "option" => [
- "relevance" => "Relevance", // no param
- "recent" => "Newest", // &sort=latest&direction=desc
- "popular" => "Most popular", // &sort=popularity&direction=desc
- "a_z" => "Title, A to Z", // &sort=alphabetical&direction=asc
- "z_a" => "Title, Z to A", // &sort=alphabetical&direction=desc
- "longest" => "Longest", // &sort=duration&direction=desc
- "shortest" => "Shortest", // &sort=duration&direction=asc
- ]
- ],
- "duration" => [
- "display" => "Duration", // &filter_duration=
- "option" => [
- "any" => "Any duration",
- "short" => "Short (less than 4 minutes)",
- "medium" => "Medium (4-10 minutes)",
- "long" => "Long (over 10 minutes)"
- ]
- ],
- "resolution" => [
- "display" => "Resolution",
- "option" => [
- "any" => "Any resolution",
- "4k" => "4K" // &filter_resolution=4k
- ]
- ],
- "category" => [
- "display" => "Category", // &filter_category=
- "option" => [
- "any" => "Any category",
- "animation" => "Animation",
- "comedy" => "Comedy",
- "music" => "Music",
- "experimental" => "Experimental",
- "documentary" => "Documentary",
- "identsandanimatedlogos" => "Idents and Animated Logos",
- "industry" => "Industry",
- "instructionals" => "Instructionals",
- "narrative" => "Narrative",
- "personal" => "Personal"
- ]
- ],
- "live" => [
- "display" => "Live events",
- "option" => [
- "any" => "Any",
- "yes" => "Live now" // &filter_live=now
- ]
- ],
- "hdr" => [
- "display" => "HDR", // &filter_hdr=
- "option" => [
- "any" => "Any",
- "hdr" => "Any HDR",
- "dolby_vision" => "Dolby Vision",
- "hdr10" => "HDR10",
- "hdr10+" => "HDR10+"
- ]
- ],
- "vimeo_360" => [
- "display" => "Vimeo 360°", // &filter_vimeo_360
- "option" => [
- "any" => "Any",
- "spatial" => "Spatial",
- "360" => "360°"
- ]
- ],
- "price" => [ // &filter_price=
- "display" => "Price",
- "option" => [
- "any" => "Any price",
- "free" => "Free",
- "paid" => "Paid"
- ]
- ],
- "collection" => [
- "display" => "Vimeo collections",
- "option" => [
- "any" => "Any collection",
- "staff_pick" => "Staff picks" // &filter_staffpicked=true
- ]
- ],
- "license" => [ // &filter_license=
- "display" => "License",
- "option" => [
- "any" => "Any license",
- "by-nc-nd" => "CC BY-NC-ND",
- "by" => "CC BY",
- "by-nc" => "CC BY-NC",
- "by-nc-sa" => "CC BY-NC-SA",
- "by-nd" => "CC BY-ND",
- "by-sa" => "CC BY-SA",
- "cc0" => "CC0"
- ]
- ]
- ];
- }
-
- private function get($proxy, $url, $get = [], $jwt = false){
-
- $curlproc = curl_init();
-
- if($get !== []){
- $get = http_build_query($get);
- $url .= "?" . $get;
- }
-
- curl_setopt($curlproc, CURLOPT_URL, $url);
- curl_setopt($curlproc, CURLOPT_ENCODING, ""); // default encoding
-
- if($jwt === false){
-
- curl_setopt(
- $curlproc,
- CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: */*",
- "Accept-Language: en-US,en;q=0.5",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "Referer: https://vimeo.com/search",
- "X-Requested-With: XMLHttpRequest",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Sec-Fetch-Dest: empty",
- "Sec-Fetch-Mode: cors",
- "Sec-Fetch-Site: same-origin",
- "Priority: u=4"]
- );
-
- }else{
-
- curl_setopt(
- $curlproc,
- CURLOPT_HTTPHEADER,
- ["User-Agent: " . config::USER_AGENT,
- "Accept: application/vnd.vimeo.*+json;version=3.3",
- "Accept-Language: en",
- "Accept-Encoding: gzip, deflate, br, zstd",
- "Referer: https://vimeo.com/",
- "Content-Type: application/json",
- "Authorization: jwt $jwt",
- "Vimeo-Page: /search/[[...slug]]",
- "Origin: https://vimeo.com",
- "DNT: 1",
- "Sec-GPC: 1",
- "Connection: keep-alive",
- "Sec-Fetch-Dest: empty",
- "Sec-Fetch-Mode: cors",
- "Sec-Fetch-Site: same-site",
- "Priority: u=4"]
- );
- }
-
-
- curl_setopt($curlproc, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYHOST, 2);
- curl_setopt($curlproc, CURLOPT_SSL_VERIFYPEER, true);
- curl_setopt($curlproc, CURLOPT_CONNECTTIMEOUT, 30);
- curl_setopt($curlproc, CURLOPT_TIMEOUT, 30);
- $this->backend->assign_proxy($curlproc, $proxy);
-
- $data = curl_exec($curlproc);
-
- if(curl_errno($curlproc)){
-
- throw new Exception(curl_error($curlproc));
- }
-
- curl_close($curlproc);
- return $data;
- }
-
- public function video($get){
-
- // parse shit
- if($get["npt"]){
-
- [$npt, $proxy] =
- $this->backend
- ->get(
- $get["npt"],
- "videos"
- );
-
- $npt = json_decode($npt, true);
- $pagetype = $npt["pagetype"];
- $npt = $npt["npt"];
-
- $jwt = $this->get_jwt($proxy);
-
- try{
-
- $json =
- $this->get(
- $proxy,
- "https://api.vimeo.com" . $npt,
- [],
- $jwt
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch JSON");
- }
-
- }else{
-
- $proxy = null;
- $jwt = $this->get_jwt($proxy); // this gives us a proxy by reference
-
- // parse filters
- $npt = [
- "query" => $get["s"],
- "page" => 1,
- "per_page" => 24,
- "facets" => "type"
- ];
-
- switch($get["display"]){
-
- case "video":
- $npt["filter_type"] = "clip";
- $npt["fields"] = "clip.name,stats.plays,clip.pictures,clip.user.name,clip.user.link,clip.user.pictures.sizes,clip.uri,clip.stats.plays,clip.duration,clip.created_time,clip.link,clip.description";
- break;
-
- case "ondemand":
- $npt["filter_type"] = "ondemand";
- $npt["sizes"] = "296x744";
- $npt["fields"] = "ondemand.link,ondemand.name,ondemand.pictures.sizes,ondemand.metadata.interactions.buy,ondemand.metadata.interactions.rent,ondemand.uri";
- break;
-
- case "people":
- $npt["filter_type"] = "people";
- $npt["fetch_user_profile"] = "1";
- $npt["fields"] = "people.name,people.location_details.formatted_address,people.metadata.public_videos.total,people.pictures.sizes,people.link,people.metadata.connections.followers.total,people.skills.name,people.skills.uri,people.background_video,people.uri";
- break;
-
- case "channel":
- $npt["filter_type"] = "channel";
- $npt["fields"] = "channel.name,channel.metadata.connections.users.total,channel.metadata.connections.videos.total,channel.pictures.sizes,channel.link,channel.uri";
- break;
-
- case "group":
- $npt["filter_type"] = "group";
- $npt["fields"] = "group.name,group.metadata.connections.users.total,group.metadata.connections.videos.total,group.pictures.sizes,group.link,group.uri";
- break;
- }
-
- // only apply filters if we're searching for videos
- if($get["display"] == "video"){
-
- switch($get["sort"]){
-
- case "relevance": break; // do nothing
-
- case "recent":
- $npt["sort"] = "latest";
- $npt["direction"] = "desc";
- break;
-
- case "popular":
- $npt["sort"] = "popularity";
- $npt["direction"] = "desc";
- break;
-
- case "a_z":
- $npt["sort"] = "alphabetical";
- $npt["direction"] = "asc";
- break;
-
- case "z_a":
- $npt["sort"] = "alphabetical";
- $npt["direction"] = "desc";
- break;
-
- case "longest":
- $npt["sort"] = "duration";
- $npt["direction"] = "desc";
- break;
-
- case "shortest":
- $npt["sort"] = "duration";
- $npt["direction"] = "asc";
- break;
- }
-
- if($get["time"] != "any"){
-
- $npt["filter_uploaded"] = $get["time"];
- }
-
- if($get["duration"] != "any"){
-
- $npt["filter_duration"] = $get["duration"];
- }
-
- if($get["resolution"] != "any"){
-
- $npt["filter_resolution"] = $get["resolution"];
- }
-
- if($get["category"] != "any"){
-
- $npt["filter_category"] = $get["category"];
- }
-
- if($get["live"] != "any"){
-
- $npt["filter_live"] = "now";
- }
-
- if($get["hdr"] != "any"){
-
- $npt["filter_hdr"] = $get["hdr"];
- }
-
- if($get["vimeo_360"] != "any"){
-
- $npt["filter_vimeo_360"] = $get["vimeo_360"];
- }
-
- if($get["price"] != "any"){
-
- $npt["filter_price"] = $get["price"];
- }
-
- if($get["collection"] == "staff_pick"){
-
- $npt["filter_staffpicked"] = "true";
- }
-
- if($get["license"] != "any"){
-
- $npt["filter_license"] = $get["license"];
- }
- }
-
- $pagetype = $npt["filter_type"];
-
- try{
-
- $json =
- $this->get(
- $proxy,
- "https://api.vimeo.com/search",
- $npt,
- $jwt
- );
- }catch(Exception $error){
-
- throw new Exception("Failed to fetch JSON");
- }
- }
-
- $json = json_decode($json, true);
-
- if($json === null){
-
- throw new Exception("Failed to parse JSON");
- }
-
- $out = [
- "status" => "ok",
- "npt" => null,
- "video" => [],
- "author" => [],
- "livestream" => [],
- "playlist" => [],
- "reel" => []
- ];
-
- if(isset($json["error"])){
-
- $error = $json["error"];
- if(isset($json["developer_message"])){
-
- $error .= " ({$json["developer_message"]})";
- }
-
- throw new Exception("Vimeo returned an error: " . $error);
- }
-
- if(!isset($json["data"])){
-
- throw new Exception("Vimeo did not return a data object");
- }
-
- switch($pagetype){
-
- case "clip":
- foreach($json["data"] as $video){
-
- $video = $video["clip"];
-
- if(isset($video["user"]["pictures"]["sizes"])){
-
- $avatar = $video["user"]["pictures"]["sizes"][count($video["user"]["pictures"]["sizes"]) - 1]["link"];
- }else{
-
- $avatar = null;
- }
-
- $out["video"][] = [
- "title" => $video["name"],
- "description" =>
- $this->limitstrlen(
- $video["description"]
- ),
- "author" => [
- "name" => $video["user"]["name"],
- "url" => $video["user"]["link"],
- "avatar" => $avatar
- ],
- "date" => strtotime($video["created_time"]),
- "duration" => (int)$video["duration"],
- "views" => (int)$video["stats"]["plays"],
- "thumb" => [
- "ratio" => "16:9",
- "url" => $video["pictures"]["base_link"]
- ],
- "url" => $video["link"]
- ];
- }
- break;
-
- case "ondemand":
- foreach($json["data"] as $video){
-
- $video = $video["ondemand"];
-
- $description = [];
- if(isset($video["metadata"]["interactions"]["rent"]["display_price"])){
-
- $description[] = "Rent for " . $video["metadata"]["interactions"]["rent"]["display_price"];
- }
-
- if(isset($video["metadata"]["interactions"]["buy"]["display_price"])){
-
- $description[] = "Buy for " . $video["metadata"]["interactions"]["buy"]["display_price"];
- }
-
- $description = implode(", ", $description);
-
- $out["video"][] = [
- "title" => $video["name"],
- "description" => $description,
- "author" => [
- "name" => null,
- "url" => null,
- "avatar" => null
- ],
- "date" => null,
- "duration" => null,
- "views" => null,
- "thumb" => [
- "ratio" => "9:16",
- "url" => $video["pictures"]["sizes"][0]["link"]
- ],
- "url" => $video["link"]
- ];
- }
- break;
-
- case "people":
- foreach($json["data"] as $user){
-
- $user = $user["people"];
-
- if(
- isset($user["pictures"]["sizes"]) &&
- count($user["pictures"]["sizes"]) !== 0
- ){
-
- $thumb = [
- "ratio" => "1:1",
- "url" => $user["pictures"]["sizes"][count($user["pictures"]["sizes"]) - 1]["link"]
- ];
- }else{
-
- $thumb = [
- "ratio" => null,
- "url" => null
- ];
- }
-
- $out["author"][] = [
- "title" => $user["name"],
- "followers" => (int)$user["metadata"]["connections"]["followers"]["total"],
- "description" => $user["metadata"]["public_videos"]["total"] . " videos.",
- "thumb" => $thumb,
- "url" => $user["link"]
- ];
- }
- break;
-
- case "channel":
- case "group":
- foreach($json["data"] as $channel){
-
- $channel = $channel[$npt["filter_type"]];
-
- if(
- isset($channel["pictures"]["sizes"]) &&
- count($channel["pictures"]["sizes"]) !== 0
- ){
-
- $thumb = [
- "ratio" => "16:9",
- "url" => $channel["pictures"]["sizes"][count($channel["pictures"]["sizes"]) - 1]["link"]
- ];
- }else{
-
- $thumb = [
- "ratio" => null,
- "url" => null
- ];
- }
-
- $out["author"][] = [
- "title" => $channel["name"],
- "followers" => (int)$channel["metadata"]["connections"]["users"]["total"],
- "description" => $channel["metadata"]["connections"]["videos"]["total"] . " videos.",
- "thumb" => $thumb,
- "url" => $channel["link"]
- ];
- }
- break;
- }
-
- //
- // get next page
- //
- if(
- isset($json["paging"]["next"]) &&
- is_string($json["paging"]["next"])
- ){
-
- $out["npt"] =
- $this->backend
- ->store(
- json_encode([
- "npt" => $json["paging"]["next"],
- "pagetype" => $pagetype
- ]),
- "videos",
- $proxy
- );
- }
-
- return $out;
- }
-
- private function get_jwt(&$proxy){
-
- //
- // get jwt token
- // it's probably safe to cache this across proxies, cause the jwt doesnt contain an userID
- // only an appID, whatever shit that is
- // we can only cache it for 5 minutes though, otherwise vimeo cries about it
- //
- if($proxy === null){
-
- $proxy = $this->backend->get_ip();
- }
-
- $jwt = apcu_fetch("vimeo_jwt");
-
- if($jwt === false){
- /*
- $html =
- $this->get(
- $proxy,
- "https://vimeo.com/search",
- [],
- false
- );
-
- $this->fuckhtml->load($html);
-
- $captcha =
- $this->fuckhtml
- ->getElementsByTagName(
- "title"
- );
-
- if(
- count($captcha) !== 0 &&
- $this->fuckhtml
- ->getTextContent(
- $captcha[0]
- ) == "Vimeo / CAPTCHA Challenge"
- ){
-
- throw new Exception("Vimeo returned a Captcha");
- }
-
- $html =
- explode(
- '<script id="viewer-bootstrap" type="application/json">',
- $html,
- 2
- );
-
- if(count($html) !== 2){
-
- throw new Exception("Failed to find JWT json");
- }
-
- $jwt =
- json_decode(
- $this->fuckhtml
- ->extract_json(
- $html[1]
- ),
- true
- );
-
- if($jwt === null){
-
- throw new Exception("Failed to decode JWT json");
- }
-
- if(!isset($jwt["jwt"])){
-
- throw new Exception("Failed to grep JWT");
- }
-
- $jwt = $jwt["jwt"];
- */
-
- $json =
- $this->get(
- $proxy,
- "https://vimeo.com/_next/jwt",
- [],
- false
- );
-
- $json = json_decode($json, true);
-
- if($json === null){
-
- throw new Exception("The JWT object could not be decoded");
- }
-
- if(!isset($json["token"])){
-
- throw new Exception("Vimeo did not return a JWT");
- }
-
- $jwt = $json["token"];
-
- apcu_store("vimeo_jwt", $jwt, 300);
- }
-
- return $jwt;
- }
-
- private function titledots($title){
-
- $substr = substr($title, -3);
-
- if(
- $substr == "..." ||
- $substr == "…"
- ){
-
- return trim(substr($title, 0, -3), " \n\r\t\v\x00\0\x0B\xc2\xa0");
- }
-
- return trim($title, " \n\r\t\v\x00\0\x0B\xc2\xa0");
- }
-
- private function limitstrlen($text){
-
- return
- explode(
- "\n",
- wordwrap(
- str_replace(
- ["\n\r", "\r\n", "\n", "\r"],
- " ",
- $text
- ),
- 300,
- "\n"
- ),
- 2
- )[0];
- }
- }
|