JSFiddle - React, Tailwind, and code Playground
AngularJS Video Player - Example directive showing a video player and controls
by dledle2
HTML
<script src="//kmturley.github.io/angular-bootstrap/app/libs/angular-ui/angular-ui-bootstrap.min.js"></script>
<body ng-app="app" ng-controller='DemoCtrl'>
<player videos='[{"type":"application/x-mpegURL","src":"http://tvemsnbc-lh.akamaihd.net/i/nbcmsnbc_1@122532/index_796_av-p.m3u8?sd=10&rebase=on" } ]' />
</body>
CSS
body {
margin: 0;
}
/* player */
.player video {
max-width: 100%;
display: block;
}
.player .progress {
border-radius: 0;
margin: 0 0 5px 0;
height: 10px;
}
.player .progress-bar {
background-color: #9e0b0f;
}
.player .controls {
text-align: center;
font-size: 2em;
}
.player .controls a {
color: #777;
cursor: pointer;
color: #000;
font-size: 1em;
margin: 0 10px;
}
.player .controls a:hover {
color: #555;
}
.player .controls .glyphicon {
vertical-align: middle;
}
/* progress */
.progress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
}
.progress-bar {
float: left;
width: 0;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #fff;
text-align: center;
background-color: #428bca;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
}
.progress.active .progress-bar, .progress-bar.active {
-webkit-animation: progress-bar-stripes 2s linear infinite;
-o-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
.progress-bar[aria-valuenow="1"], .progress-bar[aria-valuenow="2"] {
min-width: 30px;
}
.progress-bar[aria-valuenow="0"] {
min-width: 30px;
color: #777;
background-color: transparent;
background-image: none;
-webkit-box-shadow: none;
box-shadow: none;
}
JavaScript
var module = angular.module('app', []);
module.directive('player', ['$sce', function ($sce) {
'use strict';
return {
restrict: 'E',
scope: {
videos: '='
},
link: function (scope, element, attrs) {
var video = element.find('video');
element.addClass('player');
scope.playing = false;
scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
}
video.on('timeupdate', function (e) {
scope.$apply(function () {
scope.percent = (video[0].currentTime / video[0].duration) * 100;
});
});
scope.frame = function (num) {
if (video[0].readyState !== 0) {
video[0].currentTime += num;
}
};
scope.toggle = function () {
if (video[0].paused === true) {
video[0].play();
scope.playing = true;
} else {
video[0].pause();
scope.playing = false;
}
};
},
template: '<video preload="none" poster="{{ trustSrc(videos[0].poster) }}">' +
'<source ng-repeat="item in videos" ng-src="{{ trustSrc(item.src) }}" type="video/{{ item.type }}" />' +
'<track kind="captions" ng-src="{{ trustSrc(videos[0].captions) }}" srclang="en" label="English" />' +
'</video>' +
'<progressbar value="percent" max="100"></progressbar>' +
'<div class="controls noselect">' +
'<a ng-click="frame(-0.04)"><</a>' +
'<a ng-click="toggle()"> <span ng-show="!playing">▶</span><span ng-show="playing">▐▐</span> </a>' +
'<a ng-click="frame(0.04)">></a>' +
'</div>'
};
}]);
module.controller('DemoCtrl', function ($scope) {
});