découpe précise de la vidéo (+ audio) avec ffmpeg

10

Je souhaite que mon site Web permette aux utilisateurs de créer avec précision leurs propres clips à partir d'une vidéo source que je fournis.

J'ai un fichier vidéo source que je veux d'abord convertir en un fichier adapté à un site Web:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)

J'utilise ffmpeg pour le convertir comme ceci:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4

En regardant cette vidéo, elle est de bonne qualité et de taille de fichier suffisamment petite pour mes besoins, et se charge / joue sur mon site Web.

J'ai une page Web qui permet aux utilisateurs de sélectionner un début et une fin sur cette vidéo - et de créer un clip. Voici un exemple de la commande ffmpeg que j'utilise pour cela:

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4

Le problème est que le clip n'est pas toujours suffisamment précis dans le temps. Habituellement, l'audio est suffisamment précis, mais la vidéo s'arrête une demi-seconde plus tôt ou quelque chose comme ça.

Existe-t-il un moyen de rendre cela précis et synchronisé, à savoir 0,2 seconde?

EDIT: l'ajout -force_key_frames 00:00:00.2n'a pas aidé.

EDIT: J'ai changé l'écrêtage à utiliser -c:v libx264 -c:a aac -strict experimentalplutôt -codec:v copy -codec:a copyqu'avec de bons résultats (ish).

Le fichier peut être lu en externe sans problème - mais quand je le charge dans mon élément vidéo html5 et le joue - la dernière partie de la vidéo (l'audio est bien) se fige. La dernière partie qui se fige dure moins d'une seconde.

Dois-je l'essayer avec un autre encodeur vidéo? Quelle est la meilleure alternative pour libx264? Gardant à l'esprit que je souhaiterai probablement que ce soit sur un site Web public.

Mais attendez le fait qu'il joue avec précision sans problème avec un lecteur comme MPC ou Windows Media Player ne suggère pas que c'est un problème avec Google Chrome ou l'élément vidéo HTML? Ou est-ce que j'utilise un encodage non pris en charge ou quelque chose?

Pete Oakey
la source
Cela peut être lié au timing des images clés. Dans tous les cas, cela doit être déplacé vers SuperUser.com.
Brad
Salut, ffmpeg ne peut couper la vidéo à aucun moment, il ne peut couper que les images clés; pour cette raison, l'audio est presque précis, contrairement à la vidéo.
Puis-je le déplacer moi-même? Je vais essayer d'ajouter des images clés au fichier source avec -force_key_frames 00: 00: 00.2
Pete Oakey

Réponses:

9

Le comportement des -sschangements dépend de s'il est utilisé comme option d'entrée ou de sortie, et est souvent plus lent mais peut être plus précis lorsqu'il est utilisé comme option de sortie. Voir la réponse à ffmpeg convertit lentement la vidéo de la période spécifiée pour plus de détails et d'exemples.

Pour modifier la qualité de sortie, source.mp4utilisez l' -crfoption avec une valeur comprise entre 18 et 28 (23 par défaut). Voir la section CRF du Guide de codage FFmpeg et x264 pour des exemples.

Votre commande de rognage peut être simplifiée:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4

J'ai remplacé -codec:v copy -codec:a copypar -c copy -map 0. Cela copiera tous les flux au lieu des seuls flux vidéo et audio - bien que l'entrée n'ait que deux flux en raison de votre commande précédente. Comme vous ne pouvez pas mettre à l'échelle sans ré-encodage, donc étant mutuellement exclusif avec -codec:v copy, et puisque votre entrée est déjà mise à l'échelle à la taille définie, j'ai supprimé les options de filtre.

S'il n'est toujours pas assez précis, essayez:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4

Ce sera plus lent, mais probablement plus précis. Voir les liens dans la réponse dans le premier lien que j'ai fourni pour une description des différences de ces deux exemples.

Enfin, vous devez exécuter source.mp4par qt-faststart(situé dans le répertoire des outils source ffmpeg), ou utilisez l' -movflags faststartoption. Cela déplacera certaines données au début du fichier afin qu'il puisse commencer la lecture avant qu'il ne soit complètement téléchargé.

llogan
la source
+1 pour les conseils, mais j'ai essayé ffmpeg -i source.mp4 -ss 577.92 -t 011.980 -c copy -map 0 clip1.mp4 mais la première partie (presque une seconde) et la dernière partie (peut-être un quart de seconde) de la la vidéo est manquée, mais l'audio est bien.
Pete Oakey
@PeteOakey Avez-vous essayé de couper sans copie bitstream, mais un ré-encodage réel?
slhck
Je l'ai essayé sans copie bitstream - résultats annexés à ma question.
Pete Oakey
3
L'utilisation -ssde l'option de sortie au lieu de l'option d'entrée a résolu mon problème: la première image vidéo était d'environ 1 s dans la vidéo de sortie, avec uniquement de l'audio avant cela (également confirmé par ffprobe -show_frames). Le déplacement -ssaprès l'a -ifait sortir des images audio et vidéo à partir de l'image 0.
CodeManX