1

Editing a video clip

This article explains how to obtain from a video filtered with a canvas the equivalent effect in a clip and how editing the clip parameters is coded.

See the Programmer's manual.

Click in the video to start playing it. Click again to pause it, continue to play it.

  1. <div style="display:inline-flex;align-items:start;background:black">
  2. <video width="854" height="480" preload="auto" muted>
  3. <source src="/files/videos/Horloge.webm" type="video/webm" />
  4. </video>
  5. </div>
  1. <script>
  2. const hflip=false, vflip=false;
  3. const scale=0.5;
  4.  
  5. var video = document.querySelector('video');
  6.  
  7. video.style.display = 'none';
  8.  
  9. var canvas;
  1. video.onloadedmetadata = function() {
  2.     canvas = document.createElement('canvas');
  3.  
  4.     canvas.width=Math.floor(video.width*scale);
  5.     canvas.height=Math.floor(video.height*scale);
  6.  
  7.     canvas.style.cursor = 'pointer';
  8.  
  9.     var ctx = canvas.getContext('2d');
  10.  
  11.     ctx.setTransform(hflip ? -scale : scale, 0, 0, vflip ? -scale : scale, hflip ? canvas.width : 0, vflip ? canvas.height : 0);
  12.  
  13.     ctx.filter = 'sepia(1)';
  14.  
  15.     video.after(canvas);
  16.  
  17.     const keyframes = [ {transform: 'scale(1)'}, {transform: 'scale(0.8)'}, {transform: 'scale(1)'}];
  18.     const timing = { duration: 10000, iterations: Infinity };
  19.  
  20.     canvas.animation = canvas.animate(keyframes, timing);
  21.  
  22.     canvas.animation.pause();
  23.  
  24.     function streamvideo() {
  25.         if (video.paused || video.ended)
  26.             return false;
  27.  
  28.         ctx.drawImage(video, 0, 0);
  29.  
  30.         requestAnimationFrame(streamvideo);
  31.     };
  32.  
  33.     video.onplay = function() {
  34.         canvas.animation.play();
  35.         streamvideo();
  36.     };
  37.  
  38.     video.onpause = function() {
  39.         canvas.animation.pause();
  40.     };
  41.  
  42.     video.onseeked = function() {
  43.         canvas.animation.currentTime = video.currentTime*1000;
  44.         ctx.drawImage(video, 0, 0);
  45.     };
  46.  
  47.     video.seek = function(ms) {
  48.         video.currentTime = ms / 1000;
  49.     };
  50.  
  51.     video.onloadeddata = function() {
  52.         ctx.drawImage(video, 0, 0);
  53.     }
  54.  
  55.     canvas.onclick = function() {
  56.         if (video.paused)
  57.             video.play();
  58.         else
  59.             video.pause();
  60.     };
  61. };

Click in the video to start playing it. Click again to pause it, continue to play it.

VideoClip

Objective
  • Responder
    • View
      • Clip
        • VideoClip

VideoModel

Objective
  • Model
    • ClipModel
      • VideoModel
   
  1.0   1.0
  1.0   1.0
00:00:00

Move the pointer of the mouse over the video. Click in the video or press the space bar to start playing it. Click or press the space bar to pause it, to continue to play it. Use the right and left arrows to move forward or backward by one second, press the Shift key or the Ctrl key at the same time to move forward or backward by ten seconds or a hundred milliseconds. Press the 0 key to come back to the beginning. Press the plus key to play the video faster, the minus key to play it slower, the asterisk key to come back to the normal speed.

Activate the sound.

Modify the width or the height of the video in pixels. NOTE: The editor preserves the aspect ratio of the display and adjusts the other dimension automatically. Invert the display horizontally or vertically. Try a grayscale or a sepia effect. Blur the display. Modify the contrast, the brightness, the saturation, the tint of the video.

Try the Undo and Redo buttons.

Reload the page. The modifications are saved.

