Trimming videos using AngularJS

Playing video within the browser has become a fairly painless experience using the html5 video player. But there are many challenges as you add complexity to the controls. One of these is how you could set in and out points.

Here we will look at a way to trim videos using the angular-slider library and AngularJS.

First off we need to start an Angular app with a directive to handle our custom video player:

<div class="app" ng-app="app">
    <player class="player"></player>
</div>

Next we will create the AngularJS app class and the directive to hold our custom player code:

angular.module('app', [])

    .directive('player', function () {
        'use strict';
        return {
            restrict: 'E',
            template: '<div></div>'
            link: function (scope, element, attrs) {
                console.log('link');
            }
        };
    });

Next we want to update the template to container the video player and slider html:

template: '<div class="wide"><video autoplay controls><source ng-src="http://mirror.cessen.com/blender.org/peach/trailer/trailer_iphone.m4v" type="video/mp4" /></video></div>' +
            '<slider floor="0" ceiling="100" step="1" ng-model="currentPercent" change="onSliderChange()"></slider>' +
            '<slider floor="0" ceiling="{{ duration }}" step="0.1" precision="10" ng-model-low="start" ng-model-high="end" change="onTrimChange()"></slider>' + 
            '<p>start = {{ start }}</p><p>current = {{ current }}</p><p>end = {{ end }}</p>'

To render the custom sliders we need to include the ui-slider code from:
https://github.com/PopSugar/angular-slider

You will need to include the library as a dependancy to the app class with:

angular.module('app', ['ui-slider'])

In addition to this we will also add css to handle responsive widescreen video aspect ratio:

.player .wide {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
}
 
.player .wide video {
    background-color: #000;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

Lastly we will add some custom directive functions to calculate the slider events. So as sliders are moved, the correct values are calculated. This code is put within the directive link function:

link: function (scope, element, attrs) {
    var interval = 0,
        video = element.find('video');
    
    video.on('loadeddata', function (e) {
        scope.$apply(function () {
            scope.start = 0;
            scope.end = e.target.duration;
            scope.current = scope.start;
            scope.currentPercent = scope.start;
            scope.duration = scope.end;
        });
    });
    
    video.on('timeupdate', function (e) {
        scope.$apply(function () {
            scope.current = (e.target.currentTime - scope.start);
            scope.currentPercent = (scope.current / (scope.end - scope.start)) * 100;
            if (e.target.currentTime < scope.start) {
                e.target.currentTime = scope.start;
            }
            if (e.target.currentTime > scope.end) {
                if (video[0].paused === false) {
                    e.target.pause();
                } else {
                    e.target.currentTime = scope.start;
                }
            }
        });
    });
   
    scope.onTrimChange = function () {
        video[0].pause();
    };
    
    scope.onSliderChange = function () {
        video[0].pause();
        if (interval) {
            window.clearInterval(interval);
        }
        interval = window.setTimeout(function () {
            video[0].currentTime = scope.start + ((scope.currentPercent / 100 ) * (scope.end - scope.start));
        }, 300);
    };
    
    scope.$watch('start', function (num) {
        if (num !== undefined) {
            video[0].currentTime = num;
        }
    });
    scope.$watch('end', function (num) {
        if (num !== undefined) {
            video[0].currentTime = num;
        }
    });
},

Now you should have a working range slider, which will update the video start and end times. I've created a working example here:



https://jsfiddle.net/kmturley/odprs5rp/5/

No comments:

Post a Comment