28

VideoClip

Objective
  • Responder
    • View
      • Clip
        • VideoClip

Déplacez le pointeur de la souris sur le clip. Cliquez dans le clip ou appuyez sur la barre d'espace pour en démarrer la lecture. Cliquez ou appuyez de nouveau sur la barre d'espace pour mettre la lecture 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.

NOTE : Un effet de contraction programmé sur le clip change les dimensions de l'affichage de la vidéo sur une période de 10 secondes.

Dans la console du navigateur, coupez le son :

clip.muted=true

Essayez différentes options d'affichage :

clip.options={ hflip: true, sepia: true }

Redimensionnez la vidéo :

clip.dimension=[480,270]
  1. function VideoClip() {
  2.     Clip.call(this);
  3.  
  4.     this._drawingarea = new DrawingArea();
  5.  
  6.     this._video = null;
  7.  
  8.     this._animlist = null;
  9.  
  10.     this._timeWidget = null;
  11.  
  12.     this._mutedWidget = null;
  13.  
  14.     this._onmute = null;
  15.  
  16.     this._streamvideo = null;
  17. }
  18.  
  19. VideoClip.prototype = Object.create(Clip.prototype);
  20.  
  21. Object.defineProperty(VideoClip.prototype, 'constructor', { value: VideoClip, enumerable: false, writable: true });
  22.  
  23. Object.defineProperty(VideoClip.prototype, 'dimension', {
  24.     get:    function() {
  25.         return this._drawingarea.size;
  26.     },
  27.     set:    function(d) {
  28.         this._drawingarea.size = d;
  29.     }
  30. });
  31.  
  32. Object.defineProperty(VideoClip.prototype, 'duration', {
  33.     get:    function() {
  34.         return this._video ? Math.floor(this._video.duration * 1000) : 0;
  35.     }
  36. });
  37.  
  38. Object.defineProperty(VideoClip.prototype, 'currentTime', {
  39.     get:    function() {
  40.         return this._video && this._video.currentTime > 0 ? Math.floor(this._video.currentTime * 1000) - 1 : 0;
  41.     }
  42. });
  43.  
  44. Object.defineProperty(VideoClip.prototype, 'playbackRate', {
  45.     get:    function() {
  46.         return this._playbackRate;
  47.     },
  48.     set:    function(r) {
  49.         if (typeof r !== 'number')
  50.             throw new TypeError();
  51.  
  52.         if (r < Clip.minPlaybackRate || r > Clip.maxPlaybackRate)
  53.             throw new RangeError();
  54.  
  55.         this._playbackRate = r;
  56.  
  57.         if (this._video)
  58.             this._video.playbackRate = r;
  59.  
  60.         if (this._animlist)
  61.             for (let e of this._animlist)
  62.                 e.playbackRate = r;
  63.     }
  64. });
  65.  
  66. Object.defineProperty(VideoClip.prototype, 'muted', {
  67.     get:    function() {
  68.         return this._video ? this._video.muted : false;
  69.     },
  70.     set:    function(muted) {
  71.         if (this._video) {
  72.             this._video.muted = muted ? true : false;
  73.  
  74.             if (this._mutedWidget)
  75.                 this._mutedWidget.checked = this._video.muted;
  76.         }
  77.     }
  78. });
  79.  
  80. Object.defineProperty(VideoClip.prototype, 'options', {
  81.     get:    function() {
  82.         return this._drawingarea.getOptions();
  83.     },
  84.     set:    function(options) {
  85.         this._drawingarea.setOptions(options);
  86.     }
  87. });
  88.  
  89. VideoClip.prototype.get = function() {
  90.     return this._drawingarea.getOptions();
  91. };
  92.  
  93. VideoClip.prototype.set = function(options) {
  94.     this._drawingarea.setOptions(options);
  95.  
  96.     return this;
  97. };
  98.  
  99. VideoClip.prototype.setValue = function(prop, val) {
  100.     if (prop == 'size')
  101.         this._drawingarea.size = val;
  102.     else if (prop == 'hflip')
  103.         this._drawingarea.hflip = val;
  104.     else if (prop == 'vflip')
  105.         this._drawingarea.vflip = val;
  106.     else if (prop == 'grayscale')
  107.         this._drawingarea.grayscale = val;
  108.     else if (prop == 'sepia')
  109.         this._drawingarea.sepia = val;
  110.     else if (prop == 'blur')
  111.         this._drawingarea.blur = val;
  112.     else if (prop == 'invert')
  113.         this._drawingarea.invert = val;
  114.     else if (prop == 'contrast')
  115.         this._drawingarea.contrast = val;
  116.     else if (prop == 'saturate')
  117.         this._drawingarea.saturate = val;
  118.     else if (prop == 'brightness')
  119.         this._drawingarea.brightness = val;
  120.     else if (prop == 'opacity')
  121.         this._drawingarea.opacity = val;
  122.  
  123.     return this;
  124. };
  125.  
  126. VideoClip.prototype.animate = function(animations) {
  127.     if (! (Array.isArray(animations) && animations.length > 0))
  128.         throw new TypeError();
  129.  
  130.     if (!this._widget)
  131.         return this;
  132.  
  133.     if (this._animlist)
  134.         for (let e of this._animlist)
  135.             e.cancel();
  136.  
  137.     const animlist = [];
  138.  
  139.     for (let e of animations) {
  140.         if (! (Array.isArray(e) && e.length == 2))
  141.             throw new TypeError();
  142.  
  143.         let [keyframes, options] = e;
  144.  
  145.         let anim = this._widget.animate(keyframes, options);
  146.  
  147.         anim.pause();
  148.  
  149.         animlist.push(anim);
  150.     }
  151.  
  152.     this._animlist = animlist;
  153.  
  154.     return this;
  155. };
  156.  
  157. VideoClip.prototype.seek = function(ms) {
  158.     if (!this._video)
  159.         return this;
  160.  
  161.     this._video.currentTime = (ms + 1) / 1000;  // +1 for Chrome
  162.  
  163.     if (this._animlist) {
  164.         for (let e of this._animlist) {
  165.             e.currentTime = ms;
  166.             if (this._paused)
  167.                 e.pause();
  168.         }
  169.     }
  170.  
  171.     return this;
  172. };
  173.  
  174. VideoClip.prototype.play = function() {
  175.     if (!this._video)
  176.         return this;
  177.  
  178.     if (this._ended)
  179.         this.seek(0);
  180.  
  181.     this._ended = this._paused = false;
  182.  
  183.     this._video.play();
  184.  
  185.     if (this._animlist) {
  186.         for (let e of this._animlist)
  187.             e.play();
  188.     }
  189.  
  190.     return this;
  191. };
  192.  
  193. VideoClip.prototype.pause = function() {
  194.     if (!this._video)
  195.         return this;
  196.  
  197.     this._paused = true;
  198.  
  199.     this._video.pause();
  200.  
  201.     if (this._animlist) {
  202.         for (let e of this._animlist)
  203.             e.pause();
  204.     }
  205.  
  206.     return this;
  207. };
  208.  
  209. VideoClip.prototype.setWidget = function(w) {
  210.     if (w.tagName != 'VIDEO')
  211.         throw new TypeError();
  212.  
  213.     this._drawingarea.setWidget(w);
  214.  
  215.     Clip.prototype.setWidget.call(this, this._drawingarea.widget);
  216.  
  217.     w.style.display = 'none';
  218.  
  219.     w.playbackRate = this._playbackRate;
  220.  
  221.     w.after(this._drawingarea.widget);
  222.  
  223.     this._video = w;
  224.  
  225.     w.onseeked = () => {
  226.         this._drawingarea.setImage(this._video);
  227.  
  228.         if (this._timeWidget)
  229.             this._timeWidget.innerText = VideoClip._toHHMMSS(this._video.currentTime);
  230.  
  231.         this.notify('clipSeeked', this);
  232.     };
  233.  
  234.     w.onended = () => {
  235.         this._ended = this._paused = true;
  236.  
  237.         if (this._animlist) {
  238.             for (let e of this._animlist)
  239.                 e.pause();
  240.         }
  241.  
  242.         this.notify('clipEnded', this);
  243.     };
  244.  
  245.     w.load();
  246.  
  247.     return this;
  248. };
  249.  
  250. VideoClip.prototype.addTimeWidget = function(w) {
  251.     w.innerText = VideoClip._toHHMMSS(this._video.currentTime);
  252.  
  253.     this._timeWidget = w;
  254.  
  255.     return this;
  256. };
  257.  
  258. VideoClip.prototype.removeTimeWidget = function() {
  259.     this._timeWidget = null;
  260.  
  261.     return this;
  262. };
  263.  
  264. VideoClip.prototype.addMutedWidget = function(w) {
  265.     if (this._onmute)
  266.         this.removeEventListener('change', this._onmute);
  267.  
  268.     this._onmute = () => this._video.muted = this._mutedWidget.checked;
  269.  
  270.     w.addEventListener('change', this._onmute);
  271.  
  272.     w.checked = this._video.muted;
  273.  
  274.     this._mutedWidget = w;
  275.  
  276.     return this;
  277. };
  278.  
  279. VideoClip.prototype.removeMutedWidget = function() {
  280.     if (this._onmute)
  281.         this.removeEventListener('change', this._onmute);
  282.  
  283.     this._mutedWidget = null;
  284.  
  285.     return this;
  286. };
  287.  
  288. VideoClip.prototype.enablePlayer = function() {
  289.     if (this.hasPlayer())
  290.         return this;
  291.  
  292.     Clip.prototype.enablePlayer.call(this);
  293.  
  294.     if (this._streamvideo === null) {
  295.         this._streamvideo = () => {
  296.             if (this._video.paused || this._video.ended)
  297.                 return;
  298.  
  299.             this._drawingarea.setImage(this._video);
  300.  
  301.             if (this._timeWidget)
  302.                 this._timeWidget.innerText = VideoClip._toHHMMSS(this._video.currentTime);
  303.  
  304.             requestAnimationFrame(this._streamvideo);
  305.         };
  306.  
  307.         this._video.onplay = this._streamvideo;
  308.     }
  309.  
  310.     return this;
  311. };
  312.  
  313. VideoClip._toHHMMSS = function(nsecs) {
  314.     nsecs = Math.floor(nsecs);
  315.  
  316.     let hh = Math.floor(nsecs / 3600);
  317.     let mm = Math.floor((nsecs - (hh * 3600)) / 60);
  318.     let ss = nsecs - (hh * 3600) - (mm * 60);
  319.  
  320.     hh = (hh < 10 ? '0' : '') + hh;
  321.     mm = (mm < 10 ? '0' : '') + mm;
  322.     ss = (ss < 10 ? '0' : '') + ss;
  323.  
  324.     return `${hh}:${mm}:${ss}`;
  325. };
Test
  1. <?php $src='/files/videos/Horloge.webm'; ?>
  2. <?php $type='video/webm'; ?>
  3. <?php $width=854; ?>
  4. <?php $height=480; ?>
  1. <?php $id=uniqid('id'); ?>
  1. .test_display {
  2.     display: inline-flex;
  3.     flex-direction: column;
  4.     align-items: flex-start;
  5.     background: black;
  6. }
  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>
  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'); ?>
  1. const clip = new VideoClip();
  2.  
  3. const container = document.querySelector('#<?php echo $id; ?>');
  4.  
  5. clip.setManagedWidget(container.querySelector('video'));
  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]]);
  1. clip.dimension = [640, 360];
  1. clip.enablePlayer();
VOIR AUSSI

Clip, AnimateClip, ProgramClip, DrawingArea, Éditer un clip vidéo

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[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]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].