See Architecture of an editor.

  1. <?php $debug=false; ?>
  1. <?php $editor=true; ?>
  2. <?php $player=true; ?>
  1. <?php $clipname='horloge'; ?>
  1. <?php $src='/files/videos/Horloge.webm'; ?>
  2. <?php $type='video/webm'; ?>
  3. <?php $width=854; ?>
  4. <?php $height=480; ?>
  1. <?php head('javascript', 'jquery.cookie'); ?>
  1. <?php $id=uniqid('id'); ?>
  1. <div id="<?php echo $id; ?>" class="clip">
  1. <div class="ojs">
  2. <div>
  3. <div class="ojs_undo">
  4. <button type="submit" class="narrow control_undo" disabled><i class="fa fa-undo"></i></button>
  5. <button type="submit" class="narrow control_redo" disabled><i class="fa fa-redo"></i></button>
  6. </div>
  7. <span class="ojs_dimension">
  8. <input class="ojs_width" type="number" min="120"/>&nbsp;<i class="fa fa-arrows-alt-h small"></i>
  9. <input class="ojs_height" type="number" min="10"/>&nbsp;<i class="fa fa-arrows-alt-v small"></i>
  10. </span>
  11. </div>
  12. <div>
  13. <span><input id="<?php echo $id; ?>_video_hflip" type="checkbox" /><label for="<?php echo $id; ?>_video_hflip"><i class="fa fa-ellipsis-h small"></i></label></span>
  14. <span><input id="<?php echo $id; ?>_video_vflip" type="checkbox" /><label for="<?php echo $id; ?>_video_vflip"><i class="fa fa-ellipsis-v small"></i></label></span>
  15. <span><input id="<?php echo $id; ?>_video_grayscale" type="checkbox" /><label for="<?php echo $id; ?>_video_grayscale" class="grayscale">&nbsp;</label></span>
  16. <span><input id="<?php echo $id; ?>_video_sepia" type="checkbox" /><label for="<?php echo $id; ?>_video_sepia" class="sepia">&nbsp;</label></span>
  17. <span><input id="<?php echo $id; ?>_video_blur" type="checkbox" /><label for="<?php echo $id; ?>_video_blur"><i class="fa fa-brush small"></i></label></span>
  18. </div>
  19. <div>
  20. <span><i class="fa fa-adjust fa-fw small"></i>&nbsp;<input id="<?php echo $id; ?>_video_contrast" type="range" min="0" max="2" step="0.05"/>&nbsp;<output for="<?php echo $id; ?>_video_contrast">1.0</output></span>
  21. <span><i class="fa fa-fill-drip fa-fw small"></i>&nbsp;<input id="<?php echo $id; ?>_video_saturate" type="range" min="0" max="2" step="0.05"/>&nbsp;<output for="<?php echo $id; ?>_video_saturate">1.0</output></span>
  22. </div>
  23. <div>
  24. <span><i class="fa fa-sun fa-fw small"></i>&nbsp;<input id="<?php echo $id; ?>_video_brightness" type="range" min="0" max="2" step="0.05"/>&nbsp;<output for="<?php echo $id; ?>_video_brightness">1.0</output></span>
  25. <span><i class="fa fa-tint-slash fa-fw small"></i>&nbsp;<input id="<?php echo $id; ?>_video_invert" type="range" min="0" max="1" step="0.05"/>&nbsp;<output for="<?php echo $id; ?>_video_invert">1.0</output></span>
  26. </div>
  27. <div>
  28. <output id="<?php echo $id; ?>_video_time">00:00:00</output>
  29. <span><input id="<?php echo $id; ?>_video_muted" type="checkbox" /><label for="<?php echo $id; ?>_video_muted"><i class="fa fa-volume-mute"></i></label></span>
  30. </div>
  31. </div>
  1. <div class="ojs_video">
  1. <video width="<?php echo $width; ?>" height="<?php echo $height; ?>" preload="auto" muted>
  2. <source src="<?php echo $src; ?>" type="<?php echo $type; ?>" />
  3. </video>
  1. </div>
  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  3. <?php head('javascript', '/objectivejs/View.js'); ?>
  4. <?php head('javascript', '/objectivejs/Clip.js'); ?>
  5. <?php head('javascript', '/objectivejs/Model.js'); ?>
  6. <?php head('javascript', '/objectivejs/Validator.js'); ?>
  7. <?php if ($editor): ?>
  8. <?php head('javascript', '/objectivejs/Editor.js'); ?>
  9. <?php head('javascript', '/objectivejs/Inspector.js'); ?>
  10. <?php head('javascript', '/objectivejs/BooleanInspector.js'); ?>
  11. <?php head('javascript', '/objectivejs/NumberInspector.js'); ?>
  12. <?php head('javascript', '/objectivejs/StringInspector.js'); ?>
  13. <?php head('javascript', '/objectivejs/SelectInspector.js'); ?>
  14. <?php head('javascript', '/objectivejs/DimensionInspector.js'); ?>
  15. <?php head('javascript', '/objectivejs/RangeInspector.js'); ?>
  16. <?php head('javascript', '/objectivejs/Undo.js'); ?>
  17. <?php head('javascript', '/objectivejs/Panel.js'); ?>
  18. <?php head('javascript', '/objectivejs/UndoPanel.js'); ?>
  19. <?php else: ?>
  20. <?php head('javascript', '/objectivejs/ClipController.js'); ?>
  21. <?php endif; ?>
  22. <?php head('javascript', '/objectivejs/DrawingArea.js'); ?>
  23. <?php head('javascript', '/objectivejs/ClipModel.js'); ?>
  24. <?php head('javascript', '/objectivejs/VideoModel.js'); ?>
  25. <?php head('javascript', '/objectivejs/VideoClip.js'); ?>
  26. <?php head('javascript', '/objectivejs/ModelCookieDelegate.js'); ?>
  1. <?php if (!$debug): ?>
  2. (function() {
  3. <?php endif; ?>

Isolates all the code in JavaScript in a closure function if $debug is false.

  1.     const clip = new VideoClip();
  2.  
  3.     const model = new VideoModel('<?php echo $clipname; ?>');
  4.  
  5.     const container = document.querySelector('#<?php echo $id; ?>');
  6.  
  7.     clip.setManagedWidget(container.querySelector('video'));
  8.  
  9.     clip.set(model.get());
  1.     clip.enablePlayer();
  1.     clip.addTimeWidget(container.querySelector('#<?php echo $id; ?>_video_time'));
  2.     clip.addMutedWidget(container.querySelector('#<?php echo $id; ?>_video_muted'));
  3.  
  4.     const panel = new UndoPanel();
  5.  
  6.     panel.setManagedWidget(container.querySelector('.ojs_undo')).resetWidget();
  7.  
  8.     const size = model.getValue('size');
  9.  
  10.     const sizeInspector = new DimensionInspector(size[0], size[1], {minWidth: VideoModel.minWidth, maxWidth: VideoModel.maxWidth, minHeight: VideoModel.minHeight, maxHeight: VideoModel.maxHeight});
  11.  
  12.     sizeInspector.setManagedWidget(container.querySelector('.ojs_dimension')).resetWidget();
  13.  
  14.     const hflipInspector = new BooleanInspector(model.getValue('hflip'));
  15.  
  16.     hflipInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_hflip')).resetWidget();
  17.  
  18.     const vflipInspector = new BooleanInspector(model.getValue('vflip'));
  19.  
  20.     vflipInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_vflip')).resetWidget();
  21.  
  22.     const sepiaInspector = new BooleanInspector(model.getValue('sepia'));
  23.  
  24.     sepiaInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_sepia')).resetWidget();
  25.  
  26.     const grayscaleInspector = new BooleanInspector(model.getValue('grayscale'));
  27.  
  28.     grayscaleInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_grayscale')).resetWidget();
  29.  
  30.     const blurInspector = new BooleanInspector(model.getValue('blur'));
  31.  
  32.     blurInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_blur')).resetWidget();
  33.  
  34.     const contrastInspector = new RangeInspector(model.getValue('contrast'), {min: VideoModel.minContrast, max: VideoModel.maxContrast, fixed: 2});
  35.  
  36.     contrastInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_contrast')).resetWidget();
  37.  
  38.     const saturateInspector = new RangeInspector(model.getValue('saturate'), {min: VideoModel.minSaturate, max: VideoModel.maxSaturate, fixed: 2});
  39.  
  40.     saturateInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_saturate')).resetWidget();
  41.  
  42.     const brightnessInspector = new RangeInspector(model.getValue('brightness'), {min: VideoModel.minBrightness, max: VideoModel.maxBrightness, fixed: 2});
  43.  
  44.     brightnessInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_brightness')).resetWidget();
  45.  
  46.     const invertInspector = new RangeInspector(model.getValue('invert'), {min: VideoModel.minOpacity, max: VideoModel.maxOpacity, fixed: 2});
  47.  
  48.     invertInspector.setManagedWidget(container.querySelector('#<?php echo $id; ?>_video_invert')).resetWidget();
  49.  
  50.     const inspectors = {
  51.         size:       sizeInspector,
  52.         hflip:      hflipInspector,
  53.         vflip:      vflipInspector,
  54.         invert:     invertInspector,
  55.         contrast:   contrastInspector,
  56.         saturate:   saturateInspector,
  57.         brightness: brightnessInspector,
  58.         grayscale:  grayscaleInspector,
  59.         sepia:      sepiaInspector,
  60.         blur:       blurInspector
  61.     };
  62.  
  63.     const editor = new Editor(model, clip, inspectors, panel);
  1.     const controller = new ClipController(clip, model);
  1.     model.setDelegate(new ModelCookieDelegate());
  2.     model.readIn();
  3.     model.enableSync(1000);
  1. <?php if (!$debug): ?>
  2. })();
  3. <?php endif; ?>
  4. </script>

Closes the function which isolates the code in JavaScript if $debug is false.

SEE ALSO

Objective, Model, Video, Clip, VideoClip, DrawingArea, Inspector, ModelCookieDelegate, Editor, Architecture of an editor, Editing an animated clip, Editing a programmed clip, Write data on a server

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].