Éditer un clip vidéo
Cet article explique comment à partir d'une vidéo filtrée avec un canevas obtenir l'effet équivalent dans un clip et coder l'édition des paramètres du clip.
Voir le Manuel du programmeur.
Cliquez dans la vidéo pour en démarrer la lecture. Cliquez de nouveau pour mettre la lecture en pause, la relancer.
- <div style="display:inline-flex;align-items:start;background:black">
- <video width="854" height="480" preload="auto" muted>
- <source src="/files/videos/Horloge.webm" type="video/webm" />
- </video>
- </div>
- const hflip=false, vflip=false;
- const scale=0.5;
- var video = document.querySelector('video');
- video.style.display = 'none';
- var canvas;
- video.onloadedmetadata = function() {
- canvas = document.createElement('canvas');
- canvas.width=Math.floor(video.width*scale);
- canvas.height=Math.floor(video.height*scale);
- canvas.style.cursor = 'pointer';
- var ctx = canvas.getContext('2d');
- ctx.setTransform(hflip ? -scale : scale, 0, 0, vflip ? -scale : scale, hflip ? canvas.width : 0, vflip ? canvas.height : 0);
- ctx.filter = 'sepia(1)';
- video.after(canvas);
- const keyframes = [ {transform: 'scale(1)'}, {transform: 'scale(0.8)'}, {transform: 'scale(1)'}];
- const timing = { duration: 10000, iterations: Infinity };
- canvas.animation = canvas.animate(keyframes, timing);
- canvas.animation.pause();
- function streamvideo() {
- if (video.paused || video.ended)
- return false;
- ctx.drawImage(video, 0, 0);
- requestAnimationFrame(streamvideo);
- };
- video.onplay = function() {
- canvas.animation.play();
- streamvideo();
- };
- video.onpause = function() {
- canvas.animation.pause();
- };
- video.onseeked = function() {
- canvas.animation.currentTime = video.currentTime*1000;
- ctx.drawImage(video, 0, 0);
- };
- video.seek = function(ms) {
- video.currentTime = ms / 1000;
- };
- video.onloadeddata = function() {
- ctx.drawImage(video, 0, 0);
- }
- canvas.onclick = function() {
- if (video.paused)
- video.play();
- else
- video.pause();
- };
- };
Clip
Cliquez dans la vidéo pour en démarrer la lecture. Cliquez de nouveau pour mettre la lecture en pause, la relancer.
- <?php $src='/files/videos/Horloge.webm'; ?>
- <?php $type='video/webm'; ?>
- <?php $width=854; ?>
- <?php $height=480; ?>
Configure l'URL de la vidéo, son type et sa taille.
- <?php $id=uniqid('id'); ?>
Définit l'identifiant de la <div>
qui encadre le HTML de l'interface.
- .test_display {
- display: inline-flex;
- flex-direction: column;
- align-items: flex-start;
- background: black;
- }
Configure le CSS de l'affichage de la vidéo.
- <div id="<?php echo $id; ?>" class="noprint">
- <div class="test_display">
- <video width="<?php echo $width; ?>" height="<?php echo $height; ?>" preload="auto">
- <source src="<?php echo $src; ?>" type="<?php echo $type; ?>" />
- </video>
- </div>
- </div>
Affiche la vidéo.
- <?php head('javascript', '/objectivejs/Objective.js'); ?>
- <?php head('javascript', '/objectivejs/Responder.js'); ?>
- <?php head('javascript', '/objectivejs/View.js'); ?>
- <?php head('javascript', '/objectivejs/Clip.js'); ?>
- <?php head('javascript', '/objectivejs/VideoClip.js'); ?>
- <?php head('javascript', '/objectivejs/DrawingArea.js'); ?>
Inclut le code de toutes les classes nécessaires.
RAPPEL : La fonction head de la librairie iZend ajoute une balise telle que <script src="/objectivejs/Objective.js"></script>
à la section <head>
du document HTML. Adaptez le code à votre environnement de développement.
- const clip = new VideoClip();
- const container = document.querySelector('#<?php echo $id; ?>');
- clip.setManagedWidget(container.querySelector('video'));
Crée le clip.
Récupère la <div>
qui encadre le HTML du programme.
Configure l'interface du clip.
- const keyframes = [ {transform: 'scale(1)'}, {transform: 'scale(0.8)'}, {transform: 'scale(1)'}];
- const timing = { duration: 10000, iterations: Infinity };
- clip.animate([[keyframes, timing]]);
Configure et programme l'animation du clip, i.e. l'effet de contraction.
- clip.dimension = [640, 360];
Redimensionne le clip.
- clip.enablePlayer();
Active les contrôles au clavier et à la souris du clip.
- Responder
- View
- Clip
- VideoClip
- Clip
- View
- Model
- ClipModel
- VideoModel
- ClipModel
Éditeur
Déplacez le pointeur de la souris sur la vidéo. Cliquez dans la vidéo ou appuyez sur la barre d'espace pour en démarrer la lecture. Cliquez ou appuyez sur la barre d'espace pour la mettre en pause, la relancer. Utilisez les flèches droite et gauche pour avancer ou reculer d'une seconde, appuyez en même temps sur la touche Maj ou la touche Ctrl pour avancer ou reculer de dix secondes ou de cent millisecondes. Appuyez sur la touche 0 pour revenir au début. Appuyez sur la touche plus pour accélérer la lecture, sur la touche moins pour la ralentir, sur la touche astérisque pour revenir à la vitesse normale.
Activez le son.
Modifiez la largeur ou la hauteur de la vidéo en pixels. NOTE : L'éditeur préserve la rapport d'affichage et ajuste automatiquement l'autre dimension. Inversez l'affichage dans le sens horizontal ou vertical. Essayez un effet grisé ou un effet sépia. Floutez l'affichage. Modifiez le contraste, la luminosité, la saturation, la teinte de la vidéo.
Essayez les boutons Défaire et Refaire.
Rechargez la page. Les modifications sont enregistrées.
Voir Architecture d'un éditeur.
- <?php $debug=false; ?>
Mettre $debug
à true
permet d'accéder dans la console du navigateur à tous les composants de l'interface.
Si $debug
vaut false
, tout le code en JavaScript est protégé par une fonction de fermeture.
- <?php $editor=true; ?>
- <?php $player=true; ?>
Mettre $editor
à true
affiche l'éditeur du clip.
Mettre $player
à true
active les contrôles du clip.
Essayez de mettre chaque option à false
.
- <?php $clipname='horloge'; ?>
Définit le nom du modèle qui définit le nom du cookie qui enregistre les données du modèle.
- <?php $src='/files/videos/Horloge.webm'; ?>
- <?php $type='video/webm'; ?>
- <?php $width=854; ?>
- <?php $height=480; ?>
Configure l'URL de la vidéo, son type et sa taille.
- <?php head('javascript', 'js.cookie.js'); ?>
Ajoute la balise <script src="/js/js.cookie.js"/>
à la section <head>
du document HTML.
RAPPEL : La fonction head est fournie par iZend.
Adaptez le code à votre environnement de développement.
- <?php $id=uniqid('id'); ?>
Définit l'identifiant de la <div>
qui encadre le HTML de l'interface.
- <div id="<?php echo $id; ?>" class="clip">
- <div class="ojs">
- <div>
- <div class="ojs_undo">
- <button type="submit" class="ojs_button narrow control_undo" disabled><i class="fas fa-undo"></i></button>
- <button type="submit" class="ojs_button narrow control_redo" disabled><i class="fas fa-redo"></i></button>
- </div>
- <span class="ojs_dimension">
- <input class="ojs_width" type="number" min="120"/> <i class="fas fa-arrows-alt-h small"></i>
- <input class="ojs_height" type="number" min="10"/> <i class="fas fa-arrows-alt-v small"></i>
- </span>
- </div>
- <div>
- <span><input id="<?php echo $id; ?>_video_hflip" type="checkbox" /><label for="<?php echo $id; ?>_video_hflip"><i class="fas fa-ellipsis-h small"></i></label></span>
- <span><input id="<?php echo $id; ?>_video_vflip" type="checkbox" /><label for="<?php echo $id; ?>_video_vflip"><i class="fas fa-ellipsis-v small"></i></label></span>
- <span><input id="<?php echo $id; ?>_video_grayscale" type="checkbox" /><label for="<?php echo $id; ?>_video_grayscale" class="grayscale"> </label></span>
- <span><input id="<?php echo $id; ?>_video_sepia" type="checkbox" /><label for="<?php echo $id; ?>_video_sepia" class="sepia"> </label></span>
- <span><input id="<?php echo $id; ?>_video_blur" type="checkbox" /><label for="<?php echo $id; ?>_video_blur"><i class="fas fa-brush small"></i></label></span>
- </div>
- <div>
- <span><i class="fas fa-adjust fa-fw small"></i> <input id="<?php echo $id; ?>_video_contrast" type="range" min="0" max="2" step="0.05"/> <output for="<?php echo $id; ?>_video_contrast">1.0</output></span>
- <span><i class="fas fa-fill-drip fa-fw small"></i> <input id="<?php echo $id; ?>_video_saturate" type="range" min="0" max="2" step="0.05"/> <output for="<?php echo $id; ?>_video_saturate">1.0</output></span>
- </div>
- <div>
- <span><i class="fas fa-sun fa-fw small"></i> <input id="<?php echo $id; ?>_video_brightness" type="range" min="0" max="2" step="0.05"/> <output for="<?php echo $id; ?>_video_brightness">1.0</output></span>
- <span><i class="fas fa-tint-slash fa-fw small"></i> <input id="<?php echo $id; ?>_video_invert" type="range" min="0" max="1" step="0.05"/> <output for="<?php echo $id; ?>_video_invert">1.0</output></span>
- </div>
- <div>
- <output id="<?php echo $id; ?>_video_time">00:00:00</output>
- <span><input id="<?php echo $id; ?>_video_muted" type="checkbox" /><label for="<?php echo $id; ?>_video_muted"><i class="fas fa-volume-mute"></i></label></span>
- </div>
- </div>
- <div class="ojs_video">
- <video width="<?php echo $width; ?>" height="<?php echo $height; ?>" preload="auto" muted>
- <source src="<?php echo $src; ?>" type="<?php echo $type; ?>" />
- </video>
- </div>
- <?php head('javascript', '/objectivejs/Objective.js'); ?>
- <?php head('javascript', '/objectivejs/Responder.js'); ?>
- <?php head('javascript', '/objectivejs/View.js'); ?>
- <?php head('javascript', '/objectivejs/Clip.js'); ?>
- <?php head('javascript', '/objectivejs/Model.js'); ?>
- <?php head('javascript', '/objectivejs/Validator.js'); ?>
- <?php if ($editor): ?>
- <?php head('javascript', '/objectivejs/Editor.js'); ?>
- <?php head('javascript', '/objectivejs/Inspector.js'); ?>
- <?php head('javascript', '/objectivejs/BooleanInspector.js'); ?>
- <?php head('javascript', '/objectivejs/NumberInspector.js'); ?>
- <?php head('javascript', '/objectivejs/StringInspector.js'); ?>
- <?php head('javascript', '/objectivejs/SelectInspector.js'); ?>
- <?php head('javascript', '/objectivejs/DimensionInspector.js'); ?>
- <?php head('javascript', '/objectivejs/RangeInspector.js'); ?>
- <?php head('javascript', '/objectivejs/Undo.js'); ?>
- <?php head('javascript', '/objectivejs/Panel.js'); ?>
- <?php head('javascript', '/objectivejs/UndoPanel.js'); ?>
- <?php else: ?>
- <?php head('javascript', '/objectivejs/ClipController.js'); ?>
- <?php endif; ?>
- <?php head('javascript', '/objectivejs/DrawingArea.js'); ?>
- <?php head('javascript', '/objectivejs/ClipModel.js'); ?>
- <?php head('javascript', '/objectivejs/VideoModel.js'); ?>
- <?php head('javascript', '/objectivejs/VideoClip.js'); ?>
- <?php head('javascript', '/objectivejs/ModelCookieDelegate.js'); ?>
- <?php if (!$debug): ?>
- (function() {
- <?php endif; ?>
Isole tout le code en JavaScript dans une fonction de fermeture si $debug
vaut false
.
- const clip = new VideoClip();
- const model = new VideoModel('<?php echo $clipname; ?>');
- const container = document.querySelector('#<?php echo $id; ?>');
- clip.setManagedWidget(container.querySelector('video'));
- clip.set(model.get());
- clip.enablePlayer();
- clip.addTimeWidget(container.querySelector('#<?php echo $id; ?>_video_time'));
- clip.addMutedWidget(container.querySelector('#<?php echo $id; ?>_video_muted'));
- const panel = new UndoPanel();
- panel.setManagedWidget(container.querySelector('.ojs_undo')).resetWidget();
- const size = model.getValue('size');
- const sizeInspector = new DimensionInspector(size[0], size[1], {minWidth: VideoModel.minWidth, maxWidth: VideoModel.maxWidth, minHeight: VideoModel.minHeight, maxHeight: VideoModel.maxHeight});
- sizeInspector.setManagedWidget(container.querySelector('.ojs_dimension')).resetWidget();
- const hflipInspector = new BooleanInspector(model.getValue('hflip'));
- hflipInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_hflip')).resetWidget();
- const vflipInspector = new BooleanInspector(model.getValue('vflip'));
- vflipInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_vflip')).resetWidget();
- const sepiaInspector = new BooleanInspector(model.getValue('sepia'));
- sepiaInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_sepia')).resetWidget();
- const grayscaleInspector = new BooleanInspector(model.getValue('grayscale'));
- grayscaleInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_grayscale')).resetWidget();
- const blurInspector = new BooleanInspector(model.getValue('blur'));
- blurInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_blur')).resetWidget();
- const contrastInspector = new RangeInspector(model.getValue('contrast'), {min: VideoModel.minContrast, max: VideoModel.maxContrast, fixed: 2});
- contrastInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_contrast')).resetWidget();
- const saturateInspector = new RangeInspector(model.getValue('saturate'), {min: VideoModel.minSaturate, max: VideoModel.maxSaturate, fixed: 2});
- saturateInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_saturate')).resetWidget();
- const brightnessInspector = new RangeInspector(model.getValue('brightness'), {min: VideoModel.minBrightness, max: VideoModel.maxBrightness, fixed: 2});
- brightnessInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_brightness')).resetWidget();
- const invertInspector = new RangeInspector(model.getValue('invert'), {min: VideoModel.minOpacity, max: VideoModel.maxOpacity, fixed: 2});
- invertInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_invert')).resetWidget();
- const inspectors = {
- size: sizeInspector,
- hflip: hflipInspector,
- vflip: vflipInspector,
- invert: invertInspector,
- contrast: contrastInspector,
- saturate: saturateInspector,
- brightness: brightnessInspector,
- grayscale: grayscaleInspector,
- sepia: sepiaInspector,
- blur: blurInspector
- };
- const editor = new Editor(model, clip, inspectors, panel);
- const controller = new ClipController(clip, model);
- model.setDelegate(new ModelCookieDelegate());
- model.readIn();
- model.enableSync(1000);
- <?php if (!$debug): ?>
- })();
- <?php endif; ?>
- </script>
Ferme la fonction qui isole le code en JavaScript si $debug
vaut false
.
Un clip peut toujours être converti en une vidéo.
Cliquez dans la vidéo pour la démarrer. Cliquez de nouveau pour la mettre en pause.
VOIR AUSSI
Objective, Model, Video, Clip, VideoClip, DrawingArea, Inspector, ModelCookieDelegate, Editor, Architecture d'un éditeur, Éditer un clip animé, Éditer un clip programmé, Écrire des données sur un serveur
Commentaires