iMovie (pas sans perte, mais mieux qu'avant)
iMovie v10 (publié quelque temps après que la question ait été posée à l'origine) gère désormais mieux un plus grand nombre de types de médias, ce qui évite la import re-encode pour la plupart des contenus H.264 (mp4, m4v, mov, AVHDC, mts, mt2s).
Cependant, il réencode toujours lors de l'exportation et ne peut donc pas être techniquement sans perte. Une autre nouveauté est la possibilité de personnaliser la qualité d'exportation, qui peut être plus proche du sans perte. Je pense que cette partie de la réponse peut également s'appliquer à d'autres logiciels d'édition vidéo "orientés projet" (par exemple Premiere ou Final Cut), car je pense qu'ils réencodent généralement à la sortie, mais sont généralement très faciles à utiliser pour un découpage précis.
Personnellement, je pense généralement qu'un seul réencodage n'est pas un énorme problème, mais je comprends que vous avez spécifiquement demandé une solution sans perte, donc...
Sans perte (mais beaucoup plus compliqué !)
Il existe des limitations techniques quant à la précision avec laquelle vous pouvez couper une vidéo sans avoir à en réencoder au moins une partie, et cela dépend essentiellement de la fréquence des i-frames. Si chaque image est une i-frame, vous pouvez couper n'importe où, mais si elles ne sont que toutes les quelques secondes, vous ne pouvez couper sans perte qu'à ces i-frames sans perdre de contenu ou devoir ré-encoder (au moins une partie du flux) pour qu'il puisse commencer avec une i-frame.
ffmpeg
Ce SO Q&A pose spécifiquement la question de savoir comment couper entre les i-frames en utilisant ffmpeg
. Je ne connais pas d'application GUI pour faire cela, mais en gros, vous exécutez une commande comme la suivante :
ffmpeg -i input.m4v -vcodec copy -acodec copy -ss 00:01:20.000 -t 00:37:50.000 output.m4v
Les deux moments indiqués sont commencer y durée et peut être spécifié en secondes ou en hh:mm:ss.ss
et le -acodec copy
y -vcodec copy
dites à ffmpeg de ne pas ré-encoder.
Je ne sais pas exactement ce qui se passe si on coupe trop tôt, mais je pensez à la vidéo est essentiellement vide (ou peut-être corrompue, selon le lecteur) jusqu'à ce qu'elle rencontre une i-frame. Vous voudrez donc probablement trouver l'i-frame la plus proche avant de couper. Cette réponse résout ce problème en utilisant ffprobe
y awk
bien qu'un peu maladroitement. Essentiellement, vous utilisez ffprobe
pour balayer les images et trouver l'image clé la plus proche ( flags=K
) avant votre point de coupure idéal. La sortie complète pour chaque image de la vidéo peut être vue comme ceci :
ffprobe -select_streams v -show_frames <INPUT>
La réponse liée fournit cette commande pour trouver une image clé avant un temps spécifique :
ffprobe -select_streams v -show_frames -v quiet INPUT.mp4 |
awk -F= '
/pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } }
/pkt_pts_time/ { if (i && ($2 >= 150)) print $2; }
' | head -n 1
Enfin, si vous avez vraiment besoin de couper quelque part entre deux i-frames, vous pouvez diviser la vidéo et la ré-assembler. Sur la base de la Informations tirées de cette réponse il devrait être quelque chose comme :
ffmpeg -f concat -i list_of_videos.txt -c copy OUTPUT.mp4
Où list_of_videos.txt
est un simple fichier texte listant les fichiers que vous voulez concaténer.
Résumé
iMovie est probablement assez bon pour la plupart des cas (depuis la v10), et très facile.
ffmpeg peut le faire sans perte (ou presque sans perte), avec un peu de manipulation ; le niveau de difficulté dépend de votre degré d'exigence concernant le point de départ précis et la fréquence des i-frames.