Skip to content

Commit 259b480

Browse files
committed
Update MediaPlayer to support audio and video file detection
- use Audio and Video Use Groups - refactor `MediaplayerController` using media instead of video
1 parent fdde678 commit 259b480

File tree

6 files changed

+79
-77
lines changed

6 files changed

+79
-77
lines changed

Classes/Controller/MediaPlayerController.php

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,152 +50,155 @@ public function mainAction(): ResponseInterface
5050

5151
$doc = $this->document->getCurrentDocument();
5252
$pageNo = $this->requestData['page'];
53-
$video = $this->getVideoInfo($doc, $pageNo);
54-
if ($video === null) {
53+
$media = $this->getMediaplayerInfo($doc, $pageNo);
54+
if ($media === null) {
5555
return $this->htmlResponse();
5656
}
5757

5858
$this->addPlayerAssets();
5959

60-
$this->view->assign('video', $video);
60+
$this->view->assign('media', $media);
6161

6262
return $this->htmlResponse();
6363
}
6464

6565
/**
66-
* Build video info to be passed to the player template.
66+
* Build Mediaplayer info to be passed to the player template.
6767
*
6868
* @param AbstractDocument $doc
6969
* @param int $pageNo
7070
*
71-
* @return ?mixed[] The video data, or `null` if no video source is found
71+
* @return ?mixed[] The Mediaplayer data, or `null` if no audio/video-media source is found
7272
*/
73-
protected function getVideoInfo(AbstractDocument $doc, int $pageNo): ?array
73+
protected function getMediaplayerInfo(AbstractDocument $doc, int $pageNo): ?array
7474
{
75-
// Get image file use groups
76-
$imageUseGroups = $this->useGroupsConfiguration->getImage();
75+
// Get audio file use groups
76+
$audioUseGroups = $this->useGroupsConfiguration->getAudio();
7777
// Get video file use groups
7878
$videoUseGroups = $this->useGroupsConfiguration->getVideo();
7979
$mainVideoUseGroup = $videoUseGroups[0] ?? '';
80+
// Merge audio and video file use groups without duplicates
81+
$mediaplayerUseGroups = array_unique([...$audioUseGroups, ...$videoUseGroups]);
8082

8183
// Get thumbnail file use groups
8284
$thumbnailUseGroups = $this->useGroupsConfiguration->getThumbnail();
83-
8485
// Get waveform file use groups
8586
$waveformUseGroups = $this->useGroupsConfiguration->getWaveform();
87+
// Get image file use groups
88+
$imageUseGroups = $this->useGroupsConfiguration->getImage();
8689

87-
// Collect video file source URLs
90+
// Collect audio/video-media file source URLs
8891
// TODO: This is for multiple sources (MPD, HLS, MP3, ...) - revisit, make sure it's ordered by preference!
89-
$videoSources = $this->collectVideoSources($doc, $pageNo, $videoUseGroups);
90-
if (empty($videoSources)) {
92+
$mediaplayerSources = $this->collectMediaSources($doc, $pageNo, $mediaplayerUseGroups);
93+
if (empty($mediaplayerSources)) {
9194
return null;
9295
}
9396

9497
// List all chapters for chapter markers
95-
$videoChapters = $this->collectVideoChapters($doc);
98+
$mediaChapters = $this->collectMediaChapters($doc);
9699

97-
// Get additional video URLs
98-
$videoUrl = $this->collectAdditionalVideoUrls($doc, $pageNo, $thumbnailUseGroups, $waveformUseGroups, $imageUseGroups);
100+
// Get additional audio/video-media URLs
101+
$mediaUrl = $this->collectAdditionalMediaUrls($doc, $pageNo, $thumbnailUseGroups, $waveformUseGroups, $imageUseGroups);
99102

100103
return [
101-
'start' => $videoChapters[$pageNo - 1]['timecode'] ?? '',
102-
'mode' => $this->determineInitialMode($videoSources, $mainVideoUseGroup),
103-
'chapters' => $videoChapters,
104+
'start' => $mediaChapters[$pageNo - 1]['timecode'] ?? '',
105+
'mode' => $this->determineInitialMode($mediaplayerSources, $mainVideoUseGroup),
106+
'chapters' => $mediaChapters,
104107
'metadata' => $doc->getToplevelMetadata(),
105-
'sources' => $videoSources,
106-
'url' => $videoUrl,
108+
'sources' => $mediaplayerSources,
109+
'url' => $mediaUrl,
107110
];
108111
}
109112

110113
/**
111-
* Collects video sources for the given document.
114+
* Collects Audio/Video-Media sources for the given document.
112115
*
113-
* @param AbstractDocument $doc The document object to collect video sources from
114-
* @param int $pageNo The page number to collect video sources for
115-
* @param string[] $videoUseGroups The array of video use groups to search for video sources
116+
* @param AbstractDocument $doc The document object to collect media sources from
117+
* @param int $pageNo The page number to collect media sources for
118+
* @param string[] $mediaplayerUseGroups The array of mediaplayer use groups to search for media sources
116119
*
117-
* @return mixed[] An array of video sources with details like MIME type, URL, file ID, and frame rate
120+
* @return mixed[] An array of media sources with details like MIME type, URL, file ID, and frame rate
118121
*/
119-
private function collectVideoSources(AbstractDocument $doc, int $pageNo, array $videoUseGroups): array
122+
private function collectMediaSources(AbstractDocument $doc, int $pageNo, array $mediaplayerUseGroups): array
120123
{
121-
$videoSources = [];
122-
$videoFiles = $this->findFiles($doc, $pageNo, $videoUseGroups);
123-
foreach ($videoFiles as $videoFile) {
124-
if ($this->isMediaMime($videoFile['mimeType'])) {
125-
$fileMetadata = $doc->getMetadata($videoFile['fileId']);
124+
$mediaplayerSources = [];
125+
$mediaFiles = $this->findFiles($doc, $pageNo, $mediaplayerUseGroups);
126+
foreach ($mediaFiles as $mediaFile) {
127+
if ($this->isMediaMime($mediaFile['mimeType'])) {
128+
$fileMetadata = $doc->getMetadata($mediaFile['fileId']);
126129

127-
$videoSources[] = [
128-
'fileGrp' => $videoFile['fileGrp'],
129-
'mimeType' => $videoFile['mimeType'],
130-
'url' => $videoFile['url'],
131-
'fileId' => $videoFile['fileId'],
130+
$mediaplayerSources[] = [
131+
'fileGrp' => $mediaFile['fileGrp'],
132+
'mimeType' => $mediaFile['mimeType'],
133+
'url' => $mediaFile['url'],
134+
'fileId' => $mediaFile['fileId'],
132135
'frameRate' => $fileMetadata['video_frame_rate'][0] ?? '',
133136
];
134137
}
135138
}
136-
return $videoSources;
139+
return $mediaplayerSources;
137140
}
138141

139142
/**
140-
* Determine the initial mode (video or audio) based on the provided video sources and the main video use group.
143+
* Determine the initial mode (video or audio) based on the provided audio/video-media sources and the main video use group.
141144
*
142-
* @param mixed[] $videoSources An array of video sources with details like MIME type, URL, file ID, and frame rate
145+
* @param mixed[] $mediaplayerSources An array of media sources with details like MIME type, URL, file ID, and frame rate
143146
* @param string $mainVideoUseGroup The main video use group to prioritize
144147
*
145148
* @return string The initial mode ('video' or 'audio')
146149
*/
147-
private function determineInitialMode(array $videoSources, string $mainVideoUseGroup): string
150+
private function determineInitialMode(array $mediaplayerSources, string $mainVideoUseGroup): string
148151
{
149-
foreach ($videoSources as $videoSource) {
152+
foreach ($mediaplayerSources as $mediaplayerSource) {
150153
// TODO: Better guess of initial mode?
151154
// Perhaps we could look for VIDEOMD/AUDIOMD in METS
152-
if ($videoSource['fileGrp'] === $mainVideoUseGroup || str_starts_with($videoSource['mimeType'], 'video/')) {
155+
if ($mediaplayerSource['fileGrp'] === $mainVideoUseGroup || str_starts_with($mediaplayerSource['mimeType'], 'video/')) {
153156
return 'video';
154157
}
155158
}
156159
return 'audio';
157160
}
158161

159162
/**
160-
* Collects all video chapters for chapter markers from the given AbstractDocument.
163+
* Collects all audio/video-media chapters for chapter markers from the given AbstractDocument.
161164
*
162-
* @param AbstractDocument $doc The AbstractDocument object to collect video chapters from
165+
* @param AbstractDocument $doc The AbstractDocument object to collect media chapters from
163166
*
164-
* @return mixed[] An array of video chapters with details like file IDs, page numbers, titles, and timecodes
167+
* @return mixed[] An array of media chapters with details like file IDs, page numbers, titles, and timecodes
165168
*/
166-
private function collectVideoChapters(AbstractDocument $doc): array
169+
private function collectMediaChapters(AbstractDocument $doc): array
167170
{
168-
$videoChapters = [];
171+
$mediaChapters = [];
169172
foreach ($doc->tableOfContents as $entry) {
170-
$this->recurseChapters($entry, $videoChapters);
173+
$this->recurseChapters($entry, $mediaChapters);
171174
}
172-
return $videoChapters;
175+
return $mediaChapters;
173176
}
174177

175178
/**
176-
* Collects additional video URLs like poster and waveform for a given document, page number, thumb file use groups, and waveform file use groups.
179+
* Collects additional audio/video-media URLs like poster and waveform for a given document, page number, thumb file use groups, and waveform file use groups.
177180
*
178181
* @param AbstractDocument $doc The document object
179182
* @param int $pageNo The page number
180183
* @param string[] $thumbnailUseGroups An array of thumb file use groups
181184
* @param string[] $waveformUseGroups An array of waveform file use groups
182185
* @param string[] $imageUseGroups An array of image file use groups
183186
*
184-
* @return mixed[] An array containing additional video URLs like poster and waveform
187+
* @return mixed[] An array containing additional audio/video-media URLs like poster and waveform
185188
*/
186-
private function collectAdditionalVideoUrls(AbstractDocument $doc, int $pageNo, array $thumbnailUseGroups, array $waveformUseGroups, array $imageUseGroups): array
189+
private function collectAdditionalMediaUrls(AbstractDocument $doc, int $pageNo, array $thumbnailUseGroups, array $waveformUseGroups, array $imageUseGroups): array
187190
{
188-
$videoUrl = [];
191+
$mediaUrl = [];
189192

190193
$showPoster = $this->settings['constants']['showPoster'] ?? null;
191194
$thumbFiles = $this->findFiles($doc, 0, $thumbnailUseGroups); // 0 = for whole video (not just chapter)
192195
if (!empty($thumbFiles) && (int) $showPoster === 1) {
193-
$videoUrl['poster'] = $thumbFiles[0];
196+
$mediaUrl['poster'] = $thumbFiles[0];
194197
}
195198

196199
$waveformFiles = $this->findFiles($doc, $pageNo, $waveformUseGroups);
197200
if (!empty($waveformFiles)) {
198-
$videoUrl['waveform'] = $waveformFiles[0];
201+
$mediaUrl['waveform'] = $waveformFiles[0];
199202
}
200203

201204
$showAudioLabelImage = $this->settings['constants']['showAudioLabelImage'] ?? null;
@@ -204,10 +207,10 @@ private function collectAdditionalVideoUrls(AbstractDocument $doc, int $pageNo,
204207
&& (int) $showAudioLabelImage === 1
205208
&& Helper::filterFilesByMimeType($audioLabelImageFiles[0], ['image'], ['JPG'], 'mimeType')
206209
) {
207-
$videoUrl['audioLabelImage'] = $audioLabelImageFiles[0];
210+
$mediaUrl['audioLabelImage'] = $audioLabelImageFiles[0];
208211
}
209212

210-
return $videoUrl;
213+
return $mediaUrl;
211214
}
212215

213216
/**

Classes/ViewHelpers/MediaPlayerConfigViewHelper.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,8 @@ private static function getTranslations(SiteLanguage $language, string $translat
136136
// - Pass $languageKey to ensure that translation matches ISO code
137137
$phrases[$translationKey] = LocalizationUtility::translate(
138138
"LLL:$translationFile:$translationKey",
139-
/* extensionName= */
140-
null,
141-
/* arguments= */
142-
null,
139+
null, // extensionName
140+
null, // arguments
143141
$languageKey
144142
);
145143
}

Configuration/FlexForms/MediaPlayer.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<config>
3333
<type>input</type>
3434
<eval>required,alphanum_x,nospace</eval>
35-
<default>tx-dlf-video</default>
35+
<default>tx-dlf-media</default>
3636
</config>
3737
</settings.elementId>
3838
<settings.shareButtons>

Documentation/Plugins/Index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ FlexForm Configuration
526526
Media Player
527527
------------
528528

529-
The MediaPlayer plugin is only active if the selected document has valid video file use groups (useGroupsVideo).
529+
The MediaPlayer plugin is only active if the selected document has valid audio or video file use groups (useGroupsAudio, useGroupsVideo).
530530

531531
:typoscript:`plugin.tx_dlf_mediaplayer.settings.`
532532

@@ -556,7 +556,7 @@ The MediaPlayer plugin is only active if the selected document has valid video f
556556
:Data Type:
557557
:ref:`t3tsref:data-type-string`
558558
:Default:
559-
tx-dlf-video
559+
tx-dlf-media
560560
:Description:
561561
ID value of the HTML element for the media player.
562562

Resources/Private/Less/SlubMediaPlayer/SlubMediaPlayer.less

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ slub-media {
1616
}
1717
}
1818

19-
body[data-has-video] {
19+
// hide irrelevant controls when a/v mediaplayer is present (e.g. doublepage, rotate, zoom)
20+
body[mediaplayer] {
2021
.page-control,
2122
.document-functions li.doublepage,
2223
.view-functions li.rotate,

Resources/Private/Templates/MediaPlayer/Main.html

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
data-namespace-typo3-fluid="true"
44
lang="en">
55

6-
<f:if condition="{video}">
6+
<f:if condition="{media}">
77
<script>
8-
document.body.setAttribute("data-has-video", "yes");
8+
document.body.setAttribute("mediaplayer", "yes");
99
</script>
1010

1111
<kitodo:mediaPlayerConfig id="MEDIA_CONFIG" settings="{settings}" />
@@ -14,12 +14,12 @@
1414
<div class="media-panel">
1515
<!-- Wrapper panels for toolbox toggles -->
1616
<div class="media-panel-wrappers">
17-
<f:if condition="{settings.constants.showAudioLabelImage} == 1 && {video.url.audioLabelImage}">
17+
<f:if condition="{settings.constants.showAudioLabelImage} == 1 && {media.url.audioLabelImage}">
1818
<div id="panel-audiolabelimage" class="panel panel-audiolabelimage visible" data-panel="audiolabelimage">
1919
<div class="audiolabelimage-inner">
20-
<div class="audiolabelimage-bg" style="background-image: url('{video.url.audioLabelImage.url}');"></div>
20+
<div class="audiolabelimage-bg" style="background-image: url('{media.url.audioLabelImage.url}');"></div>
2121
<div class="audiolabelimage-art">
22-
<img src="{video.url.audioLabelImage.url}" alt="Audio Label Image">
22+
<img src="{media.url.audioLabelImage.url}" alt="Audio Label Image">
2323
</div>
2424
</div>
2525
</div>
@@ -54,21 +54,21 @@
5454
</div>
5555

5656
<div id="tx-dlf-view" class="tx-dlf-view">
57-
<f:if condition="{video.url.waveform}">
58-
<dlf-waveform hidden id="{settings.elementId}-waveform" forPlayer="{settings.elementId}" src="{video.url.waveform.url}" type="{video.url.waveform.mimeType}"></dlf-waveform>
57+
<f:if condition="{media.url.waveform}">
58+
<dlf-waveform hidden id="{settings.elementId}-waveform" forPlayer="{settings.elementId}" src="{media.url.waveform.url}" type="{media.url.waveform.mimeType}"></dlf-waveform>
5959
</f:if>
6060

61-
<slub-media id="{settings.elementId}" player-view="combined-container" poster="{video.url.poster.url}" config="MEDIA_CONFIG" start="{video.start}" mode="auto" mode-fallback="{video.mode}">
61+
<slub-media id="{settings.elementId}" player-view="combined-container" poster="{media.url.poster.url}" config="MEDIA_CONFIG" start="{media.start}" mode="auto" mode-fallback="{media.mode}">
6262
<f:comment>NOTE: If one of these doesn't exist, the player will try the next one.</f:comment>
63-
<f:for each="{video.sources}" as="source">
63+
<f:for each="{media.sources}" as="source">
6464
<source src="{source.url}" type="{source.mimeType}" data-fps="{source.frameRate}" data-fileid="{source.fileId}">
6565
</f:for>
6666

67-
<f:for each="{video.chapters}" as="chapter">
67+
<f:for each="{media.chapters}" as="chapter">
6868
<dlf-chapter title="{chapter.title}" timecode="{chapter.timecode}" fileids="{chapter.fileIdsJoin}" pageNo="{chapter.pageNo}"></dlf-chapter>
6969
</f:for>
7070

71-
<f:for each="{video.metadata}" as="values" key="key">
71+
<f:for each="{media.metadata}" as="values" key="key">
7272
<f:for each="{values}" as="value">
7373
<dlf-meta key="{key}" value="{value}"></dlf-meta>
7474
</f:for>
@@ -77,7 +77,7 @@
7777
<dlf-media-controls>
7878
<button data-type="volume"></button>
7979
<button data-type="mute"></button>
80-
<f:if condition="{video.url.waveform}">
80+
<f:if condition="{media.url.waveform}">
8181
<button class="material-icons-round sxnd-waveform-button" data-t-title="control.waveform.tooltip" data-action="sound_tools.waveform.toggle">graphic_eq</button>
8282
</f:if>
8383
<button class="material-icons-round sxnd-screenshot-button" data-t-title="control.screenshot.tooltip" data-action="modal.screenshot.open">photo_camera</button>

0 commit comments

Comments
 (0)