GET_subtitles_v1( $path, $return_raw ); } else { return $this->GET_subtitles_v2( $path, $return_raw ); } } function GET_subtitles_v1( $path, $return_raw = FALSE ) { // GET /wistiamara/subtitles/ $url = isset( $_GET['url'] ) ? $_GET['url'] : 'http://' . implode( '/', $path ); $c = curl_init(self::AMARA_API_V1_URL . 'show_widget'); $p = 'video_url=' . urlencode($url) . '&is_remote=true&base_state=%7B%7D'; curl_setopt($c, CURLOPT_POST, 2); curl_setopt($c, CURLOPT_POSTFIELDS, $p); curl_setopt($c, CURLOPT_HTTPHEADER, array( 'X-api-username: ' . AmaraLink::USERNAME, 'X-apikey: ' . AmaraLink::KEY ) ); curl_setopt($c, CURLOPT_RETURNTRANSFER, true ); $text = curl_exec ( $c ); if (! $text) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Could not retrieve subtitle data from Amara.' ) ); } return "V1 LISTING FOR " . $url . "\n\n\n" . $text; $srcdata = json_decode($text, true); if ( !$srcdata ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Malformed subtitle data returned from Amara.' ) ); }; if ( array_key_exists('error_msg', $srcdata) ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>$srcdata['error_msg'] ) ); }; if ( array_key_exists('error', $srcdata) ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Amara error: ' . $srcdata['error'] ) ); }; $languages = array(); foreach( $srcdata['languages'] as $lang ) { $languages[ $lang[0] ] = $lang[1]; } $subtitles = array(); $available_languages = array(); $urlvid = urlencode($srcdata['video_id']); $alltext = "\{ 'mode': 'raw'\n"; $calls = ''; foreach( $srcdata['drop_down_contents'] as $lang ) { $c = curl_init(self::AMARA_API_V1_URL . 'fetch_subtitles'); $p = 'language_pk=' . urlencode($lang['pk']) . '&video_id=%22' . $urlvid . '%22'; $calls .= self::AMARA_API_V1_URL . 'fetch_subtitles' . "\n\t" . $p . "\n\n"; //language_pk -> The pk for the langauage you want to show, as taken from the first request //video_id -> the video this subtitle set belongs to, as taken from the first request curl_setopt($c, CURLOPT_POST, 2); curl_setopt($c, CURLOPT_POSTFIELDS, $p); //curl_setopt($c, CURLOPT_HTTPHEADER, array( 'X-api-username: ' . AmaraLink::USERNAME, 'X-apikey: ' . AmaraLink::KEY ) ); curl_setopt($c, CURLOPT_RETURNTRANSFER, true ); $text = curl_exec ( $c ); $alltext .= ", \n'" . $lang['language'] . "': " . $text . "\n"; $obj = json_decode($text, true); $subtitles[ $lang['language'] ] = $this->extract_subtitles( $obj['subtitles'] ); $available_languages[ $lang['language'] ] = $languages[ $lang['language'] ]; } if ($return_raw) { $alltext .= "'_calls': \"" . $calls . "\"\n\n"; return $alltext; } return json_encode( array('languages'=>(object)$available_languages, 'subtitles'=>(object)$subtitles, 'language_count'=>count($available_languages), 'ok'=>TRUE ) ); } function GET_subtitles_v2( $path, $return_raw = FALSE ) { $url = isset( $_GET['url'] ) ? $_GET['url'] : 'http://' . implode( '/', $path ); $p = '?video_url=' . urlencode($url); $c = curl_init( self::AMARA_API_V2_URL . 'videos/' . $p ); curl_setopt($c, CURLOPT_HTTPHEADER, array( 'X-api-username: ' . AmaraLink::USERNAME, 'X-apikey: ' . AmaraLink::KEY ) ); curl_setopt($c, CURLOPT_RETURNTRANSFER, true ); $text = curl_exec ( $c ); if (! $text) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Could not retrieve subtitle data from Amara.' ) ); } $srcdata = json_decode($text, true); if ( !$srcdata ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Malformed subtitle data returned from Amara.' ) ); }; if ( array_key_exists('error_msg', $srcdata) ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>$srcdata['error_msg'] ) ); }; if ( array_key_exists('error', $srcdata) ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>$srcdata['error'] ) ); }; if ( ! is_array($srcdata['meta']) ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>FALSE, 'error_msg'=>'Malformed result from Amara' ) ); }; if ( $srcdata['meta']['total_count'] < 1 ) { return json_encode( array('languages'=>(object)array(), 'subtitles'=>(object)array(), 'language_count'=>0, 'ok'=>TRUE ) ); }; $languages =& $srcdata['objects'][0]['languages']; $subtitles = array(); $available_languages = array(); $alltext = "\{ 'mode': 'raw'\n"; $calls = ''; foreach( $languages as $lang ) { $c = curl_init(self::AMARA_API_V2_URLPREFIX . $lang['subtitles_uri'] . '?format=json'); $calls .= self::AMARA_API_V2_URLPREFIX . $lang['subtitles_uri'] . "\n\n"; curl_setopt($c, CURLOPT_HTTPHEADER, array( 'X-api-username: ' . AmaraLink::USERNAME, 'X-apikey: ' . AmaraLink::KEY ) ); curl_setopt($c, CURLOPT_RETURNTRANSFER, true ); $text = curl_exec ( $c ); $alltext .= ", \n'" . $lang['code'] . "': " . $text . "\n"; $obj = json_decode($text, true); $subtitles[ $lang['code'] ] = $this->extract_subtitles( $obj['subtitles'] ); $available_languages[ $lang['code'] ] = $lang['name']; } if ($return_raw) { $alltext .= "'_calls': \"" . $calls . "\"\n\n"; return $alltext; } // return "V2 LISTING FOR " . $url . "\n\n\n" . json_encode($alltext) . "\n\n\n'_calls': \"" . $calls . "\"\n\n"; return json_encode( array('languages'=>(object)$available_languages, 'subtitles'=>(object)$subtitles, 'language_count'=>count($available_languages), 'ok'=>TRUE ) ); } function extract_subtitles( $src ) { if ( is_array($src) ) { return $this->extract_subtitles_json($src); }; // If they were JSON, then they were already object-converted // Otherwise, try to figure out what format the subs are in. if ( strpos( substr($src, 0, 100),'xmlns="http://www.w3.org/ns/ttml"') !== FALSE ) { // TTML identified. return $this->extract_subtitles_ttml($src); } return null; // Can't solve. } function extract_subtitles_json( $src ) { $subs = array(); foreach ($src as $s) { $subs[] = array( 'html'=>str_replace("\n", "
\n", $s['text']), 'begin'=>isset($s['start_time']) ? $s['start_time'] : $s['start'], 'end'=>isset($s['end_time']) ? $s['end_time'] : $s['end'], ); } return $subs; } function extract_subtitles_ttml( $src ) { $ttml = new \SimpleXMLElement($src); $subs = array(); foreach( $ttml->body->div->p as $p ) { $subs[] = array( 'html'=>$this->strip_outermost_xml_tag($p->asXML()), //'hmsbegin'=>'' . $p['begin'], //'hmsend'=>'' . $p['end'], 'begin'=>$this->ttml_time_to_ms($p['begin']), 'end'=>$this->ttml_time_to_ms($p['end']), ); } return $subs; // Stub } function strip_outermost_xml_tag( $src ) { $i = strpos($src, '>'); if ($i !== FALSE) { $src = substr($src, $i+1); } $i = strrpos($src, '<'); if ($i !== FALSE) { $src = substr($src, 0, $i); } return $src; } function ttml_time_to_ms( $time ) { sscanf($time, "%d:%d:%d.%d", $hours, $minutes, $seconds, $millis); return ($hours * 3600000) + ($minutes * 60000) + ($seconds * 1000) + $millis; } } /****************************************************************************************\ RESTful routing \****************************************************************************************/ $routes = array ( 'GET' => array( 'subtitles' => function ( $path ) { if (isset( $_GET['api_version'] )) { $api_version = 0 + $_GET['api_version']; } else { $api_version = FALSE; } $link = new AmaraLink(); return $link->GET_subtitles( $path, FALSE, $api_version ); }, 'raw' => function ( $path ) { if (isset( $_GET['api_version'] )) { $api_version = 0 + $_GET['api_version']; } else { $api_version = FALSE; } $link = new AmaraLink(); return $link->GET_subtitles( $path, TRUE, $api_version ); } ) ); function routeREST() { global $routes; $method = $_SERVER['REQUEST_METHOD']; if (isset( $_REQUEST['PATH_INFO'] )) { $pathsrc = $_REQUEST['PATH_INFO']; } else { $pathsrc = $_SERVER['PATH_INFO']; } $path = explode('/', trim( $pathsrc, '/' )); $root = array_shift( $path ); if (array_key_exists($method, $routes)) { if (array_key_exists($root, $routes[$method])) { try { $out = $routes[$method][$root]( $path ); header('Content-type: application/json'); echo $out; return; } catch (\Exception $e) { header('HTTP/1.0 500 Server Error', true, 500); echo "Uncaught exception:\n{$e->getMessage()}"; return; } } else { header('HTTP/1.0 501 Not Implemented', true, 501); echo "Unkown root resource '$root' in " . $pathsrc; return; } } else { header('HTTP/1.0 501 Not Implemented', true, 501); echo "Method '$method' not supported for resource " . $pathsrc; return; } } routeREST();