Project

General

Profile

Feature #78264 » video-v2.patch

Guido S., 2016-10-13 14:40

View differences:

typo3/sysext/core/Classes/Resource/AbstractFile.php
*/
const FILETYPE_APPLICATION = 5;
/**
* Youtube provider, subtype of video mimetype
*/
const FILETYPE_YOUTUBE = 6;
/**
* Vimeo provider, subtype of video mimetype
*/
const FILETYPE_VIMEO = 7;
/******************
* VARIOUS FILE PROPERTY GETTERS
******************/
......
// we don't need to make an SQL statement like EXT:media does currently
if (!$this->properties['type']) {
$mimeType = $this->getMimeType();
list($fileType) = explode('/', $mimeType);
list($fileType, $subType) = explode('/', $mimeType);
switch (strtolower($fileType)) {
case 'text':
$this->properties['type'] = self::FILETYPE_TEXT;
......
break;
case 'video':
$this->properties['type'] = self::FILETYPE_VIDEO;
if ($subType === 'youtube') {
$this->properties['type'] = self::FILETYPE_YOUTUBE;
}
if ($subType === 'vimeo') {
$this->properties['type'] = self::FILETYPE_VIMEO;
}
break;
case 'application':
typo3/sysext/core/Classes/Resource/Index/Indexer.php
*/
protected function getFileType($mimeType)
{
list($fileType) = explode('/', $mimeType);
list($fileType, $subType) = explode('/', $mimeType);
switch (strtolower($fileType)) {
case 'text':
$type = File::FILETYPE_TEXT;
......
break;
case 'video':
$type = File::FILETYPE_VIDEO;
if ($subType === 'youtube') {
$type = File::FILETYPE_YOUTUBE;
}
if ($subType === 'vimeo') {
$type = File::FILETYPE_VIMEO;
}
break;
case 'application':
case 'software':
typo3/sysext/core/Classes/Resource/Rendering/AudioTagRenderer.php
protected $possibleMimeTypes = ['audio/mpeg', 'audio/wav', 'audio/ogg'];
/**
* Attributes for HTML Audio Tag
*
* @var array
*/
protected $possibleAudioAttributes = ['autoplay', 'muted', 'loop', 'controls', 'preload'];
/**
* Returns the priority of the renderer
* This way it is possible to define/overrule a renderer
* for a specific file type/context.
......
*/
public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false)
{
// If autoplay isn't set manually check if $file is a FileReference take autoplay from there
if (!isset($options['autoplay']) && $file instanceof FileReference) {
$autoplay = $file->getProperty('autoplay');
if ($autoplay !== null) {
$options['autoplay'] = $autoplay;
if ($file instanceof FileReference) {
foreach ($this->possibleAudioAttributes as $audioTagAttribute) {
// If video tag attribute isn't set manually check if $file is a FileReference take custom attribute from there
if (!isset($options[$audioTagAttribute])) {
$fileAttribute = $file->getProperty($audioTagAttribute);
if ($fileAttribute !== null) {
$options[$audioTagAttribute] = $fileAttribute;
}
}
}
}
$additionalAttributes = [];
if (!isset($options['controls']) || !empty($options['controls'])) {
$additionalAttributes[] = 'controls';
}
if (!empty($options['autoplay'])) {
$additionalAttributes[] = 'autoplay';
}
if (!empty($options['muted'])) {
$additionalAttributes[] = 'muted';
}
if (!empty($options['loop'])) {
$additionalAttributes[] = 'loop';
// check additional attributes from template
foreach ($this->possibleAudioAttributes as $key) {
if (!isset($options[$key]) || !empty($options[$key])) {
$additionalAttributes[$key] = $key;
}
}
foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload'] as $key) {
if (!empty($options[$key])) {
$additionalAttributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
$additionalAttributes[$key] = $key . '="' . htmlspecialchars($options[$key]) . '"';
}
}
return sprintf(
'<audio%s><source src="%s" type="%s"></audio>',
empty($additionalAttributes) ? '' : ' ' . implode(' ', $additionalAttributes),
empty($additionalAttributes) ? '' : ' ' . implode(' ', array_unique($additionalAttributes)),
htmlspecialchars($file->getPublicUrl($usedPathsRelativeToCurrentScript)),
$file->getMimeType()
);
typo3/sysext/core/Classes/Resource/Rendering/VideoTagRenderer.php
protected $possibleMimeTypes = ['video/mp4', 'video/webm', 'video/ogg', 'application/ogg'];
/**
* Attributes for HTML Video Tag
*
* @var array
*/
protected $possibleVideoAttributes = ['autoplay', 'muted', 'preload', 'loop', 'controls'];
/**
* Returns the priority of the renderer
* This way it is possible to define/overrule a renderer
* for a specific file type/context.
......
*/
public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false)
{
// If autoplay isn't set manually check if $file is a FileReference take autoplay from there
if (!isset($options['autoplay']) && $file instanceof FileReference) {
$autoplay = $file->getProperty('autoplay');
if ($autoplay !== null) {
$options['autoplay'] = $autoplay;
if ($file instanceof FileReference) {
foreach ($this->possibleVideoAttributes as $videoTagAttribute) {
// If video tag attribute isn't set manually check if $file is a FileReference take custom attribute from there
if (!isset($options[$videoTagAttribute])) {
$fileAttribute = $file->getProperty($videoTagAttribute);
if ($fileAttribute !== null) {
$options[$videoTagAttribute] = $fileAttribute;
}
}
}
}
$attributes = [];
// check additional attributes from template
if ((int)$width > 0) {
$attributes[] = 'width="' . (int)$width . '"';
}
if ((int)$height > 0) {
$attributes[] = 'height="' . (int)$height . '"';
}
if (!isset($options['controls']) || !empty($options['controls'])) {
$attributes[] = 'controls';
}
if (!empty($options['autoplay'])) {
$attributes[] = 'autoplay';
}
if (!empty($options['muted'])) {
$attributes[] = 'muted';
}
if (!empty($options['loop'])) {
$attributes[] = 'loop';
foreach ($this->possibleVideoAttributes as $key) {
if (!isset($options[$key]) || !empty($options[$key])) {
$attributes[$key] = $key;
}
}
foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick'] as $key) {
foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'preload'] as $key) {
if (!empty($options[$key])) {
$attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"';
}
......
return sprintf(
'<video%s><source src="%s" type="%s"></video>',
empty($attributes) ? '' : ' ' . implode(' ', $attributes),
empty($attributes) ? '' : ' ' . implode(' ', array_unique($attributes)),
htmlspecialchars($file->getPublicUrl($usedPathsRelativeToCurrentScript)),
$file->getMimeType()
);
typo3/sysext/core/Configuration/TCA/pages.php
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.videoOverlayPalette;videoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_YOUTUBE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIMEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
typo3/sysext/core/Configuration/TCA/sys_file.php
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.image', 2],
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.audio', 3],
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.video', 4],
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.software', 5]
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.software', 5],
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.youtube', 6],
['LLL:EXT:lang/locallang_tca.xlf:sys_file.type.vimeo', 7]
]
]
],
typo3/sysext/core/Configuration/TCA/sys_file_reference.php
'default' => 0
]
],
'loop' => [
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.loop',
'config' => [
'type' => 'check',
'default' => 0
]
],
'muted' => [
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.muted',
'config' => [
'type' => 'check',
'default' => 0
]
],
'preload' => [
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.auto', 'auto'],
['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.none', 'none'],
['LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.preload.metadata', 'metadata']
],
'default' => 'auto'
]
],
'controls' => [
'exclude' => true,
'label' => 'LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.controls',
'config' => [
'type' => 'check',
'default' => 0
]
],
],
'types' => [
// Note that at the moment we define the same fields for every media type.
......
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.basicoverlayPalette;basicoverlayPalette,
--palette--;;filePalette'
]
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_YOUTUBE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.basicoverlayPalette;basicoverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIMEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.basicoverlayPalette;basicoverlayPalette,
--palette--;;filePalette'
],
],
'palettes' => [
// Used for basic overlays: having a filelist etc
......
// Used for everything that is a video
'videoOverlayPalette' => [
'showitem' => '
title,description,--linebreak--,autoplay,controls,loop,muted,--linebreak--,preload
',
],
// Used for everything that is a video
'internetVideoOverlayPalette' => [
'showitem' => '
title,description,--linebreak--,autoplay
',
],
// Used for everything that is a audio file
'audioOverlayPalette' => [
'showitem' => '
title,description,--linebreak--,autoplay
title,description,--linebreak--,autoplay,controls,loop,muted,--linebreak--,preload
',
],
// File palette, hidden but needs to be included all the time
......
'isHiddenPalette' => true,
],
],
];
];
typo3/sysext/core/Tests/Unit/Resource/Rendering/AudioTagRendererTest.php
/**
* @test
*/
public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
$audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
......
$audioTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
);
}
/**
* @test
*/
public function renderOutputWithMutedIsCorrect()
{
$audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
$fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
$fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
$fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
$this->assertSame(
'<audio controls muted><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
$audioTagRenderer->render($fileResourceMock, '300m', '200', ['muted' => 1])
);
}
/**
* @test
*/
public function renderOutputWithPreloadIsCorrect()
{
$audioTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\AudioTagRenderer();
$fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
$fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('audio/mpeg'));
$fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myAudioFile'));
$this->assertSame(
'<audio controls loop preload="auto"><source src="//:path/myAudioFile" type="audio/mpeg"></audio>',
$audioTagRenderer->render($fileResourceMock, '300m', '200', ['preload' => 'auto'])
);
}
}
typo3/sysext/core/Tests/Unit/Resource/Rendering/VideoTagRendererTest.php
/**
* @test
*/
public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
$VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
......
$VideoTagRenderer->render($fileResourceMock, '300m', '200', ['controls' => 0, 'autoplay' => 1])
);
}
/**
* @test
*/
public function renderOutputWithMutedIsCorrect()
{
$VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
$fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
$fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
$fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
$this->assertSame(
'<video width="300" height="200" controls muted><source src="//:path/myVideoFile" type="video/mp4"></video>',
$VideoTagRenderer->render($fileResourceMock, '300m', '200', ['muted' => 1])
);
}
/**
* @test
*/
public function renderOutputWithPreloadIsCorrect()
{
$VideoTagRenderer = new \TYPO3\CMS\Core\Resource\Rendering\VideoTagRenderer();
$fileResourceMock = $this->createMock(\TYPO3\CMS\Core\Resource\File::class);
$fileResourceMock->expects($this->any())->method('getMimeType')->will($this->returnValue('video/mp4'));
$fileResourceMock->expects($this->any())->method('getPublicUrl')->will($this->returnValue('//:path/myVideoFile'));
$this->assertSame(
'<video width="300" height="200" controls preload="auto"><source src="//:path/myVideoFile" type="video/mp4"></video>',
$VideoTagRenderer->render($fileResourceMock, '300m', '200', ['preload' => 'auto'])
);
}
}
typo3/sysext/core/Tests/Unit/Resource/Rendering/VimeoRendererTest.php
/**
* @test
*/
public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
/** @var File|\PHPUnit_Framework_MockObject_MockObject $fileResourceMock */
$fileResourceMock = $this->createMock(File::class);
typo3/sysext/core/Tests/Unit/Resource/Rendering/YouTubeRendererTest.php
/**
* @test
*/
public function renderOutputWithAutoplayAndWithoutControllsIsCorrect()
public function renderOutputWithAutoplayAndWithoutControlsIsCorrect()
{
/** @var File|\PHPUnit_Framework_MockObject_MockObject $fileResourceMock */
$fileResourceMock = $this->createMock(File::class);
typo3/sysext/core/ext_tables.sql
link varchar(1024) DEFAULT '' NOT NULL,
crop varchar(4000) DEFAULT '' NOT NULL,
autoplay tinyint(4) DEFAULT '0' NOT NULL,
preload varchar(8) DEFAULT '' NOT NULL,
controls tinyint(4) DEFAULT '0' NOT NULL,
muted tinyint(4) DEFAULT '0' NOT NULL,
loop tinyint(4) DEFAULT '0' NOT NULL,
PRIMARY KEY (uid),
KEY parent (pid,deleted),
typo3/sysext/frontend/Configuration/TCA/pages_language_overlay.php
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.videoOverlayPalette;videoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_YOUTUBE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIMEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
typo3/sysext/frontend/Configuration/TCA/tt_content.php
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.videoOverlayPalette;videoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_YOUTUBE => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_VIMEO => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.internetVideoOverlayPalette;internetVideoOverlayPalette,
--palette--;;filePalette'
],
\TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
'showitem' => '
--palette--;LLL:EXT:lang/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
typo3/sysext/lang/locallang_tca.xlf
<trans-unit id="sys_file.type.software">
<source>Software</source>
</trans-unit>
<trans-unit id="sys_file.type.youtube">
<source>Youtube</source>
</trans-unit>
<trans-unit id="sys_file.type.vimeo">
<source>Vimeo</source>
</trans-unit>
<trans-unit id="sys_file.mime_type">
<source>Mime Type</source>
</trans-unit>
......
<trans-unit id="sys_file_reference.autoplay">
<source>Autoplay</source>
</trans-unit>
<trans-unit id="sys_file_reference.controls">
<source>Controls</source>
</trans-unit>
<trans-unit id="sys_file_reference.muted">
<source>Muted</source>
</trans-unit>
<trans-unit id="sys_file_reference.loop">
<source>Loop</source>
</trans-unit>
<trans-unit id="sys_file_reference.preload">
<source>Preload</source>
</trans-unit>
<trans-unit id="sys_file_reference.preload.auto">
<source>Auto</source>
</trans-unit>
<trans-unit id="sys_file_reference.preload.none">
<source>None</source>
</trans-unit>
<trans-unit id="sys_file_reference.preload.metadata">
<source>Metadata</source>
</trans-unit>
<trans-unit id="sys_file_collection">
<source>File collection</source>
</trans-unit>
(2-2/2)