Feature #78264 » video.patch
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/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.
|
||
... | ... | |
// Used for everything that is a video
|
||
'videoOverlayPalette' => [
|
||
'showitem' => '
|
||
title,description,--linebreak--,autoplay
|
||
title,description,--linebreak--,autoplay,controls,loop,muted,--linebreak--,preload
|
||
',
|
||
],
|
||
// 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
|
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/lang/locallang_tca.xlf | ||
---|---|---|
<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>
|