WCAG 4.1.2: add WebVTT caption support for <video> elements on tfe.php

Problem: <video> elements on tfe.php had no <track kind="captions"> element,
violating WCAG 4.1.2 (name, role, value) for video content.

Changes:
- public/tfe.php: collect all text/vtt files from the thesis file list before
  rendering; skip standalone rendering of .vtt entries; for each MP4 emit a
  <track kind="captions" srclang="fr" label="Sous-titres" default> pointing
  to the N-th VTT file (N-th video paired with N-th caption in document order)
- public/media.php: add text/vtt to allowed MIME list; normalise finfo
  text/plain -> text/vtt for .vtt files; add vtt branch to cache/header
  block (Content-Type: text/vtt; charset=utf-8, 1-day cache)
- public/admin/actions/formulaire.php: allow .vtt uploads (text/vtt MIME,
  vtt extension); normalise text/plain finfo result; set file_type='caption'
  for VTT files so they are distinguishable from other thesis files
- public/admin/add.php: extend files field accept attr to include .vtt;
  update hint text to document the VTT sidecar convention

VTT files uploaded under theses/ inherit the same access_type visibility
gate in media.php as all other thesis content (403 for access_type_id=3).
This commit is contained in:
Pontoporeia
2026-04-03 13:24:26 +02:00
parent 6e68edfbff
commit 94e9060dc7
6 changed files with 58 additions and 8 deletions

View File

@@ -196,6 +196,19 @@ $bodyClass = 'tfe-body';
<?php
$accessTypeId = $db->getThesisAccessTypeId($thesisId) ?? 1;
$isInterdit = ($accessTypeId === 3);
// Collect any WebVTT caption files uploaded for this thesis.
// The N-th VTT file is paired with the N-th video in document order.
$_captionFiles = [];
foreach ($data['files'] ?? [] as $_cf) {
$__mime = $_cf['mime_type'] ?? '';
$__ext2 = strtolower(pathinfo($_cf['file_path'], PATHINFO_EXTENSION));
if ($__mime === 'text/vtt' || $__ext2 === 'vtt') {
$_captionFiles[] = $_cf['file_path'];
}
}
$_videoIndex = 0;
unset($_cf, $__mime, $__ext2);
?>
<?php if ($isInterdit): ?>
<p class="tfe-restricted">
@@ -203,7 +216,11 @@ $bodyClass = 'tfe-body';
</p>
<?php elseif (!empty($data['files'])): ?>
<?php foreach ($data['files'] as $file): ?>
<?php $ext = strtolower(pathinfo($file['file_path'], PATHINFO_EXTENSION)); ?>
<?php
$ext = strtolower(pathinfo($file['file_path'], PATHINFO_EXTENSION));
// VTT caption files are consumed inline by <video>; skip standalone rendering.
if ($ext === 'vtt') continue;
?>
<figure>
<?php if ($ext === 'pdf'): ?>
<embed src="/media.php?path=<?= urlencode($file['file_path']) ?>"
@@ -221,8 +238,20 @@ $bodyClass = 'tfe-body';
: ($data['title'] . ' — ' . ($data['authors'] ?? ''))
) ?>">
<?php elseif ($ext === 'mp4'): ?>
<?php
// Pair this video with the N-th VTT file (if one was uploaded).
$_vttPath = $_captionFiles[$_videoIndex] ?? null;
$_videoIndex++;
?>
<video width="100%" controls>
<source src="/media.php?path=<?= urlencode($file['file_path']) ?>" type="video/mp4">
<?php if ($_vttPath): ?>
<track kind="captions"
src="/media.php?path=<?= urlencode($_vttPath) ?>"
srclang="fr"
label="Sous-titres"
default>
<?php endif; ?>
</video>
<?php endif; ?>
<?php if (!empty($file['description'])): ?>