I\'m new with AngularJS. I must create customs controls for a video player (HTML5 ).
Basically, I would use
getElementById(\'myvideotag\')
I also used videojs
bower install videojs --save
I wanted to use my directive in a ng-repeat
and with a scope object, so... here's my version of it with props to Eduard above. I didn't seem to have a problem with the video player disposal, but the source tag issue referenced was an actual problem.
I also decided to write this up as an answer, so that I could give an example of how one might want to handle the videojs events.
IMPORTANT! Please note I am using Angular.js with Jinja2 templates, so I had to change my Angular HTML interpolation markers to {[ ]}
from {{ }}
in case anyone notices that as weird. I'll include that code too, so it's not weird for anyone.
Interpolation tweak
app.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('{[');
$interpolateProvider.endSymbol(']}');
}]);
Directive
angular.module('myModule').directive('uiVideo', function () {
// Function for logging videojs events, possibly to server
function playLog(player, videoId, action, logToDb) {
action = action || 'view';
var time = player.currentTime().toFixed(3);
if (logToDb) {
// Implement your own server logging here
}
// Paused
if (player.paused()) {
console.log('playLog: ', action + " at " + time + " " + videoId);
// Playing
} else {
console.log('playLog: ', action + ", while playing at " + time + " " + videoId);
if (action === 'play') {
var wrapFn = function () {
playLog(player, videoId, action, logToDb);
};
setTimeout(wrapFn, 1000);
}
}
}
return {
template: [
'<div class="video">',
'<video id="video-{[ video.id ]}" class="video-js vjs-default-skin img-responsive" controls preload="none"',
' ng-src="{[ video.mp4 ]}"',
' poster="{[ video.jpg ]}"',
' width="240" height="120">',
'</video>',
'</div>'
].join(''),
scope: {
video: '=video',
logToDb: '=logToDb'
},
link: function (scope, element, attrs) {
scope.logToDb = scope.logToDb || false;
var videoEl = element[0].children[0].children[0];
var vp = videojs(videoEl, {},
function(){
this.on("firstplay", function(){
playLog(vp, scope.video.id, 'firstplay', scope.logToDb);
});
this.on("play", function(){
playLog(vp, scope.video.id, 'play', scope.logToDb);
});
this.on("pause", function(){
playLog(vp, scope.video.id, 'pause', scope.logToDb);
});
this.on("seeking", function(){
playLog(vp, scope.video.id, 'seeking', scope.logToDb);
});
this.on("seeked", function(){
playLog(vp, scope.video.id, 'seeked', scope.logToDb);
});
this.on("ended", function(){
playLog(vp, scope.video.id, 'ended', scope.logToDb);
});
}
);
}
};
});
Directive HTML usage
<div ng-repeat="row in videos">
<ui-video video="row"></ui-video>
</div>
You could also take a look to my project Videogular.
https://github.com/2fdevs/videogular
It's a video player written in AngularJS, so you will have all the benefits of bindings and scope variables. Also you could write your own themes and plugins.
For full control, like behaviour and look&feel, I'm using videoJS
in angular.
I have a ui-video
directive that wraps the video
HTML5 element. This is necessary to overcome a problem of integration with AngularJS:
m.directive('uiVideo', function () {
var vp; // video player object to overcome one of the angularjs issues in #1352 (https://github.com/angular/angular.js/issues/1352). when the videojs player is removed from the dom, the player object is not destroyed and can't be reused.
var videoId = Math.floor((Math.random() * 1000) + 100); // in random we trust. you can use a hash of the video uri
return {
template: '<div class="video">' +
'<video ng-src="{{ properties.src }}" id="video-' + videoId + '" class="video-js vjs-default-skin" controls preload="auto" >' +
//'<source type="video/mp4"> '+ /* seems not yet supported in angular */
'Your browser does not support the video tag. ' +
'</video></div>',
link: function (scope, element, attrs) {
scope.properties = 'whatever url';
if (vp) vp.dispose();
vp = videojs('video-' + videoId, {width: 640, height: 480 });
}
};
});
How about this:
In your HTML, set ng-click="video($event)"
(don't forget the $event
argument), which calls the following function:
$scope.video = function(e) {
var videoElements = angular.element(e.srcElement);
videoElements[0].pause();
}
I believe this is the simplest method.
Documentation for angular.element
Also, this might help you get used to Angular: How do I “think in AngularJS/EmberJS(or other client MVC framework)” if I have a jQuery background?