Sonder une vidéo¶
Objectif : extraire les métadonnées d'une vidéo uploadée avec ffprobe.
Ce que vous allez apprendre : probe_video. La fonction lance ffprobe
(lecture seule) sur le fichier d'origine d'une vidéo et en extrait durée,
dimensions, codecs et conteneur. C'est l'étape qui précède le transcodage :
on inspecte la source avant de la convertir.
Premier palier du niveau avancé de la progression vidéo, la bascule vers le
transcodage réel. Après le niveau intermédiaire.
ffprobe requis
Ce palier exécute ffprobe. Installez ffmpeg/ffprobe et renseignez au
besoin FORGE_VIDEO_FFPROBE_BIN. ffprobe lit la source ; il ne
transcode pas.
Ce que ce starter montre¶
- la sonde d'un fichier via
probe_video(ffprobe, lecture seule) ; - l'extraction de
duration_seconds,width,height,video_codec,
audio_codec,container; - des réponses pédagogiques :
404(UUID inconnu),502(sonde échouée).
La table videos est garantie par la migration fournie plus bas.
Classes Forge utilisées¶
| Classe / fonction | Rôle dans ce starter | Référence |
|---|---|---|
VideoRepository.get_by_uuid |
Retrouver le chemin du fichier d'origine. | Parcours vidéo |
forge_mvc_video.probe.probe_video |
Lancer ffprobe et extraire les métadonnées. | Parcours vidéo |
VideoProbeError |
Sonde échouée (source illisible / non vidéo). | Parcours vidéo |
Tester¶
Avec une vidéo uploadée (niveau intermédiaire) et ffprobe installé, ouvrez
https://localhost:8000/video-probe/<uuid> : la réponse JSON donne les
métadonnées extraites du fichier.
Le contrôleur¶
# mvc/controllers/video_probe_controller.py
from pathlib import Path
from core.http.request import Request
from core.http.response import Response
from core.mvc.controller.base_controller import BaseController
from forge_mvc_video.config import load_video_config
from forge_mvc_video.probe import VideoProbeError, probe_video
from forge_mvc_video.storage.repository import VideoRepository
_STORAGE_NOT_READY = {
"error": "video_storage_not_ready",
"message": (
"La table videos n'est pas encore disponible. "
"Applique la migration Forge Vidéo (forge video:init)."
),
}
class VideoProbeController(BaseController):
@staticmethod
def index(request: Request) -> Response:
uuid = request.route("uuid")
try:
video = VideoRepository().get_by_uuid(uuid)
except Exception:
return Response.json(_STORAGE_NOT_READY, status=503)
if video is None:
return Response.json(
{"error": "video_not_found", "uuid": uuid}, status=404
)
cfg = load_video_config()
path = str(Path(cfg.storage_root) / video["original_path"])
try:
meta = probe_video(path, config=cfg)
except VideoProbeError as exc:
return Response.json(
{"error": "probe_failed", "message": str(exc)}, status=502
)
return Response.json({
"uuid": uuid,
"metadata": {
"duration_seconds": meta.duration_seconds,
"width": meta.width,
"height": meta.height,
"video_codec": meta.video_codec,
"audio_codec": meta.audio_codec,
"container": meta.container,
},
})
Comprendre ce code¶
- On retrouve le chemin du fichier via la ligne
videos(original_path,
relatif àstorage_root), jamais un chemin fourni par le client. probe_video(path, config=cfg)exécute ffprobe en lecture seule : il
n'altère pas le fichier. UneVideoProbeError(source illisible, pas une vidéo)
devient un502clair.- C'est l'inspection préalable : le transcodage proprement dit vient au palier
suivant.
La migration¶
La sonde lit le chemin du fichier d'origine depuis la table videos. Créez-la
si elle n'existe pas déjà. CREATE TABLE IF NOT EXISTS reste idempotent.
-- mvc/migrations/20260601230000_create_videos.sql
CREATE TABLE IF NOT EXISTS videos (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
uuid CHAR(36) NOT NULL,
title VARCHAR(255) NULL,
original_path VARCHAR(500) NOT NULL,
mp4_path VARCHAR(500) NULL,
poster_path VARCHAR(500) NULL,
mime_type VARCHAR(120) NULL,
size_bytes BIGINT UNSIGNED NOT NULL,
duration_seconds INT UNSIGNED NULL,
width INT UNSIGNED NULL,
height INT UNSIGNED NULL,
status VARCHAR(30) NOT NULL,
error_message TEXT NULL,
created_at DATETIME(6) NOT NULL,
updated_at DATETIME(6) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uq_videos_uuid (uuid),
INDEX idx_videos_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
La route¶
Ajoutez la route paramétrée dans le groupe public de mvc/routes.py.
# mvc/routes.py
from mvc.controllers.video_probe_controller import VideoProbeController
with router.group("", public=True) as public:
public.add("GET", "/video-probe/{uuid}", VideoProbeController.index, name="video_probe_index")
À retenir¶
probe_videolance ffprobe (lecture seule) et extrait les métadonnées.- On sonde la source à partir de son chemin stocké, pas d'une entrée client.
- La sonde précède le transcodage : on inspecte avant de convertir.
Après ce starter¶
Vous savez inspecter une source. La suite : la transcoder en MP4.