273

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. };
Clip

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

  1. <?php $src='/files/videos/Horloge.webm'; ?>
  2. <?php $type='video/webm'; ?>
  3. <?php $width=854; ?>
  4. <?php $height=480; ?>

Configures the URL of the video, its type and its size.

  1. <?php $id=uniqid('id'); ?>

Defines the identifier of the <div> which surrounds the HTML of the interface.

  1. .test_display {
  2.     display: inline-flex;
  3.     flex-direction: column;
  4.     align-items: flex-start;
  5.     background: black;
  6. }

Configures the CSS of the display of the video.

  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="test_display">
  3. <video width="<?php echo $width; ?>" height="<?php echo $height; ?>" preload="auto">
  4. <source src="<?php echo $src; ?>" type="<?php echo $type; ?>" />
  5. </video>
  6. </div>
  7. </div>

Displays the video.

  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/VideoClip.js'); ?>
  6. <?php head('javascript', '/objectivejs/DrawingArea.js'); ?>

Includes the code of all the necessary classes. REMINDER: The function head of the iZend library adds a tag such as <script src="/objectivejs/Objective.js"></script> to the <head> section of the document in HTML. Adapt the code to your development environment.

  1. const clip = new VideoClip();
  2.  
  3. const container = document.querySelector('#<?php echo $id; ?>');
  4.  
  5. clip.setManagedWidget(container.querySelector('video'));

Creates the clip. Retrieves the <div> which surrounds the HTML of the program. Configures the interface of the clip.

  1. const keyframes = [ {transform: 'scale(1)'}, {transform: 'scale(0.8)'}, {transform: 'scale(1)'}];
  2. const timing = { duration: 10000, iterations: Infinity };
  3.  
  4. clip.animate([[keyframes, timing]]);

Configures and programs the animation of the clip, i.e. the shrink effect.

  1. clip.dimension = [640, 360];

Resizes the clip.

  1. clip.enablePlayer();

Enables the keyboard and the mouse controls of the clip.

Objective
  • Responder
    • View
      • Clip
        • VideoClip

VideoClip

Objective
  • Model
    • ClipModel
      • VideoModel

VideoModel

Editor
   
  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; ?>

Setting $debug to true gives access in the console of the navigator to all the components of the interface. If $debug is false, all the code in JavaScript is protected by a closure function.

  1. <?php $editor=true; ?>
  2. <?php $player=true; ?>

Setting $editor to true displays the editor of the clip. Setting $player to true activates the controls of the clip. Try setting each option to false.

  1. <?php $clipname='horloge'; ?>

Defines the name of the model which defines the name of the cookie which records the data of the model.

  1. <?php $src='/files/videos/Horloge.webm'; ?>
  2. <?php $type='video/webm'; ?>
  3. <?php $width=854; ?>
  4. <?php $height=480; ?>

Configures the URL of the video, its type and its size.

  1. <?php head('javascript', 'js.cookie.js'); ?>

Adds the tag <script src="/js/js.cookie.js"></script> to the <head> section of the document in HTML. REMINDER: The function head is provided by iZend. Adapt the code to your development environment.

  1. <?php $id=uniqid('id'); ?>

Defines the identifier of the <div> which surrounds the HTML of the interface.

  1. <div id="<?php echo $id; ?>" class="clip">
  1. <div class="ojs">
  2. <div>
  3. <div class="ojs_undo">
  4. <button type="submit" class="ojs_button narrow control_undo" disabled><i class="fas fa-undo"></i></button>
  5. <button type="submit" class="ojs_button narrow control_redo" disabled><i class="fas fa-redo"></i></button>
  6. </div>
  7. <span class="ojs_dimension">
  8. <input class="ojs_width" type="number" min="120"/>&nbsp;<i class="fas fa-arrows-alt-h small"></i>
  9. <input class="ojs_height" type="number" min="10"/>&nbsp;<i class="fas 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="fas 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="fas 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="fas fa-brush small"></i></label></span>
  18. </div>
  19. <div>
  20. <span><i class="fas 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="fas 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="fas 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="fas 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="fas 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.

A clip can always be converted into a video.

Click in the video to start it. Click again to pause it.

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].