Héberger les vidéos sur son site WordPress est souvent problématique. Utiliser YouTube c’est dépendre de Google. J’utilise donc PeerTube. J’ai un compte sur une instance. Oui mais le score des bonnes pratiques était à améliorer. Alors je suis allé chercher une solution que je partage ici.
Les vidéos sur un site, c’est souvent problématique
Sur le papier avec WordPress on pourrait embarquer des vidéos et les partager comme les audios ou les images.
Il y a deux problèmes connus depuis longtemps :
- la charge du serveur surtout si la vidéo est longue et très partagée simultanément
- la compatibilité des formats avec les différents navigateurs et systèmes : j’ai vu des soucis notamment avec des vidéos importées depuis un smartphone, des problèmes avec Apple etc.
Il est donc en général recommandé d’utiliser une plateforme externe.
Pas de YouTube
Aucune envie de créer un lien ou une dépendance entre ce site et Google. Outre la collecte de données, la monétisation, la publicité, YouTube impose ses scripts et pose de nombreux problèmes y compris en termes de performances.
J’ai donc choisi d’héberger les vidéos sur l’instance PeerTube « Mes numériques ». Peer Tube respecte le RGPD, c’est open-source et compatible avec le Fédiverse.
Certes, il s’agit d’une plateforme tierce. À terme, je pourrai installer ma propre instance sur un serveur dédié puisque PeerTube c’est libre !
Améliorer les performances
j’ai toutefois découvert que des erreurs étaient générées en termes de bonnes pratiques et de performances sous mobile. Ces erreurs sont évaluables avec Lighthouse ou PageSpeed Insights par exemple. Je passais de 100% à 96%. Pas dramatique mais agaçant.
Je pourrais ne mettre qu’un lien simple sans embarquer la vidéo, c’est un peu austère.
J’ai cherché et bricolé (oui avec l’aide de l’IA) un code PHP qui permet de résoudre le problème : on obtient 100% de réussite partout. Il faut veiller au poids des autres images de la page le cas échéant.
Exemple avec cette page https://vincentbreton.fr/et-lopera-bastide/
Je le ferai à l’avenir pour les nouvelles vidéos.
Voici le code que je partagerai aussi sur Codeberg.
/**
* Shortcode [peertube url="https://peertube.mesnumeriques.fr/w/xxxxx"]
* Génère une facade (miniature + bouton play) et ne charge l'iframe PeerTube
* (et donc HLS.js) qu'au clic de l'utilisateur.
*/
function vb_peertube_shortcode( $atts ) {
$atts = shortcode_atts( array(
'url' => '',
'autoplay' => '1', // autoplay au clic uniquement, pas au chargement
'loop' => '0',
'muted' => '0',
), $atts, 'peertube' );
if ( empty( $atts['url'] ) ) {
return '';
}
$watch_url = esc_url_raw( $atts['url'] );
// Extrait l'host et l'ID vidéo (watch, w, ou embed)
if ( ! preg_match( '#^https?://([^/]+)/(?:videos/watch|w|videos/embed)/([A-Za-z0-9\-]+)#', $watch_url, $m ) ) {
return '';
}
$host = $m[1];
$video_id = $m[2];
// Cache les métadonnées oEmbed (titre + miniature) 7 jours
$cache_key = 'vb_peertube_' . md5( $watch_url );
$data = get_transient( $cache_key );
if ( false === $data ) {
$oembed_url = 'https://' . $host . '/services/oembed?format=json&url=' . rawurlencode( $watch_url );
$response = wp_remote_get( $oembed_url, array( 'timeout' => 8 ) );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return '<p><a href="' . esc_url( $watch_url ) . '">' . esc_html( $watch_url ) . '</a></p>';
}
$json = json_decode( wp_remote_retrieve_body( $response ), true );
$data = array(
'title' => $json['title'] ?? '',
'thumbnail' => $json['thumbnail_url'] ?? '',
);
set_transient( $cache_key, $data, WEEK_IN_SECONDS );
}
$embed_src = esc_url( 'https://' . $host . '/videos/embed/' . $video_id );
$params = array();
if ( '1' === $atts['autoplay'] ) { $params[] = 'autoplay=1'; }
if ( '1' === $atts['loop'] ) { $params[] = 'loop=1'; }
if ( '1' === $atts['muted'] ) { $params[] = 'muted=1'; }
$embed_src .= $params ? '?' . implode( '&', $params ) : '';
ob_start();
?>
<div class="vb-peertube-facade"
data-embed="<?php echo esc_attr( $embed_src ); ?>"
style="position:relative;max-width:100%;aspect-ratio:16/9;cursor:pointer;background:#000;border-radius:8px;overflow:hidden;">
<?php if ( $data['thumbnail'] ) : ?>
<img src="<?php echo esc_url( $data['thumbnail'] ); ?>"
alt="<?php echo esc_attr( $data['title'] ); ?>"
loading="lazy"
style="width:100%;height:100%;object-fit:cover;display:block;">
<?php endif; ?>
<button type="button" class="vb-peertube-play"
aria-label="Lire la vidéo<?php echo $data['title'] ? ' : ' . esc_attr( $data['title'] ) : ''; ?>"
style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:68px;height:68px;border:none;border-radius:50%;background:rgba(0,0,0,0.6);cursor:pointer;">
<svg viewBox="0 0 24 24" width="28" height="28" fill="#fff" style="margin-left:4px;">
<path d="M8 5v14l11-7z"/>
</svg>
</button>
</div>
<?php
return ob_get_clean();
}
add_shortcode( 'peertube', 'vb_peertube_shortcode' );
/**
* Un seul petit script global, chargé une fois par page,
* qui gère le clic sur toutes les facades PeerTube.
*/
function vb_peertube_facade_script() {
if ( ! is_singular() ) {
return;
}
?>
<script>
document.addEventListener('click', function (e) {
var el = e.target.closest('.vb-peertube-facade');
if (!el) return;
var iframe = document.createElement('iframe');
iframe.src = el.dataset.embed;
iframe.setAttribute('allow', 'autoplay; fullscreen');
iframe.setAttribute('sandbox', 'allow-same-origin allow-scripts allow-popups allow-forms');
iframe.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;border:0;';
el.innerHTML = '';
el.appendChild(iframe);
});
</script>
<?php
}
add_action( 'wp_footer', 'vb_peertube_facade_script' );
À savoir :
Il suffit alors d’utiliser ce format d’URL :
[peertube url="https://peertube.mesnumeriques.fr/w/kBNkFqcsfENMvs2ir4AbSP"]
et ça donne ça :
[peertube url= »https://peertube.mesnumeriques.fr/w/kBNkFqcsfENMvs2ir4AbSP »]
Le code PHP se chargera lui-même de reconstruire l’URL « d’embed « correcte (/videos/embed/kBNkFqcsfENMvs2ir4AbSP) à partir de l’ID extrait.
Petit rappel pratique pour la suite : quand on récupère une vidéo depuis PeerTube, il faudra retenir l’URL de la page de la vidéo (/w/xxxx ou /videos/watch/xxxx, visible dans la barre d’adresse quand on regarde la vidéo sur le site et non l’URL d’embed que PeerTube propose dans son code d’intégration.
Cette page que vous lisez obtient 100% sur tous les onglets Ligthouse ou PageSpeed Insights (avec cache XtremCache)
Comme on trouve très peu de documentation sur cette question, si les unes ou les autres avez des idées de bonnes pratiques à proposer, je suis preneur !

Un mot en retour ?