Skip to content
Snippets Groups Projects
Commit 8f8f057a authored by Anika Henke's avatar Anika Henke
Browse files

Merge pull request #265 from splitbrain/video-audio

Added video and audio support
parents e9776410 a051c274
No related branches found
No related tags found
No related merge requests found
...@@ -13,6 +13,9 @@ swf application/x-shockwave-flash ...@@ -13,6 +13,9 @@ swf application/x-shockwave-flash
mp3 audio/mpeg mp3 audio/mpeg
ogg audio/ogg ogg audio/ogg
wav audio/wav wav audio/wav
webm video/webm
ogv video/ogg
mp4 video/mp4
tgz !application/octet-stream tgz !application/octet-stream
tar !application/x-gtar tar !application/x-gtar
......
...@@ -2134,4 +2134,61 @@ function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x= ...@@ -2134,4 +2134,61 @@ function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=
return $okay; 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: */ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
...@@ -781,7 +781,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -781,7 +781,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
} }
function internalmedia ($src, $title=null, $align=null, $width=null, 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; global $ID;
list($src,$hash) = explode('#',$src,2); list($src,$hash) = explode('#',$src,2);
resolve_mediaid(getNS($ID),$src, $exists); resolve_mediaid(getNS($ID),$src, $exists);
...@@ -793,8 +793,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -793,8 +793,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
list($ext,$mime,$dl) = mimetype($src,false); list($ext,$mime,$dl) = mimetype($src,false);
if(substr($mime,0,5) == 'image' && $render){ if(substr($mime,0,5) == 'image' && $render){
$link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),($linking=='direct')); $link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),($linking=='direct'));
}elseif($mime == 'application/x-shockwave-flash' && $render){ }elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render){
// don't link flash movies // don't link movies
$noLink = true; $noLink = true;
}else{ }else{
// add file icons // add file icons
...@@ -812,8 +812,13 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -812,8 +812,13 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
} }
//output formatted //output formatted
if ($linking == 'nolink' || $noLink) $this->doc .= $link['name']; if ($return) {
else $this->doc .= $this->_formatLink($link); 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, function externalmedia ($src, $title=null, $align=null, $width=null,
...@@ -829,8 +834,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -829,8 +834,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
if(substr($mime,0,5) == 'image' && $render){ if(substr($mime,0,5) == 'image' && $render){
// link only jpeg images // link only jpeg images
// if ($ext != 'jpg' && $ext != 'jpeg') $noLink = true; // if ($ext != 'jpg' && $ext != 'jpeg') $noLink = true;
}elseif($mime == 'application/x-shockwave-flash' && $render){ }elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render){
// don't link flash movies // don't link movies
$noLink = true; $noLink = true;
}else{ }else{
// add file icons // add file icons
...@@ -1091,6 +1096,48 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -1091,6 +1096,48 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$ret .= ' />'; $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'){ }elseif($mime == 'application/x-shockwave-flash'){
if (!$render) { if (!$render) {
// if the flash is not supposed to be rendered // if the flash is not supposed to be rendered
...@@ -1223,6 +1270,94 @@ class Doku_Renderer_xhtml extends Doku_Renderer { ...@@ -1223,6 +1270,94 @@ 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="'.hsc($posterUrl).'"';
$out .= '>'.NL;
$fallback = '';
// 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)
$fallback .= $this->internalmedia($file, $title, NULL, NULL, NULL, $cache=NULL, $linking='linkonly', $return=true);
}
// finish
$out .= $fallback;
$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;
$fallback = '';
// 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)
$fallback .= $this->internalmedia($file, $title, NULL, NULL, NULL, $cache=NULL, $linking='linkonly', $return=true);
}
// finish
$out .= $fallback;
$out .= '</audio>'.NL;
return $out;
}
} }
//Setup VIM: ex: et ts=4 : //Setup VIM: ex: et ts=4 :
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
...@@ -101,7 +101,9 @@ address { ...@@ -101,7 +101,9 @@ address {
padding: 0; padding: 0;
} }
div { div,
video,
audio {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment