28 'audio' =>
'audio/aiff' 31 'audio' =>
'audio/x-au' 34 'audio' =>
'video/x-msvideo' 37 'video' =>
'video/x-ms-asf' 40 'audio' =>
'application/java',
41 'video' =>
'application/java' 44 'video' =>
'application/x-director' 47 'audio' =>
'audio/flac' 50 'video' =>
'video/x-flv' 53 'audio' =>
'audio/mpeg' 56 'video' =>
'video/mp4' 59 'audio' =>
'audio/ogg' 62 'audio' =>
'audio/ogg',
63 'video' =>
'video/ogg' 66 'video' =>
'video/ogg' 69 'audio' =>
'audio/x-m4a' 72 'video' =>
'video/quicktime' 75 'audio' =>
'audio/mp4a-latm' 78 'video' =>
'video/x-m4v' 81 'video' =>
'video/quicktime' 84 'audio' =>
'application/x-director' 87 'audio' =>
'application/x-shockwave-flash',
88 'video' =>
'application/x-shockwave-flash' 91 'audio' =>
'audio/wave' 94 'audio' =>
'audio/webm',
95 'video' =>
'video/webm' 98 'audio' =>
'audio/x-ms-wmv' 107 'useBuiltInControls',
117 'playerFallbackOrder' 137 'url' =>
'plugins/flowplayer.captions-3.2.10.swf',
139 'captionTarget' =>
'content' 143 'url' =>
'plugins/flowplayer.content-3.2.9.swf',
146 'backgroundColor' =>
'transparent',
147 'backgroundGradient' =>
'none',
149 'textDecoration' =>
'outline',
153 'fontFamily' =>
'Arial',
154 'textAlign' =>
'center',
166 'provider' =>
'audio',
169 'url' =>
'plugins/flowplayer.audio-3.2.11.swf' 173 'fullscreen' => FALSE
194 public function render($conf = array()) {
196 $pageRenderer =
$GLOBALS[
'TSFE']->getPageRenderer();
199 $prefix =
$GLOBALS[
'TSFE']->baseUrl;
201 if (
$GLOBALS[
'TSFE']->absRefPrefix) {
202 $prefix =
$GLOBALS[
'TSFE']->absRefPrefix;
205 $replaceElementIdString = str_replace(
'.',
'', uniqid(
'mmswf', TRUE));
206 $GLOBALS[
'TSFE']->register[
'MMSWFID'] = $replaceElementIdString;
207 $layout = isset($conf[
'layout.']) ? $this->cObj->stdWrap($conf[
'layout'], $conf[
'layout.']) : $conf[
'layout'];
208 $content = str_replace(
'###ID###', $replaceElementIdString, $layout);
209 $type = isset($conf[
'type.']) ? $this->cObj->stdWrap($conf[
'type'], $conf[
'type.']) : $conf[
'type'];
210 $typeConf = $conf[$type .
'.'];
212 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/flowplayer/flowplayer-3.2.13.min.js');
214 $pageRenderer->addCssFile(TYPO3_mainDir .
'contrib/flowplayer/express-install/express-install.css');
216 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/videojs/video-js/video.js');
218 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/videojs/video-js/video.js');
220 $pageRenderer->addCssFile(TYPO3_mainDir .
'contrib/videojs/video-js/video-js.css');
222 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/videojs/video-js/controls/control-bar.js');
223 $pageRenderer->addCssFile(TYPO3_mainDir .
'contrib/videojs/video-js/controls/control-bar.css');
225 $player = isset($typeConf[
'player.']) ? $this->cObj->stdWrap($typeConf[
'player'], $typeConf[
'player.']) : $typeConf[
'player'];
227 $player = $prefix . TYPO3_mainDir .
'contrib/flowplayer/flowplayer-3.2.18.swf';
229 $installUrl = isset($conf[
'installUrl.']) ? $this->cObj->stdWrap($conf[
'installUrl'], $conf[
'installUrl.']) : $conf[
'installUrl'];
231 $installUrl = $prefix . TYPO3_mainDir .
'contrib/flowplayer/expressinstall.swf';
233 $flashVersion = isset($conf[
'flashVersion.']) ? $this->cObj->stdWrap($conf[
'flashVersion'], $conf[
'flashVersion.']) : $conf[
'flashVersion'];
234 if (!$flashVersion) {
235 $flashVersion = array(9, 115);
237 $flashConfiguration = array(
241 'expressInstall' => $installUrl,
243 'version' => $flashVersion,
245 'onFail' =>
'###ONFAIL###' 247 $flashDownloadUrl =
'http://www.adobe.com/go/getflashplayer';
248 $onFail =
'function() { 249 if (!(flashembed.getVersion()[0] > 0)) { 250 var message = "<p>" + "' .
$GLOBALS[
'TSFE']->sL(
'LLL:EXT:cms/locallang_ttc.xlf:media.needFlashPlugin') .
'" + "</p>" + "<p>" + "<a href=\\"' . $flashDownloadUrl .
'\\">' .
$GLOBALS[
'TSFE']->sL(
'LLL:EXT:cms/locallang_ttc.xlf:media.downloadFlash') .
'</a>" + "</p>"; 251 document.getElementById("' . $replaceElementIdString .
'_flash_install_info").innerHTML = "<div class=\\"message\\">" + message + "</div>"; 254 $flashConfiguration = json_encode($flashConfiguration);
255 $flashConfiguration = str_replace(
'"###ONFAIL###"', $onFail, $flashConfiguration);
256 $filename = isset($conf[
'file.']) ? $this->cObj->stdWrap($conf[
'file'], $conf[
'file.']) : $conf[
'file'];
258 if (strpos($filename,
'://') !== FALSE) {
259 $conf[
'flashvars.'][
'url'] = $filename;
262 $conf[
'flashvars.'][
'url'] = $prefix . $filename;
264 $conf[
'flashvars.'][
'url'] = str_repeat(
'../', substr_count($player,
'/')) . $filename;
268 if (is_array($conf[
'sources'])) {
269 foreach ($conf[
'sources'] as $key => $source) {
270 if (strpos($source,
'://') === FALSE) {
271 $conf[
'sources'][$key] = $prefix . $source;
275 if (is_array($conf[
'audioSources'])) {
276 foreach ($conf[
'audioSources'] as $key => $source) {
277 if (strpos($source,
'://') === FALSE) {
278 $conf[
'audioSources'][$key] = $prefix . $source;
282 if (isset($conf[
'audioFallback']) && strpos($conf[
'audioFallback'],
'://') === FALSE) {
283 $conf[
'audioFallback'] = $prefix . $conf[
'audioFallback'];
285 if (isset($conf[
'caption']) && strpos($conf[
'caption'],
'://') === FALSE) {
286 $conf[
'caption'] = $prefix . $conf[
'caption'];
289 $conf[
'player'] = $player ?: $filename;
290 $conf[
'installUrl'] = $installUrl;
291 $conf[
'filename'] = $conf[
'flashvars.'][
'url'];
292 $conf[
'prefix'] = $prefix;
294 $conf[
'flashvars.'] = array_merge((array) $typeConf[
'default.'][
'flashvars.'], (array) $conf[
'flashvars.']);
295 $conf[
'params.'] = array_merge((array) $typeConf[
'default.'][
'params.'], (array) $conf[
'params.']);
296 $conf[
'attributes.'] = array_merge((array) $typeConf[
'default.'][
'attributes.'], (array) $conf[
'attributes.']);
297 $conf[
'embedParams'] =
'flashvars, params, attributes';
299 if (is_array(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/hooks/class.tx_cms_mediaitems.php'][
'swfParamTransform'])) {
300 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/hooks/class.tx_cms_mediaitems.php'][
'swfParamTransform'] as $classRef) {
305 $flowplayerVideoConfig = array();
307 if (is_array($conf[
'flashvars.'])) {
310 $conf[
'flashvars.'] = array();
312 $conf[
'videoflashvars'] = $conf[
'flashvars.'];
313 $conf[
'audioflashvars'] = $conf[
'flashvars.'];
314 $conf[
'audioflashvars'][
'url'] = $conf[
'audioFallback'];
317 if (is_array($conf[
'sources'])) {
318 foreach ($conf[
'sources'] as $source) {
320 $mimeType = $this->mimeTypes[$fileinfo[
'fileext']][
'video'];
321 $videoSources .=
'<source src="' . $source .
'"' . ($mimeType ?
' type="' . $mimeType .
'"' :
'') .
' />' . LF;
326 if (is_array($conf[
'audioSources'])) {
327 foreach ($conf[
'audioSources'] as $source) {
329 $mimeType = $this->mimeTypes[$fileinfo[
'fileext']][
'audio'];
330 $audioSources .=
'<source src="' . $source .
'"' . ($mimeType ?
' type="' . $mimeType .
'"' :
'') .
' />' . LF;
334 if ($conf[
'type'] ===
'video' && isset($conf[
'caption'])) {
336 $videoCaptions =
'<track id="' . $replaceElementIdString .
'_captions_track" kind="captions" src="' . $conf[
'caption'] .
'" default="default" />' . LF;
338 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/videojs/video-js/controls/captions.js');
340 $conf[
'videoflashvars'][
'captionUrl'] = $conf[
'caption'];
342 $flowplayerVideoConfig = array_merge_recursive($flowplayerVideoConfig, $this->flowplayerCaptionsConfig);
345 if (isset($conf[
'audioFallback'])) {
349 if ($conf[
'type'] ==
'video') {
350 if (is_array($conf[
'audioSources']) && count($conf[
'audioSources'])) {
352 $pageRenderer->addJsFile(TYPO3_mainDir .
'contrib/videojs/video-js/controls/audio-description.js');
354 if (isset($conf[
'audioFallback'])) {
360 if (count($conf[
'videoflashvars'])) {
361 $flowplayerVideoConfig = array_merge_recursive($flowplayerVideoConfig, array(
'clip' => $conf[
'videoflashvars']));
363 $flowplayerVideoJsonConfig = str_replace(array(
'"true"',
'"false"'), array(
'true',
'false'), json_encode($flowplayerVideoConfig));
364 if (count($conf[
'audioflashvars'])) {
367 $flowplayerAudioJsonConfig = str_replace(array(
'"true"',
'"false"'), array(
'true',
'false'), json_encode(
$flowplayerAudioConfig));
369 if (is_array($conf[
'params.'])) {
372 $videoFlashParams =
'';
373 if (is_array($conf[
'params.'])) {
374 foreach ($conf[
'params.'] as $name => $value) {
375 $videoFlashParams .=
'<param name="' . $name .
'" value="' . $value .
'" />' . LF;
378 $audioFlashParams = $videoFlashParams;
380 $videoFlashParams .=
'<param name="movie" value="' . $player .
'" />' . LF;
381 $videoFlashParams .=
'<param name="flashvars" value=\'config=' . $flowplayerVideoJsonConfig .
'\' />
' . LF; 382 $audioFlashParams .= '<param name=
"movie" value=
"' . $player . '" />
' . LF; 383 $audioFlashParams .= '<param name=
"flashvars" value=\
'config=' . $flowplayerAudioJsonConfig .
'\' />
' . LF; 384 // Assemble audio/video tag attributes 386 if (is_array($conf['attributes.
'])) { 387 \TYPO3\CMS\Core\Utility\GeneralUtility::remapArrayKeys($conf['attributes.
'], $typeConf['attributes.
']['params.
']); 389 foreach ($this->html5TagAttributes as $attribute) { 390 if ($conf['attributes.
'][$attribute] === 'true
' || $conf['attributes.
'][$attribute] === strToLower($attribute) || $conf['attributes.
'][$attribute] === $attribute) { 391 $attributes .= strToLower($attribute) . '=
"' . strToLower($attribute) . '" '; 395 $width = isset($conf['width.
']) ? $this->cObj->stdWrap($conf['width
'], $conf['width.
']) : $conf['width
']; 397 $width = $conf[$type . '.
']['defaultWidth
']; 399 $height = isset($conf['height.
']) ? $this->cObj->stdWrap($conf['height
'], $conf['height.
']) : $conf['height
']; 401 $height = $conf[$type . '.
']['defaultHeight
']; 404 $alternativeContent = isset($conf['alternativeContent.
']) ? $this->cObj->stdWrap($conf['alternativeContent
'], $conf['alternativeContent.
']) : $conf['alternativeContent
']; 406 if ($conf['type
'] === 'video
') { 407 if ($conf['preferFlashOverHtml5
']) { 408 // Flash with video tag fallback 409 $conf['params.
']['playerFallbackOrder
'] = array('flash
', 'html5
'); 410 $flashDivContent = $videoFlashParams . LF . '<video
id=
"' . $replaceElementIdString . '_video_js" class=
"video-js" ' . $attributes . 'controls=
"controls" mediagroup=
"' . $replaceElementIdString . '" width=
"' . $width . '" height=
"' . $height . '">
' . LF . $videoSources . $videoCaptions . $alternativeContent . LF . '</video>
' . LF; 412 <div
id=
"' . $replaceElementIdString . '_flash_install_info" class=
"flash-install-info"></div>
' . LF . '<noscript>
' . LF . '<
object id=
"' . $replaceElementIdString . '_vjs_flash" type=
"application/x-shockwave-flash" data=
"' . $player . '" width=
"' . $width . '" height=
"' . $height . '">
' . LF . $flashDivContent . '</
object>
' . LF . '</noscript>
' . LF; 413 $content = str_replace('###SWFOBJECT###
', '<div
id=
"' . $replaceElementIdString . '_video" class=
"flashcontainer" style=
"width:' . $width . 'px; height:' . $height . 'px;">
' . LF . $divContent . '</div>
', $content); 415 // Video tag with Flash fallback 416 $conf['params.
']['playerFallbackOrder
'] = array('html5
', 'flash
'); 417 $videoTagContent = $videoSources . $videoCaptions; 418 if (isset($conf['videoflashvars
']['url
'])) { 419 $videoTagContent .= ' 420 <noscript>
' . LF . '<
object class=
"vjs-flash-fallback" id=
"' . $replaceElementIdString . '_vjs_flash_fallback" type=
"application/x-shockwave-flash" data=
"' . $player . '" width=
"' . $width . '" height=
"' . $height . '">
' . LF . $videoFlashParams . LF . $alternativeContent . LF . '</
object>
' . LF . '</noscript>
'; 423 <div
id=
"' . $replaceElementIdString . '_flash_install_info" class=
"flash-install-info"></div>
' . LF . '<video
id=
"' . $replaceElementIdString . '_video_js" class=
"video-js" ' . $attributes . 'controls=
"controls" mediagroup=
"' . $replaceElementIdString . '" width=
"' . $width . '" height=
"' . $height . '">
' . LF . $videoTagContent . '</video>
'; 424 $content = str_replace('###SWFOBJECT###
', '<div
id=
"' . $replaceElementIdString . '_video" class=
"video-js-box" style=
"width:' . $width . 'px; height:' . $height . 'px;">
' . LF . $divContent . '</div>
', $content); 428 if ($conf['type
'] === 'audio
' || $audioSources || isset($conf['audioFallback
'])) { 429 if ($conf['preferFlashOverHtml5
']) { 430 // Flash with audio tag fallback 431 $flashDivContent = $audioFlashParams . LF . '<audio
id=
"' . $replaceElementIdString . '_audio_element"' . $attributes . ($conf['type
'] === 'video
' ? ' mediagroup=
"' . $replaceElementIdString . 'style="position:absolute;left:-10000px;
"' : ' controls="controls
"') . ' style="width:
' . $width . 'px; height:
' . $height . 'px;
">' . LF . $audioSources . $alternativeContent . LF . '</audio>' . LF; 432 $divContent = ($conf['type'] === 'video' ? '' : '<div id="' . $replaceElementIdString . '_flash_install_info
" class="flash-install-info
"></div>' . LF) . '<noscript>' . LF . '<object id="' . $replaceElementIdString . '_audio_flash
" type="application/x-shockwave-flash
" data="' . $player . '" width="' . ($conf['type
'] === 'video
' ? 0 : $width) . '" height="' . ($conf['type
'] === 'video
' ? 0 : $height) . '">' . LF . $flashDivContent . '</object>' . LF . '</noscript>' . LF; 433 $audioContent = '<div id="' . $replaceElementIdString . '_audio_box
" class="audio-flash-container
" style="width:
' . ($conf['type
'] === 'video
' ? 0 : $width) . 'px; height:
' . ($conf['type
'] === 'video
' ? 0 : $height) . 'px;
">' . LF . $divContent . '</div>'; 435 // Audio tag with Flash fallback 436 $audioTagContent = $audioSources; 437 if (isset($conf['audioflashvars']['url'])) { 438 $audioTagContent .= ' 439 <noscript>' . LF . '<object class="audio-flash-fallback
" id="' . $replaceElementIdString . '_audio_flash
" type="application/x-shockwave-flash
" data="' . $player . '" width="' . $width . '" height="' . $height . '">' . LF . $audioFlashParams . LF . $alternativeContent . LF . '</object>' . LF . '</noscript>'; 441 $divContent = ($conf['type'] === 'video' ? '' : '<div id="' . $replaceElementIdString . '_flash_install_info
" class="flash-install-info
"></div>' . LF) . '<audio id="' . $replaceElementIdString . '_audio_element
" class="audio-element
"' . $attributes . ($conf['type'] === 'video' ? ' mediagroup="' . $replaceElementIdString . '" style="position:absolute;left:-10000px;
"' : ' controls="controls
"') . '>' . LF . $audioTagContent . '</audio>' . LF . $audioSourcesEmbeddingJsScript; 442 $audioContent = '<div id="' . $replaceElementIdString . '_audio_box
" class="audio-box
" style="width:
' . ($conf['type
'] === 'video
' ? 0 : $width) . 'px; height:
' . ($conf['type
'] === 'video
' ? 0 : $height) . 'px;
">' . LF . $divContent . '</div>'; 444 if ($conf['type'] === 'audio') { 445 $content = str_replace('###SWFOBJECT###', $audioContent, $content); 447 $content .= LF . $audioContent; 450 // Assemble inline JS code 452 $flowplayerHandlers = ''; 453 if ($conf['type'] === 'video') { 454 // Assemble videoJS options 455 $videoJsOptions = array(); 456 foreach ($this->videoJsOptions as $videoJsOption) { 457 if (isset($conf['params.'][$videoJsOption])) { 458 $videoJsOptions[$videoJsOption] = $conf['params.'][$videoJsOption]; 461 $videoJsOptions = count($videoJsOptions) ? json_encode($videoJsOptions) : '{}'; 462 // videoJS setup and videoJS listeners for audio description synchronisation 463 if ($audioSources || isset($conf['audioFallback'])) { 465 var ' . $replaceElementIdString . '_video = VideoJS.setup("' . $replaceElementIdString . '_video_js
", ' . $videoJsOptions . '); 466 var ' . $replaceElementIdString . '_video_element = document.getElementById("' . $replaceElementIdString . '_video_js
"); 467 var ' . $replaceElementIdString . '_audio_element = document.getElementById("' . $replaceElementIdString . '_audio_element
"); 468 if (!!' . $replaceElementIdString . '_video_element && !!' . $replaceElementIdString . '_audio_element) { 469 ' . $replaceElementIdString . '_audio_element.muted = true; 470 VideoJS.addListener(' . $replaceElementIdString . '_video_element, "pause
", function () { document.getElementById("' . $replaceElementIdString . '_audio_element
").pause(); }); 471 VideoJS.addListener(' . $replaceElementIdString . '_video_element, "play
", function () { try {document.getElementById("' . $replaceElementIdString . '_audio_element
").currentTime = document.getElementById("' . $replaceElementIdString . '_video_js
").currentTime} catch(e) {}; document.getElementById("' . $replaceElementIdString . '_audio_element
").play(); }); 472 VideoJS.addListener(' . $replaceElementIdString . '_video_element, "seeked
", function () { document.getElementById("' . $replaceElementIdString . '_audio_element
").currentTime = document.getElementById("' . $replaceElementIdString . '_video_js
").currentTime; }); 473 VideoJS.addListener(' . $replaceElementIdString . '_video_element, "volumechange
", function () { document.getElementById("' . $replaceElementIdString . '_audio_element
").volume = document.getElementById("' . $replaceElementIdString . '_video_js
").volume; }); 477 var ' . $replaceElementIdString . '_video = VideoJS.setup("' . $replaceElementIdString . '_video_js
", ' . $videoJsOptions . '); 480 // Prefer Flash or fallback to Flash 481 $videoSourcesEmbedding = ''; 482 // If we have a video file for Flash 483 if (isset($conf['filename'])) { 484 // If we prefer Flash 485 if ($conf['preferFlashOverHtml5']) { 486 $videoTagAssembly = ''; 487 // Create "source
" elements 488 if (is_array($conf['sources']) && count($conf['sources'])) { 489 foreach ($conf['sources'] as $source) { 490 $fileinfo = \TYPO3\CMS\Core\Utility\GeneralUtility::split_fileref($source); 491 $mimeType = $this->mimeTypes[$fileinfo['fileext']]['video']; 492 $videoTagAssembly .= ' 493 ' . $replaceElementIdString . '_video_js.appendChild($f.extend(document.createElement("source
"), { 494 src: "' . $source . '", 495 type: "' . $mimeType . '" 498 // Create "track
" elements 499 if (isset($conf['caption'])) { 500 // Assemble captions track tag 501 // It will take a while before the captions are loaded and parsed... 502 $videoTagAssembly .= ' 503 var track = document.createElement("track
"); 504 track.setAttribute("src
", "' . $conf['caption
'] . '"); 505 track.setAttribute("id", "' . $replaceElementIdString . '_captions_track
"); 506 track.setAttribute("kind
", "captions
"); 507 track.setAttribute("default", "default"); 508 ' . $replaceElementIdString . '_video_js.appendChild(track);'; 510 $videoTagAssembly .= ' 511 $f.extend(' . $replaceElementIdString . '_video_js, { 512 id: "' . $replaceElementIdString . '_video_js
", 513 className: "video-js
", 514 controls: "controls
", 515 mediagroup: "' . $replaceElementIdString . '", 517 width: "' . $width . '", 518 height: "' . $height . '" 520 ' . $replaceElementIdString . '_video.appendChild(' . $replaceElementIdString . '_video_js); 521 ' . $replaceElementIdString . '_video.className = "video-js-box
";'; 522 $videoTagAssembly .= $videoJsSetup; 524 $videoSourcesEmbedding = ' 525 var ' . $replaceElementIdString . '_video = document.getElementById("' . $replaceElementIdString . '_video
"); 526 var ' . $replaceElementIdString . '_video_js = document.createElement("video
"); 527 if (flashembed.getVersion()[0] > 0) { 528 // Flash is available 529 var videoPlayer = flowplayer("' . $replaceElementIdString . '_video
", ' . $flashConfiguration . ', ' . $flowplayerVideoJsonConfig . ').load(); 530 videoPlayer.onBeforeUnload(function () { return false; }); 531 } else if (!!' . $replaceElementIdString . '_video_js.canPlayType) { 532 // Flash is not available: fallback to videoJS if video tag is supported 533 ' . $videoTagAssembly . ' 535 // Neither Flash nor video is available: offer to install Flash 536 flashembed("' . $replaceElementIdString . '_video
", ' . $flashConfiguration . '); 538 } elseif (is_array($conf['sources'])) { 539 // HTML5 is the preferred rendering method 540 // Test whether the browser supports any of types of the provided sources 541 $supported = array(); 542 foreach ($conf['sources'] as $source) { 543 $fileinfo = \TYPO3\CMS\Core\Utility\GeneralUtility::split_fileref($source); 544 $mimeType = $this->mimeTypes[$fileinfo['fileext']]['video']; 545 $supported[] = $replaceElementIdString . '_videoTag.canPlayType("' . $mimeType . '") != ""'; 547 // Testing whether the browser supports the video tag with any of the provided source types 548 // If no support, embed flowplayer 549 $videoSourcesEmbedding = ' 550 var ' . $replaceElementIdString . '_videoTag = document.createElement(\'video\'); 551 var ' . $replaceElementIdString . '_video_box = document.getElementById("' . $replaceElementIdString . '_video
"); 552 if (' . $replaceElementIdString . '_video_box) { 553 if (!' . $replaceElementIdString . '_videoTag || !' . $replaceElementIdString . '_videoTag.canPlayType || !(' . (count($supported) ? implode(' || ', $supported) : 'false') . ')) { 554 // Avoid showing an empty video element 555 if (document.getElementById("' . $replaceElementIdString . '_video_js
")) { 556 document.getElementById("' . $replaceElementIdString . '_video_js
").style.display = "none
"; 558 if (flashembed.getVersion()[0] > 0) { 559 // Flash is available 560 var videoPlayer = flowplayer("' . $replaceElementIdString . '_video
", ' . $flashConfiguration . ', ' . $flowplayerVideoJsonConfig . ').load(); 561 videoPlayer.onBeforeUnload(function () { return false; }); 563 // Neither Flash nor video is available: offer to install Flash 564 flashembed("' . $replaceElementIdString . '_video
", ' . $flashConfiguration . '); 566 } else {' . $videoJsSetup . ' 572 // Audio fallback to Flash 573 $audioSourcesEmbedding = ''; 574 // If we have an audio file for Flash 575 if (isset($conf['audioFallback'])) { 576 // If we prefer Flash in 577 if ($conf['preferFlashOverHtml5']) { 578 $audioTagAssembly = ''; 579 // Create "source
" elements 580 if (is_array($conf['audioSources']) && count($conf['audioSources'])) { 581 foreach ($conf['audioSources'] as $source) { 582 $fileinfo = \TYPO3\CMS\Core\Utility\GeneralUtility::split_fileref($source); 583 $mimeType = $this->mimeTypes[$fileinfo['fileext']]['audio']; 584 $audioTagAssembly .= ' 585 ' . $replaceElementIdString . '_audio_element.appendChild($f.extend(document.createElement("source
"), { 586 src: "' . $source . '", 587 type: "' . $mimeType . '" 590 $audioTagAssembly .= ' 591 $f.extend(' . $replaceElementIdString . '_audio_element, { 592 id: "' . $replaceElementIdString . '_audio_element
", 593 className: "audio-element
", 594 controls: "' . ($conf['type
'] === 'video
' ? '' : 'controls
') . '", 595 mediagroup: "' . $replaceElementIdString . '", 597 width: "' . ($conf['type
'] === 'video
' ? 0 : $width) . 'px
", 598 height: "' . ($conf['type
'] === 'video
' ? 0 : $height) . 'px
" 600 ' . $replaceElementIdString . '_audio_box.appendChild(' . $replaceElementIdString . '_audio_element); 601 ' . $replaceElementIdString . '_audio_box.className = "audio-box
";'; 603 $audioSourcesEmbedding = ' 604 var ' . $replaceElementIdString . '_audio_box = document.getElementById("' . $replaceElementIdString . '_audio_box
"); 605 var ' . $replaceElementIdString . '_audio_element = document.createElement("audio
"); 606 if (flashembed.getVersion()[0] > 0) { 607 // Flash is available 608 var audioPlayer = flowplayer("' . $replaceElementIdString . '_audio_box
", ' . $flashConfiguration . ', ' . $flowplayerAudioJsonConfig . ').load(); 609 audioPlayer.onBeforeUnload(function () { return false; }); 610 ' . ($conf['type'] === 'video' ? 'audioPlayer.mute();' : '') . ' 611 } else if (!!' . $replaceElementIdString . '_audio_element.canPlayType) { 612 // Flash is not available: fallback to audio element if audio tag is supported 613 ' . $audioTagAssembly . ' 615 // Neither Flash nor audio is available: offer to install Flash if this is not an audio description of a video 616 ' . ($conf['type'] === 'video' ? '' : 'flashembed("' . $replaceElementIdString . '_audio_box
", ' . $flashConfiguration . ');') . ' 618 } elseif (is_array($conf['audioSources'])) { 619 // HTML5 is the preferred rendering method 620 // Test whether the browser supports any of types of the provided sources 621 $supported = array(); 622 foreach ($conf['audioSources'] as $source) { 623 $fileinfo = \TYPO3\CMS\Core\Utility\GeneralUtility::split_fileref($source); 624 $mimeType = $this->mimeTypes[$fileinfo['fileext']]['audio']; 625 $supported[] = $replaceElementIdString . '_audioTag.canPlayType("' . $mimeType . '") != ""'; 627 // Testing whether the browser supports the audio tag with any of the provided source types 628 // If no support, embed flowplayer 629 $audioSourcesEmbedding = ' 630 var ' . $replaceElementIdString . '_audioTag = document.createElement(\'audio\'); 631 var ' . $replaceElementIdString . '_audio_box = document.getElementById("' . $replaceElementIdString . '_audio_box
"); 632 if (' . $replaceElementIdString . '_audio_box) { 633 if (!' . $replaceElementIdString . '_audioTag || !' . $replaceElementIdString . '_audioTag.canPlayType || !(' . (count($supported) ? implode(' || ', $supported) : 'false') . ')) { 634 // Avoid showing an empty audio element 635 if (document.getElementById("' . $replaceElementIdString . '_audio_element
")) { 636 document.getElementById("' . $replaceElementIdString . '_audio_element
").style.display = "none
"; 638 if (flashembed.getVersion()[0] > 0) { 639 var audioPlayer = flowplayer("' . $replaceElementIdString . '_audio_box
", ' . $flashConfiguration . ', ' . $flowplayerAudioJsonConfig . ').load(); 640 audioPlayer.onBeforeUnload(function () { return false; }); 641 ' . ($conf['type'] === 'video' ? 'audioPlayer.mute()' : '') . ' 643 // Neither Flash nor audio is available: offer to install Flash if this is not an audio description of a video 644 ' . ($conf['type'] === 'video' ? '' : 'flashembed("' . $replaceElementIdString . '_audio_box
", ' . $flashConfiguration . ');') . ' 649 // Flowplayer eventHandlers for audio description synchronisation 650 $flowplayerHandlers = ''; 651 if ($conf['type'] === 'video') { 652 $flowplayerHandlers = ' 653 if (flashembed.getVersion()[0] > 0) { 654 // Flash is available 655 var videoPlayer = flowplayer("' . $replaceElementIdString . '_video
"); 657 // Control audio description through video control bar 658 videoPlayer.onVolume(function (volume) { flowplayer("' . $replaceElementIdString . '_audio_box
").setVolume(volume); }); 659 videoPlayer.onMute(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").mute(); }); 660 videoPlayer.onUnmute(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").unmute(); }); 661 videoPlayer.onPause(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").pause(); }); 662 videoPlayer.onResume(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").resume(); }); 663 videoPlayer.onStart(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").play(); }); 664 videoPlayer.onStop(function () { flowplayer("' . $replaceElementIdString . '_audio_box
").stop(); }); 665 videoPlayer.onSeek(function (clip, seconds) { flowplayer("' . $replaceElementIdString . '_audio_box
").seek(seconds); }); 666 // Mute audio description on start 667 flowplayer("' . $replaceElementIdString . '_audio_box
").onStart(function () { this.mute()}); 668 // Audio description toggle 669 var videoContainer = document.getElementById("' . $replaceElementIdString . '_video
"); 670 var buttonContainer = document.createElement("div
"); 671 $f.extend(buttonContainer, { 672 id: "' . $replaceElementIdString . '_audio_description_toggle
", 673 className: "vjs-audio-description-control
" 675 var button = document.createElement("div
"); 676 buttonContainer.appendChild(button); 677 buttonContainer.style.position = "relative
"; 678 buttonContainer.style.left = (parseInt(' . $width . ', 10)-27) + "px
"; 679 videoContainer.parentNode.insertBefore(buttonContainer, videoContainer.nextSibling); 680 VideoJS.addListener(buttonContainer, "click
", function () { 681 var buttonContainer = document.getElementById("' . $replaceElementIdString . '_audio_description_toggle
"); 682 var state = buttonContainer.getAttribute("data-state
"); 683 if (state == "enabled
") { 684 buttonContainer.setAttribute("data-state
", "disabled
"); 685 flowplayer("' . $replaceElementIdString . '_audio_box
").mute(); 687 buttonContainer.setAttribute("data-state
", "enabled
"); 688 flowplayer("' . $replaceElementIdString . '_audio_box
").unmute(); 695 // Wrap up inline JS code 696 $jsInlineCode = $audioSourcesEmbedding . $videoSourcesEmbedding . $flowplayerHandlers; 698 $jsInlineCode = 'VideoJS.DOMReady(function(){' . $jsInlineCode . LF . '});'; 700 $pageRenderer->addJsInlineCode($replaceElementIdString, $jsInlineCode); 701 if (isset($conf['stdWrap.'])) { 702 $content = $this->cObj->stdWrap($content, $conf['stdWrap.']); $flowplayerAudioDescriptionConfig
$flowplayerCaptionsConfig
static remapArrayKeys(&$array, $mappingTable)
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
static split_fileref($fileNameWithPath)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]