diff options
-rw-r--r-- | conf/mime.conf | 3 | ||||
-rw-r--r-- | inc/media.php | 57 | ||||
-rw-r--r-- | inc/parser/xhtml.php | 145 | ||||
-rw-r--r-- | lib/images/fileicons/mp4.png | bin | 0 -> 740 bytes | |||
-rw-r--r-- | lib/images/fileicons/ogv.png | bin | 0 -> 740 bytes | |||
-rw-r--r-- | lib/images/fileicons/webm.png | bin | 0 -> 740 bytes | |||
-rw-r--r-- | lib/tpl/dokuwiki/css/basic.less | 2 |
7 files changed, 200 insertions, 7 deletions
diff --git a/conf/mime.conf b/conf/mime.conf index 381b93f86..2a50fab10 100644 --- a/conf/mime.conf +++ b/conf/mime.conf @@ -13,6 +13,9 @@ swf application/x-shockwave-flash mp3 audio/mpeg ogg audio/ogg wav audio/wav +webm video/webm +ogv video/ogg +mp4 video/mp4 tgz !application/octet-stream tar !application/x-gtar diff --git a/inc/media.php b/inc/media.php index a9f6be771..d45b2a91d 100644 --- a/inc/media.php +++ b/inc/media.php @@ -2129,4 +2129,61 @@ function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x= return $okay; } +/** + * Return other media files with the same base name + * but different extensions. + * + * @param string $src - ID of media file + * @param array $exts - alternative extensions to find other files for + * @return array - mime type => file ID + * + * @author Anika Henke <anika@selfthinker.org> + */ +function media_alternativefiles($src, $exts){ + + $files = array(); + list($srcExt, $srcMime) = mimetype($src); + $filebase = substr($src, 0, -1 * (strlen($srcExt)+1)); + + foreach($exts as $ext) { + $fileid = $filebase.'.'.$ext; + $file = mediaFN($fileid); + if(file_exists($file)) { + list($fileExt, $fileMime) = mimetype($file); + $files[$fileMime] = $fileid; + } + } + return $files; +} + +/** + * Check if video/audio is supported to be embedded. + * + * @param string $src - mimetype of media file + * @param string $type - type of media files to check ('video', 'audio', or none) + * @return boolean + * + * @author Anika Henke <anika@selfthinker.org> + */ +function media_supportedav($mime, $type=NULL){ + $supportedAudio = array( + 'ogg' => 'audio/ogg', + 'mp3' => 'audio/mpeg', + 'wav' => 'audio/wav', + ); + $supportedVideo = array( + 'webm' => 'video/webm', + 'ogv' => 'video/ogg', + 'mp4' => 'video/mp4', + ); + if ($type == 'audio') { + $supportedAv = $supportedAudio; + } elseif ($type == 'video') { + $supportedAv = $supportedVideo; + } else { + $supportedAv = array_merge($supportedAudio, $supportedVideo); + } + return in_array($mime, $supportedAv); +} + /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index fd02c0ce0..5fca1bf45 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -781,7 +781,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } function internalmedia ($src, $title=null, $align=null, $width=null, - $height=null, $cache=null, $linking=null) { + $height=null, $cache=null, $linking=null, $return=NULL) { global $ID; list($src,$hash) = explode('#',$src,2); resolve_mediaid(getNS($ID),$src, $exists); @@ -793,8 +793,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { list($ext,$mime,$dl) = mimetype($src,false); if(substr($mime,0,5) == 'image' && $render){ $link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),($linking=='direct')); - }elseif($mime == 'application/x-shockwave-flash' && $render){ - // don't link flash movies + }elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render){ + // don't link movies $noLink = true; }else{ // add file icons @@ -812,8 +812,13 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } //output formatted - if ($linking == 'nolink' || $noLink) $this->doc .= $link['name']; - else $this->doc .= $this->_formatLink($link); + if ($return) { + if ($linking == 'nolink' || $noLink) return $link['name']; + else return $this->_formatLink($link); + } else { + if ($linking == 'nolink' || $noLink) $this->doc .= $link['name']; + else $this->doc .= $this->_formatLink($link); + } } function externalmedia ($src, $title=null, $align=null, $width=null, @@ -829,8 +834,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if(substr($mime,0,5) == 'image' && $render){ // link only jpeg images // if ($ext != 'jpg' && $ext != 'jpeg') $noLink = true; - }elseif($mime == 'application/x-shockwave-flash' && $render){ - // don't link flash movies + }elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render){ + // don't link movies $noLink = true; }else{ // add file icons @@ -1091,6 +1096,48 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $ret .= ' />'; + }elseif(media_supportedav($mime, 'video')){ + // first get the $title + if (!is_null($title)) { + $title = $this->_xmlEntities($title); + } + if (!$title) { + // just show the sourcename + $title = $this->_xmlEntities(utf8_basename(noNS($src))); + } + if (!$render) { + // if the video is not supposed to be rendered + // return the title of the video + return $title; + } + + $att = array(); + $att['class'] = "media$align"; + + //add video(s) + $ret .= $this->_video($src, $width, $height, $att); + + }elseif(media_supportedav($mime, 'audio')){ + // first get the $title + if (!is_null($title)) { + $title = $this->_xmlEntities($title); + } + if (!$title) { + // just show the sourcename + $title = $this->_xmlEntities(utf8_basename(noNS($src))); + } + if (!$render) { + // if the video is not supposed to be rendered + // return the title of the video + return $title; + } + + $att = array(); + $att['class'] = "media$align"; + + //add audio + $ret .= $this->_audio($src, $att); + }elseif($mime == 'application/x-shockwave-flash'){ if (!$render) { // if the flash is not supposed to be rendered @@ -1223,6 +1270,90 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } + /** + * Embed video(s) in HTML + * + * @author Anika Henke <anika@selfthinker.org> + * + * @param string $src - ID of video to embed + * @param int $width - width of the video in pixels + * @param int $height - height of the video in pixels + * @param array $atts - additional attributes for the <video> tag + * @return string + */ + function _video($src,$width,$height,$atts=null){ + + // prepare width and height + if(is_null($atts)) $atts = array(); + $atts['width'] = (int) $width; + $atts['height'] = (int) $height; + if(!$atts['width']) $atts['width'] = 320; + if(!$atts['height']) $atts['height'] = 240; + + // prepare alternative formats + $extensions = array('webm', 'ogv', 'mp4'); + $alternatives = media_alternativefiles($src, $extensions); + $poster = media_alternativefiles($src, array('jpg', 'png'), true); + $posterUrl = ''; + if (!empty($poster)) { + $posterUrl = ml(reset($poster),array('cache'=>$cache),true,'&'); + } + + $out = ''; + // open video tag + $out .= '<video '.buildAttributes($atts).' controls="controls"'; + if ($posterUrl) $out .= ' poster="'.$posterUrl.'"'; + $out .= '>'.NL; + + // output source for each alternative video format + foreach($alternatives as $mime => $file) { + $url = ml($file,array('cache'=>$cache),true,'&'); + $title = $this->_xmlEntities(utf8_basename(noNS($file))); + + $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL; + // alternative content (just a link to the file) + $out .= $this->internalmedia($file, $title, NULL, NULL, NULL, $cache=NULL, $linking='linkonly', $return=true); + } + + // finish + $out .= '</video>'.NL; + return $out; + } + + /** + * Embed audio in HTML + * + * @author Anika Henke <anika@selfthinker.org> + * + * @param string $src - ID of audio to embed + * @param array $atts - additional attributes for the <audio> tag + * @return string + */ + function _audio($src,$atts=null){ + + // prepare alternative formats + $extensions = array('ogg', 'mp3', 'wav'); + $alternatives = media_alternativefiles($src, $extensions); + + $out = ''; + // open audio tag + $out .= '<audio '.buildAttributes($atts).' controls="controls">'.NL; + + // output source for each alternative audio format + foreach($alternatives as $mime => $file) { + $url = ml($file,array('cache'=>$cache),true,'&'); + $title = $this->_xmlEntities(utf8_basename(noNS($file))); + + $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL; + // alternative content (just a link to the file) + $out .= $this->internalmedia($file, $title, NULL, NULL, NULL, $cache=NULL, $linking='linkonly', $return=true); + } + + // finish + $out .= '</audio>'.NL; + return $out; + } + } //Setup VIM: ex: et ts=4 : diff --git a/lib/images/fileicons/mp4.png b/lib/images/fileicons/mp4.png Binary files differnew file mode 100644 index 000000000..b89fc5299 --- /dev/null +++ b/lib/images/fileicons/mp4.png diff --git a/lib/images/fileicons/ogv.png b/lib/images/fileicons/ogv.png Binary files differnew file mode 100644 index 000000000..b89fc5299 --- /dev/null +++ b/lib/images/fileicons/ogv.png diff --git a/lib/images/fileicons/webm.png b/lib/images/fileicons/webm.png Binary files differnew file mode 100644 index 000000000..b89fc5299 --- /dev/null +++ b/lib/images/fileicons/webm.png diff --git a/lib/tpl/dokuwiki/css/basic.less b/lib/tpl/dokuwiki/css/basic.less index 5886889fd..636923192 100644 --- a/lib/tpl/dokuwiki/css/basic.less +++ b/lib/tpl/dokuwiki/css/basic.less @@ -93,6 +93,8 @@ pre, table, hr, blockquote, +video, +audio, figure, details, fieldset, |