From a1f3994a1849dbd1b5157adf8c16e6e72ca5736e Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sun, 26 Jun 2016 18:08:07 -0400 Subject: updated videogular to 1.4.4 Former-commit-id: 7348ef0ae60746ce86cd4e813cf10e8b53e723d7 --- www/lib/videogular/.bower.json | 15 +-- www/lib/videogular/bower.json | 2 +- www/lib/videogular/index.js | 2 +- www/lib/videogular/package.json | 6 +- www/lib/videogular/videogular.js | 242 ++++++++++++++++++++++++++--------- www/lib/videogular/videogular.min.js | 2 +- 6 files changed, 198 insertions(+), 71 deletions(-) (limited to 'www/lib/videogular') diff --git a/www/lib/videogular/.bower.json b/www/lib/videogular/.bower.json index f105cfd7..2246d623 100644 --- a/www/lib/videogular/.bower.json +++ b/www/lib/videogular/.bower.json @@ -1,20 +1,19 @@ { "name": "videogular", - "version": "1.3.2", + "version": "1.4.4", "main": "./videogular.js", "dependencies": { "angular": "^1.3.x", "angular-sanitize": "^1.3.x" }, "homepage": "https://github.com/2fdevs/bower-videogular", - "_release": "1.3.2", + "_release": "1.4.4", "_resolution": { "type": "version", - "tag": "v1.3.2", - "commit": "b0c01c91bd5277797d3a02e5546a5b31423cfeaa" + "tag": "v1.4.4", + "commit": "6075385b6f0e41ffa707cf2c1f0afd456ac45e69" }, - "_source": "git://github.com/2fdevs/bower-videogular.git", - "_target": "~1.3.2", - "_originalSource": "videogular", - "_direct": true + "_source": "https://github.com/2fdevs/bower-videogular.git", + "_target": "~1.4.4", + "_originalSource": "videogular" } \ No newline at end of file diff --git a/www/lib/videogular/bower.json b/www/lib/videogular/bower.json index c593e6c9..50cca3b7 100644 --- a/www/lib/videogular/bower.json +++ b/www/lib/videogular/bower.json @@ -1,6 +1,6 @@ { "name": "videogular", - "version": "1.3.2", + "version": "1.4.4", "main": "./videogular.js", "dependencies": { "angular": "^1.3.x", diff --git a/www/lib/videogular/index.js b/www/lib/videogular/index.js index 51945645..84d99a76 100644 --- a/www/lib/videogular/index.js +++ b/www/lib/videogular/index.js @@ -1,4 +1,4 @@ -require('angular'); +require('angular'); require('angular-sanitize'); require('./videogular'); diff --git a/www/lib/videogular/package.json b/www/lib/videogular/package.json index ee4603b7..9892ee30 100644 --- a/www/lib/videogular/package.json +++ b/www/lib/videogular/package.json @@ -1,7 +1,11 @@ { "name": "videogular", - "version": "1.3.2", + "version": "1.4.4", "main": "index.js", + "dependencies": { + "angular": "^1.3.0", + "angular-sanitize": "^1.3.0" + }, "devDependencies": { "grunt": "~0.4.1", "grunt-release": "~0.7.0" diff --git a/www/lib/videogular/videogular.js b/www/lib/videogular/videogular.js index 5685b076..1a29b398 100644 --- a/www/lib/videogular/videogular.js +++ b/www/lib/videogular/videogular.js @@ -1,5 +1,5 @@ /** - * @license videogular v1.3.2 http://videogular.com + * @license videogular v1.4.4 http://videogular.com * Two Fucking Developers http://twofuckingdevelopers.com * License: MIT */ @@ -78,13 +78,13 @@ angular.module("com.2fdevs.videogular") * - stop(): Stops media. * - playPause(): Toggles play and pause. * - seekTime(value, byPercent): Seeks to a specified time position. Param value must be an integer representing the target position in seconds or a percentage. By default seekTime seeks by seconds, if you want to seek by percentage just pass byPercent to true. - * - setVolume(volume): Sets volume. Param volume must be an integer with a value between 0 and 1. - * - setPlayback(playback): Sets playback. Param plaback must be an integer with a value between 0 and 2. + * - setVolume(volume): Sets volume. Param volume must be a float number with a value between 0 and 1. + * - setPlayback(playback): Sets playback. Param plaback must be a float number with a value between 0 and 2. * - setState(state): Sets a new state. Param state mus be an string with 'play', 'pause' or 'stop'. This method only changes the state of the player, but doesn't plays, pauses or stops the media file. * - toggleFullScreen(): Toggles between fullscreen and normal mode. * - updateTheme(css-url): Removes previous CSS theme and sets a new one. * - clearMedia(): Cleans the current media file. - * - changeSource(array): Updates current media source. Param `array` must be an array of media source objects. + * - changeSource(array): Updates current media source. Param `array` must be an array of media source objects or a simple URL string. * A media source is an object with two properties `src` and `type`. The `src` property must contains a trustful url resource. *
{src: $sce.trustAsResourceUrl("http://static.videogular.com/assets/videos/videogular.mp4"), type: "video/mp4"}
* @@ -98,7 +98,7 @@ angular.module("com.2fdevs.videogular") * - nativeFullscreen: Boolean value to know if Videogular if fullscreen mode will use native mode or emulated mode. * - mediaElement: Reference to video/audio object. * - videogularElement: Reference to videogular tag. - * - sources: Array with current sources. + * - sources: Array with current sources or a simple URL string. * - tracks: Array with current tracks. * - cuePoints: Object containing a list of timelines with cue points. Each property in the object represents a timeline, which is an Array of objects with the next definition: *
{
@@ -139,12 +139,28 @@ angular.module("com.2fdevs.videogular")
         var currentTheme = null;
         var isFullScreenPressed = false;
         var isMetaDataLoaded = false;
+        var hasStartTimePlayed = false;
+        var isVirtualClip = false;
 
         // PUBLIC $API
         this.videogularElement = null;
 
         this.clearMedia = function () {
             this.mediaElement[0].src = '';
+            this.mediaElement[0].removeEventListener("canplay", this.onCanPlay.bind(this), false);
+            this.mediaElement[0].removeEventListener("loadedmetadata", this.onLoadMetaData.bind(this), false);
+            this.mediaElement[0].removeEventListener("waiting", this.onStartBuffering.bind(this), false);
+            this.mediaElement[0].removeEventListener("ended", this.onComplete.bind(this), false);
+            this.mediaElement[0].removeEventListener("playing", this.onStartPlaying.bind(this), false);
+            this.mediaElement[0].removeEventListener("play", this.onPlay.bind(this), false);
+            this.mediaElement[0].removeEventListener("pause", this.onPause.bind(this), false);
+            this.mediaElement[0].removeEventListener("volumechange", this.onVolumeChange.bind(this), false);
+            this.mediaElement[0].removeEventListener("playbackchange", this.onPlaybackChange.bind(this), false);
+            this.mediaElement[0].removeEventListener("timeupdate", this.onUpdateTime.bind(this), false);
+            this.mediaElement[0].removeEventListener("progress", this.onProgress.bind(this), false);
+            this.mediaElement[0].removeEventListener("seeking", this.onSeeking.bind(this), false);
+            this.mediaElement[0].removeEventListener("seeked", this.onSeeked.bind(this), false);
+            this.mediaElement[0].removeEventListener("error", this.onVideoError.bind(this), false);
         };
 
         this.onRouteChange = function() {
@@ -155,7 +171,12 @@ angular.module("com.2fdevs.videogular")
 
         this.onCanPlay = function (evt) {
             this.isBuffering = false;
-            $scope.$apply($scope.vgCanPlay({$event: evt}));
+            $scope.$parent.$digest($scope.vgCanPlay({$event: evt}));
+
+            if (!hasStartTimePlayed && (this.startTime > 0 || this.startTime === 0)) {
+                this.seekTime(this.startTime);
+                hasStartTimePlayed = true;
+            }
         };
 
         this.onVideoReady = function () {
@@ -164,10 +185,13 @@ angular.module("com.2fdevs.videogular")
             this.playsInline = $scope.vgPlaysInline;
             this.nativeFullscreen = $scope.vgNativeFullscreen || true;
             this.cuePoints = $scope.vgCuePoints;
+            this.startTime = $scope.vgStartTime;
+            this.virtualClipDuration = $scope.vgVirtualClipDuration;
             this.clearMediaOnNavigate = $scope.vgClearMediaOnNavigate || true;
             this.currentState = VG_STATES.STOP;
 
             isMetaDataLoaded = true;
+            isVirtualClip = this.startTime >= 0 && this.virtualClipDuration > 0;
 
             //Set media volume from localStorage if available
             if (VG_UTILS.supportsLocalStorage()) {
@@ -194,6 +218,9 @@ angular.module("com.2fdevs.videogular")
             $scope.vgNativeFullscreen = this.config.nativeFullscreen;
             $scope.vgCuePoints = this.config.cuePoints;
             $scope.vgClearMediaOnNavigate = this.config.clearMediaOnNavigate;
+            $scope.vgStartTime = this.config.startTime;
+            $scope.vgVirtualClipDuration = this.config.virtualClipDuration;
+            isVirtualClip = $scope.vgStartTime >= 0 && $scope.vgVirtualClipDuration > 0;
 
             $scope.vgPlayerReady({$API: this});
         };
@@ -204,39 +231,65 @@ angular.module("com.2fdevs.videogular")
         };
 
         this.onProgress = function (event) {
+            this.updateBuffer(event);
+
+            $scope.$parent.$digest();
+        };
+
+        this.updateBuffer = function getBuffer(event) {
             if (event.target.buffered.length) {
                 this.buffered = event.target.buffered;
                 this.bufferEnd = 1000 * event.target.buffered.end(event.target.buffered.length - 1);
-            }
 
-            $scope.$apply();
+                // Avoid bufferEnd overflow by virtual clips
+                if (this.bufferEnd > this.totalTime) this.bufferEnd = this.totalTime;
+            }
         };
 
         this.onUpdateTime = function (event) {
-            this.currentTime = 1000 * event.target.currentTime;
+            var targetTime = 1000 * event.target.currentTime;
 
-            if (event.target.buffered.length) {
-                this.buffered = event.target.buffered;
-                this.bufferEnd = 1000 * event.target.buffered.end(event.target.buffered.length - 1);
-            }
+            this.updateBuffer(event);
+
+            if (event.target.duration != Infinity && event.target.duration != null && event.target.duration != undefined && event.target.duration != 1.7976931348623157e+308) {
+                // Fake the duration and current time for virtual clips
+                if (isVirtualClip) {
+                    if (hasStartTimePlayed && (event.target.currentTime < this.startTime || event.target.currentTime - this.startTime > this.virtualClipDuration)) {
+                        this.onComplete();
+                    }
+                    else {
+                        this.currentTime = Math.max(0, targetTime - (1000 * this.startTime));
+                        this.totalTime = 1000 * this.virtualClipDuration;
+                        this.timeLeft = (1000 * this.virtualClipDuration) - this.currentTime;
+                    }
+                }
+                else {
+                    this.currentTime = targetTime;
+                    this.totalTime = 1000 * event.target.duration;
+                    this.timeLeft = 1000 * (event.target.duration - event.target.currentTime);
+                }
 
-            if (event.target.duration != Infinity) {
-                this.totalTime = 1000 * event.target.duration;
-                this.timeLeft = 1000 * (event.target.duration - event.target.currentTime);
                 this.isLive = false;
             }
             else {
                 // It's a live streaming without and end
+                this.currentTime = targetTime;
                 this.isLive = true;
             }
 
+            var targetSeconds = isVirtualClip ? this.currentTime / 1000 : event.target.currentTime;
+            var targetDuration = isVirtualClip ? this.totalTime / 1000 : event.target.duration;
+
             if (this.cuePoints) {
-                this.checkCuePoints(event.target.currentTime);
+                this.checkCuePoints(targetSeconds);
             }
 
-            $scope.vgUpdateTime({$currentTime: event.target.currentTime, $duration: event.target.duration});
+            $scope.vgUpdateTime({$currentTime: targetSeconds, $duration: targetDuration});
 
-            $scope.$apply();
+            // Safe apply just in case we're calling from a non-event
+            if ($scope.$$phase != '$apply' && $scope.$$phase != '$digest') {
+                $scope.$parent.$digest();
+            }
         };
 
         this.checkCuePoints = function checkCuePoints(currentTime) {
@@ -293,28 +346,30 @@ angular.module("com.2fdevs.videogular")
 
         this.onPlay = function () {
             this.setState(VG_STATES.PLAY);
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onPause = function () {
-            if (this.mediaElement[0].currentTime == 0) {
+            var currentTime = isVirtualClip ? this.currentTime : this.mediaElement[0].currentTime;
+
+            if (currentTime == 0) {
                 this.setState(VG_STATES.STOP);
             }
             else {
                 this.setState(VG_STATES.PAUSE);
             }
 
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onVolumeChange = function () {
             this.volume = this.mediaElement[0].volume;
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onPlaybackChange = function () {
             this.playback = this.mediaElement[0].playbackRate;
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onSeeking = function (event) {
@@ -328,12 +383,26 @@ angular.module("com.2fdevs.videogular")
         this.seekTime = function (value, byPercent) {
             var second;
             if (byPercent) {
-                second = value * this.mediaElement[0].duration / 100;
-                this.mediaElement[0].currentTime = second;
+                if (isVirtualClip) {
+                    value = Math.max(0, Math.min(value, 100));
+                    second = (value * this.virtualClipDuration / 100);
+                    this.mediaElement[0].currentTime = this.startTime + second;
+                }
+                else {
+                    second = value * this.mediaElement[0].duration / 100;
+                    this.mediaElement[0].currentTime = second;
+                }
             }
             else {
-                second = value;
-                this.mediaElement[0].currentTime = second;
+                if (isVirtualClip) {
+                    var durationPercent = value/this.mediaElement[0].duration;
+                    second = !hasStartTimePlayed ? 0 : this.virtualClipDuration * durationPercent;
+                    this.mediaElement[0].currentTime = !hasStartTimePlayed ? this.startTime : this.startTime + second;
+                }
+                else {
+                    second = value;
+                    this.mediaElement[0].currentTime = second;
+                }
             }
 
             this.currentTime = 1000 * second;
@@ -371,9 +440,11 @@ angular.module("com.2fdevs.videogular")
         this.stop = function () {
             try {
                 this.mediaElement[0].pause();
-                this.mediaElement[0].currentTime = 0;
 
-                this.currentTime = 0;
+                var targetTime = isVirtualClip ? this.startTime : 0;
+                this.mediaElement[0].currentTime = targetTime;
+
+                this.currentTime = targetTime;
                 this.buffered = [];
                 this.bufferEnd = 0;
                 this.setState(VG_STATES.STOP);
@@ -494,12 +565,12 @@ angular.module("com.2fdevs.videogular")
 
         this.onStartBuffering = function (event) {
             this.isBuffering = true;
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onStartPlaying = function (event) {
             this.isBuffering = false;
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         this.onComplete = function (event) {
@@ -507,7 +578,12 @@ angular.module("com.2fdevs.videogular")
 
             this.setState(VG_STATES.STOP);
             this.isCompleted = true;
-            $scope.$apply();
+
+            if (isVirtualClip) {
+                this.stop()
+            }
+
+            $scope.$parent.$digest();
         };
 
         this.onVideoError = function (event) {
@@ -543,6 +619,7 @@ angular.module("com.2fdevs.videogular")
             this.isFullScreen = false;
             this.playback = 1;
             this.isConfig = ($scope.vgConfig != undefined);
+            this.mediaElement = [{play:function(){}, pause:function(){}, stop:function(){}, addEventListener:function(){}, removeEventListener: function(){}}];
 
             if (vgFullscreen.isAvailable) {
                 this.isFullScreen = vgFullscreen.isFullScreen();
@@ -567,6 +644,31 @@ angular.module("com.2fdevs.videogular")
             }
         };
 
+        this.onUpdateStartTime = function onUpdateStartTime(newValue) {
+            if (newValue && (newValue != this.startTime)) {
+                this.mediaElement[0].currentTime = newValue;
+                this.startTime = newValue;
+                isVirtualClip = this.startTime >= 0 && this.virtualClipDuration > 0;
+
+                var fakeEvent = {
+                    target: this.mediaElement[0]
+                };
+                this.onUpdateTime(fakeEvent, true);
+            }
+        };
+
+        this.onUpdateVirtualClipDuration = function onUpdateVirtualClipDuration(newValue) {
+            if (newValue && (newValue != this.virtualClipDuration)) {
+                this.virtualClipDuration = newValue;
+                isVirtualClip = this.startTime >= 0 && this.virtualClipDuration > 0;
+
+                var fakeEvent = {
+                    target: this.mediaElement[0]
+                };
+                this.onUpdateTime(fakeEvent, true);
+            }
+        };
+
         this.onUpdatePlaysInline = function onUpdatePlaysInline(newValue) {
             this.playsInline = newValue;
         };
@@ -591,6 +693,10 @@ angular.module("com.2fdevs.videogular")
 
             $scope.$watch("vgAutoPlay", this.onUpdateAutoPlay.bind(this));
 
+            $scope.$watch("vgStartTime", this.onUpdateStartTime.bind(this));
+
+            $scope.$watch("vgVirtualClipDuration", this.onUpdateVirtualClipDuration.bind(this));
+
             $scope.$watch("vgPlaysInline", this.onUpdatePlaysInline.bind(this));
 
             $scope.$watch("vgNativeFullscreen", this.onUpdateNativeFullscreen.bind(this));
@@ -602,7 +708,7 @@ angular.module("com.2fdevs.videogular")
 
         this.onFullScreenChange = function (event) {
             this.isFullScreen = vgFullscreen.isFullScreen();
-            $scope.$apply();
+            $scope.$parent.$digest();
         };
 
         // Empty mediaElement on destroy to avoid that Chrome downloads video even when it's not present
@@ -738,7 +844,7 @@ angular.module("com.2fdevs.videogular")
  * @description
  * Directive to add a source of videos or audios. This directive will create a <video> or <audio> tag and usually will be above plugin tags.
  *
- * @param {array} vgSrc Bindable array with a list of media sources. A media source is an object with two properties `src` and `type`. The `src` property must contains a trustful url resource.
+ * @param {array} vgSrc Bindable array with a list of media sources or a simple url string. A media source is an object with two properties `src` and `type`. The `src` property must contains a trustful url resource.
  * @param {string} vgType String with "video" or "audio" values to set a