1<?php
2/**
3 * DokuWiki Plugin html5video (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author lisps
7 * Parts borrowed from the videogg plugin written by Ludovic Kiefer and from the html5video plugin written by
8 * Jason van Gumster (Fweeb) <jason@monsterjavaguns.com> which is based on Christophe Benz' Dailymotion plugin, which, in turn,
9 * is based on Ikuo Obataya's Youtube plugin.
10 *
11 * Currently only supports h264 videos
12 */
13
14class syntax_plugin_html5video_video extends DokuWiki_Syntax_Plugin {
15
16    public function getType() {
17        return 'substition';
18    }
19
20    public function getPType() {
21        return 'normal';
22    }
23
24    public function getSort() {
25        return 159;
26    }
27
28    public function connectTo($mode) {
29		// {file}.mp4?{width}x{height}?{file}|{alternatetext}
30		$this->Lexer->addSpecialPattern('\{\{[^\}]+\.mp4[^\}]*\}\}',$mode,'plugin_html5video_video');
31    }
32
33    /**
34     * mostly copied from handler.php -> Doku_Handler_Parse_Media()
35     */
36    public function handle($match, $state, $pos, Doku_Handler $handler){
37
38
39        // Strip the opening and closing markup
40        $link = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match);
41
42        // Split title from URL
43        $link = explode('|',$link,2);
44
45        // Check alignment
46        $ralign = (bool)preg_match('/^ /',$link[0]);
47        $lalign = (bool)preg_match('/ $/',$link[0]);
48
49        // Logic = what's that ;)...
50        if ( $lalign & $ralign ) {
51            $align = 'center';
52        } else if ( $ralign ) {
53            $align = 'right';
54        } else if ( $lalign ) {
55            $align = 'left';
56        } else {
57            $align = NULL;
58        }
59
60        // The title...
61        if ( !isset($link[1]) ) {
62            $link[1] = NULL;
63        }
64
65        //remove aligning spaces
66        $link[0] = trim($link[0]);
67
68        //split into src and parameters (using the very last questionmark)
69        $pos = strrpos($link[0], '?');
70        if($pos !== false){
71            $src   = substr($link[0],0,$pos);
72            $param = substr($link[0],$pos+1);
73        }else{
74            $src   = $link[0];
75            $param = '';
76        }
77
78        //parse width and height
79        if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){
80            ($size[1]) ? $w = $size[1] : $w = NULL;
81            ($size[3]) ? $h = $size[3] : $h = NULL;
82        } else {
83            $w = 640;
84            $h = 360;
85        }
86
87        if(preg_match('/linkonly/i',$param)){
88            $linking = 'linkonly';
89        } else {
90            $linking = '';
91        }
92
93        $params = explode('&',$param);
94        $poster = $this->getConf('GlobalVideoPreviewPicture');
95        foreach($params as $p){
96            if ($this->media_exists($p))
97                $poster = cleanID($p);
98        }
99
100        /*
101        dbg(array(
102            'link'=>$link,
103            'src'=>$src,
104            'param'=>$param,
105            'size'=>$size,
106            'w'=>$w,
107            'h'=>$h,
108            'linking'=>$linking,
109            'align'=>$align,
110            'poster'=>$poster,
111        ));
112        */
113
114        if ( preg_match('#^(https?|ftp)#i',$src) ) {
115            $type = 'externalmedia';
116        } else {
117            $type = 'internalmedia';
118        }
119        return array(
120            $src,
121            $align,
122            $w,
123            $h,
124            $linking,
125            $poster,
126            $type,
127            $link[1]
128
129        );
130    }
131
132    protected function media_exists($id) {
133        return @file_exists(mediaFN($id));
134    }
135
136    public function render($mode, Doku_Renderer $renderer, $data) {
137	    global $ID;
138        // initalisize video class id
139        static $counter = 1;
140
141        if($mode != 'xhtml') {
142			return false;
143		}
144
145        list($src,
146            $align,
147            $w,
148            $h,
149            $linking,
150            $poster,
151            $type,
152            $alt) = $data;
153
154        $exists = false;
155		resolve_mediaid(getNS($ID), $src, $exists);
156
157		if($type == 'internalmedia' && !$exists) {
158            $renderer->internalmedia($src,$alt,$align,$w,$h);
159            return true;
160        }
161
162        if($linking == 'linkonly') {
163            //$alt = $alt?$alt:hsc($src);
164            // Check whether this is a local or remote image
165            if ( $type == 'externalmedia' ) {
166                $renderer->externalmedia($src,$alt,$align,$w,$h,NULL,$linking);
167            } else {
168                $renderer->internalmedia($src,$alt,$align,$w,$h,NULL,$linking);
169            }
170            return true;
171        }
172
173
174
175		// preprocess content to display on screen
176		$obj = '<video id="'.hsc($this->getConf('videoPlayerIDText')).'' . $counter . '" class="video-js vjs-default-skin media'.$align.'" '.
177            ($w?('width="' .$w.'" '):'').
178            ($h?('height="'.$h.'" '):'').
179            ' controls preload="'.hsc($this->getConf('VideoPreload')).
180            '" '.($poster? 'poster="'.hsc(''.ml($poster)).'" ':'').
181            ' data-setup=\'{"techOrder": ["'.hsc($this->getConf('preferedVideoTechnologie')).'", "'.hsc($this->getConf('fallBackVideoTechnologie')).
182            '"]}\'>';
183
184        $obj .= '<source src="' . ml($src) . '" type="'.hsc($this->getConf('html5VideoType')).'" /></video>';
185
186		// preprocess content to print
187		if($this->getConf('showThumbOnPrint') && $poster != "") {
188			// Print Picture if specified
189			$obj .= '<div class="vjs-alternatetext"><img src="' . ml($poster) . '" alt="' . hsc($alt) . '"  '.
190                $w?('width="' .$w.'px" '):''.
191                $h?('height="'.$h.'px" '):''.
192                '></div>';
193		} else if($alt != "") {
194			// Print alternate text if specified
195			$obj .= '<div class="vjs-alternatetext">' . hsc($alt) . '</div>';
196		} else  if($this->getConf('showStandardTextOnPrint')) {
197			// Print standard alternate text
198			$obj .= '<div class="vjs-alternatetext">' . hsc($this->getConf('standardAlternateTextPrint')) . '</div>';
199		}
200
201		// increment video class id on current page
202		$counter++;
203
204		// set render output
205        $renderer->doc .= $obj;
206        return true;
207    }
208    private function _getAlts($filename) {
209        return false;
210    }
211}
212