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)">&lt;</a>' +
            '<a ng-click="toggle()"> <span ng-show="!playing">&#9654;</span><span ng-show="playing">&#9616;&#9616;</span> </a>' +
            '<a ng-click="frame(0.04)">&gt;</a>' +
            '</div>'
    };
}]);

module.controller('DemoCtrl', function ($scope) {

});