IET-OU/open-media-player

View on GitHub
application/controllers/timedtext.php

Summary

Maintainability
C
7 hrs
Test Coverage
<?php defined('BASEPATH') or exit('No direct script access allowed');
/**
 * Captions/timed-text controller.
 *
 * Very important - Flowplayer only accepts,
 *   xmlns="http://www.w3.org/2006/10/ttaf1"
 * NOT
 *   xmlns="http://www.w3.org/2006/04/ttaf1"
 *
 * @author N.D.Freear, 27 April 2011/6 February 2012.
 * @copyright Copyright 2012 The Open University.
 */

define('TTML_NS', 'http://www.w3.org/2006/10/ttaf1');


class Timedtext extends \IET_OU\Open_Media_Player\MY_Controller
{

  // Captions for Mediaelement-based players.

    /**
   * TTML+XML to WebVTT (Web Video Text Tracks) parser.
   * Copyright 2012-02-06 N.D.Freear/ The Open University.
   *
   * See, http://dev.w3.org/html5/webvtt/#the-webvtt-file-format
   * See, http://www.delphiki.com/webvtt/
   *
   * FROM: oup-mep/webvtt.php
   */
    public function webvtt()
    {

        $ttml_url = $this->input->get('url');
        #'http://podcast.open.ac.uk/feeds/student-experiences/closed-captions/openings-being-an-ou-student.xml';
        $debug = $this->input->get('debug');

        if (! $ttml_url) {
            $this->_error("Error, 'url' is a required parameter.", 400);
        }

        // Security.
        if (! preg_match('@^https?:\/\/podcast.open.ac.uk\/@', $ttml_url)) {
            $this->_error("Error, bad 'url' parameter.", 400);
            return;
        }

        $p = parse_url($ttml_url);


        // A naive check for SRT captions, from VLE etc.
        $is_srt = 'srt' == pathinfo($p['path'], PATHINFO_EXTENSION);


   // Bug #1334, Proxy mode to fix VLE caption redirects.
   // Example https://learn2acct.open.ac.uk/pluginfile.php/985394/mod_oucontent/oucontent/155114/k315-0-video1.srt
        $options = array();
        if ($is_srt && preg_match('/^(learn|[\w\.]*vledev)\w*.open.ac.uk\/(moodle\w*\/)?pluginfile/', $p['host'].$p['path'], $matches)) {
            $options['proxy_cookies'] = true;
            $options['max_redirects'] = 0;
            $options['ua'] = $this->agent->agent_string();
            $options['ssl_verify'] = false;
            $options['debug'] = true;
        }

        $http = new \IET_OU\Open_Media_Player\Http();

        $result = $http->request($ttml_url, $spoof = false, $options);

        if (! $result->success) {
            if (404 == $result->info['http_code']) {
                $this->_error('Caption file not found.', 404);
            }
          #var_dump($result->info);
            $this->_error('Caption request problem.', $result->http_code);
        }


        if (! $is_srt) {
            $xmlo = @simplexml_load_string($result->data);
          #$xmlo = new SimpleXMLElement($result->data);
            if (! $xmlo) {
                $this->_error('XML caption parsing problem.', 503);
            }
        }

        if ($debug) {
            header('Content-Type: text/plain; charset=UTF-8');
        } else {
            header('Content-Type: text/vtt; charset=UTF-8');
        }
        @header('X-Input-Text-Track: '.$ttml_url); #Was: X-Input-TTML
        @header('Content-Disposition: inline; filename='.basename($ttml_url).'.vtt');
        echo 'WEBVTT'.PHP_EOL.PHP_EOL;


      // Assume the SRT captions are well formed.
        if ($is_srt) {
            echo $result->data;
            exit;
        }


      // Get declared namespaces.
        $ns = $xmlo->getDocNamespaces();

        $ns_string = '';
        foreach ($ns as $pre => $url) {
            $fix = ''==$pre ? 'xmlns' : 'xmlns:'.$pre;
            $ns_string .= " $fix='$url'";
        }

        $count=0;
        foreach ($xmlo->body->div->p as $el => $para) {
            $count++;

            $text ='';
            $line = $para;
          /*if (isset($para->span)) {
            $line = $para->span;
          }*/

            if ($line->br) {
                $para_n = str_replace('<br/>', ' ', $line->asXML());
                $xml_n = "<x $ns_string>$para_n</x>";
                $xmlo_n = new SimpleXMLElement($xml_n);
                if (isset($xmlo_n->p->span)) {
                    foreach ($xmlo_n->p->children() as $span) {
                        $text .= (string) $span.' ';
                    }
                } else {
                    $text = (string) $xmlo_n->p;
                }
            } elseif (isset($para->span)) {
                $text = (string) $para->span;
            } else {
                $text = (string) $line;
            }
            echo
            $count.PHP_EOL
            .$para['begin'].' --> '.$para['end'].PHP_EOL
            .$text .PHP_EOL.PHP_EOL;
        }
    }



    // Captions for Flowplayer-based players.

    /**
    *  OU-podcast player captions - TTML format.
    */
    public function pod_captions($custom_id, $shortcode, $captions_file = null)
    {

        $captions = config_item('captions'); #$this->CI->config->item
        if (isset($captions[$custom_id][$shortcode])) {
            $cc_file = $captions[$custom_id][$shortcode];

            $cc_path = config_item('data_dir')."oupodcast/captions/$cc_file";

            if (file_exists($cc_path)) {
                header('Content-Type: application/xml; charset=utf-8');
                header("Content-Disposition: inline; filename=$cc_file");
             #header('Content-Type: text/xml');
             #header('Accept-Ranges: bytes');
                echo file_get_contents($cc_path);
            } else {
                //Error 404.
                die('404.1');
            }
        } else {
            //Error 404.
            die('404.2');
        }
    }
}