123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /**
- * Created by intelWorx on 19/11/2015.
- */
- (function () {
- 'use strict';
- /**
- * Main module, your application should depend on this
- * @module {mdWavesurfer}
- */
- var app = angular.module('mdWavesurfer', ['ngMaterial']);
- /**
- * @ngdoc service
- * @name $mdWavesurferUtils
- *
- * @description
- *
- * Utility service for this directive, exposes method:
- * - getLength(url), which returns a promise for the length of the audio specified by URL
- *
- * ```js
- * app.directive('myFancyDirective', function(mdWavesurferUtils) {
- * return {
- * restrict: 'e',
- * link: function(scope, el, attrs) {
- * mdWavesurferUtils(attrs.url)
- * .then(function(l){
- * scope.length = l;
- * }, function(){
- * someErrorhandler()
- * })
- * ;
- * }
- * };
- * });
- * ```
- */
- app.factory('mdWavesurferUtils', ['$q', '$document', '$timeout',
- function ($q, $document, $timeout) {
- return {
- getLength: function (object) {
- var deferred = $q.defer();
- var estimateLength = function (url) {
- var audio = $document[0].createElement('audio');
- audio.src = url;
- audio.addEventListener('loadeddata', function listener() {
- deferred.resolve(this.duration);
- audio.removeEventListener('loadeddata', listener);
- audio.src = 'data:audio/mpeg,0';//destroy loading.
- });
- audio.addEventListener('error', function (e) {
- deferred.resolve(e.target.error);
- });
- };
- if (typeof object === 'string') {
- //this is a URL
- estimateLength(object);
- } else {
- $timeout(function () {
- deferred.reject(new DOMError("NotSupportedError", "Specified argument is not supported"));
- });
- }
- return deferred.promise;
- }
- };
- }
- ]);
- /**
- * @ngdoc filter
- * @name mdWavesurferTimeFormat
- *
- * Simple filter to convert value in seconds to MM:SS format
- *
- * @param Number duration in seconds
- */
- app.filter('mdWavesurferTimeFormat', function () {
- return function (input) {
- if (!input) {
- return "00:00";
- }
- var minutes = Math.floor(input / 60);
- var seconds = Math.ceil(input) % 60;
- return (minutes < 10 ? '0' : '')
- + minutes
- + ":"
- + (seconds < 10 ? '0' : '') + seconds;
- };
- });
- app.controller('mdWavesurferAudioController', ['$attrs', '$element',
- function (attributes, $element) {
- var audio = this;
- audio.tracks = [];
- audio.selectedIndex = audio.selectedIndex || 0;
- audio.currentTrack = null;
- //adds to an audio track
- audio.addTrack = function (trackScope) {
- if (audio.tracks.indexOf(trackScope) < 0) {
- audio.tracks.push(trackScope);
- }
- if (!audio.currentTrack) {
- audio.currentTrack = audio.tracks[audio.selectedIndex];
- }
- };
- //remove audio track
- audio.removeTrack = function (trackScope) {
- var idx = audio.tracks.indexOf(trackScope);
- if (idx >= 0) {
- audio.tracks.splice(idx, 1);
- }
- };
- audio.playerProperties = {}
- var nKey;
- for (var attr in attributes) {
- if (attr.match(/^player/)) {
- nKey = attr.replace(/^player([A-Z])/, function (m, $1) {
- return $1.toLowerCase();
- });
- audio.playerProperties[nKey] = attributes[attr];
- }
- }
- var getPlayer = function(){
- return $element.find('md-wavesurfer-player').controller('mdWavesurferPlayer');
- };
- var setAutoPlay = function (forcePlay) {
- var controller = getPlayer();
- if (controller && (forcePlay || controller.surfer.isPlaying())) {
- controller.autoPlay = true;
- }
- };
- audio.setTrack = function (idx, forcePlay) {
- if (audio.tracks.length > idx) {
- if (audio.selectedIndex === idx) {
- var ctrl = getPlayer();
- ctrl.surfer.playPause();
- } else {
- setAutoPlay(forcePlay);
- audio.currentTrack = audio.tracks[idx];
- audio.selectedIndex = idx;
- }
- }
- };
- audio.extraButtons = [{
- icon: 'zmdi zmdi-skip-previous',
- title: 'Previous',
- action: function ($event) {
- if (audio.selectedIndex > 0) {
- audio.setTrack(audio.selectedIndex - 1);
- }
- },
- class: ''
- }, {
- icon: 'zmdi zmdi-skip-next',
- title: 'Next',
- action: function ($event) {
- if (audio.selectedIndex < audio.tracks.length - 1) {
- audio.setTrack(audio.selectedIndex + 1);
- }
- },
- class: ''
- }];
- }
- ]);
- /**
- * @ngdoc directive
- * @name md-wavesurfer-audio
- *
- * Directive for playing a set of audio files. This directive is analogous to `<audio>` HTML tag.
- * The audio files, should be specified using the `md-wavesurfer-source`
- *
- * WaveSurfer properties can be passed in using the prefix : player-* for attributes, e.g. `player-wave-color` is
- * equivalent to WaveSurfer's waveColor option.
- *
- * Must be used as an element.
- *
- * @usage
- * ```html
- * <md-wavesurfer-audio player-wave-color="gray" player-progress-color="black" player-backend="MediaElement">
- * <md-wavesurfer-source src="source1" title="Title-1"></md-wavesurfer-source>
- * <md-wavesurfer-source src="source2" title="Title-2"></md-wavesurfer-source>
- * <md-wavesurfer-source src="source3" title="Title-3"></md-wavesurfer-source>
- * ...
- * <md-wavesurfer-source src="sourceN" title="Рассказы о сновидениях"></md-wavesurfer-source>
- * </md-wavesurfer-audio>
- * ```
- *
- * @param string player-* specifies WaveSurfer properties.
- *
- */
- app.directive('mdWavesurferAudio', [
- function () {
- return {
- restrict: 'E',
- templateUrl: 'md-player-audio.partial.html',
- transclude: true,
- controller: 'mdWavesurferAudioController',
- controllerAs: 'audio'
- };
- }
- ]);
- /**
- * @ngdoc directive
- *
- * @name md-wavesurfer-source
- *
- * This directive is used within the `md-wavesurfer-audio` directive to specify an audio file source, it is
- * synonymous to `<source>` tag in HTML
- *
- * The directive cannot be used as standalone.
- *
- * @usage
- *
- * ```html
- * <md-wavesurfer-source src="source3" title="Title-3" album-art="Album-Art-Url" duration=""></md-wavesurfer-source>
- * ```
- * @param String src the URL to the audio file, this is required.
- * @param String title track title
- * @param String album-art the album art URL
- * @param Number duration the length of the audio file in seconds, will be auto-detected if not specified.
- *
- */
- app.directive('mdWavesurferSource', ['mdWavesurferUtils',
- function (mdWavesurferUtils) {
- return {
- restrict: 'E',
- require: '^mdWavesurferAudio',
- scope: {
- src: '@',
- albumArt: '@',
- title: '@',
- duration: '='
- },
- link: function (scope, element, attrs, audio) {
- audio.addTrack(scope);
- if (!scope.duration) {
- mdWavesurferUtils.getLength(scope.src).then(function (dur) {
- scope.duration = dur;
- }, function (e) {
- scope.duration = 0;
- console.log('Failed to get audio length, reason: ', e.message);
- });
- }
- element.on('$destroy', function () {
- audio.removeTrack(audio);
- });
- }
- };
- }
- ]);
- app.controller('mdWavesurferPlayerController', ['$element', '$scope', '$attrs', '$interval', '$mdTheming',
- function ($element, $scope, attributes, $interval, $mdTheme) {
- var control = this, timeInterval;
- control.themeClass = "md-" + $mdTheme.defaultTheme() + "-theme";
- control.isReady = false;
- control.surfer = null;
- control.toggleMute = function () {
- if (control.surfer) {
- control.surfer.toggleMute();
- control.isMute = !control.isMute;
- }
- };
- var initWaveSurfer = function () {
- control.isReady = false;
- control.currentTime = 0;
- if (!control.surfer) {
- var options = {
- container: $element[0].querySelector('.waveSurferWave')
- }, defaults = {
- scrollParent: true,
- waveColor: 'violet',
- progressColor: 'purple'
- };
- options = angular.extend(defaults, attributes, (control.properties || {}), options);
- control.surfer = WaveSurfer.create(options);
- control.surfer.on('ready', function () {
- control.isReady = true;
- if (control.autoPlay) {
- control.surfer.play();
- }
- $scope.$apply();
- });
- control.surfer.on('pause', function () {
- stopInterval();
- });
- control.surfer.on('finish', function () {
- stopInterval();
- });
- control.surfer.on('play', function () {
- startInterval();
- });
- }
- control.title = control.title || control.src.split('/').pop();
- control.surfer.load(control.src);
- };
- var startInterval = function () {
- timeInterval = $interval(function () {
- control.currentTime = control.isReady ? control.surfer.getCurrentTime() : 0;
- }, 1000);
- }, stopInterval = function () {
- $interval.cancel(timeInterval);
- };
- initWaveSurfer();
- $scope.$watch('control.src', function (src1, src2) {
- if (src1 != src2) {
- initWaveSurfer();
- }
- });
- $element.on('$destroy', function () {
- if (control.surfer) {
- control.surfer.destroy();
- }
- stopInterval();
- });
- $scope.$watch(function () {
- var div = $element[0].querySelector('.audioPlayerWrapper');
- return div ? div.offsetWidth : 0;
- }, function (width) {
- if (width < 1) {
- //hidden
- control.surfer.pause();
- }
- });
- }
- ]);
- /**
- * @ngdoc directive
- *
- * @name md-wavesurfer-player
- *
- * @usage
- * This directive can be used as a stand-alone directive to display Audio WaveSurfer with a few controls, by default
- * this will only display play/pause, fast-forward, rewind and mute toggle buttons, however, you can add extra
- * buttons using the `extra-buttons` parameters.
- *
- * ```html
- * <md-wavesurfer-player url="trackUrl" title="Track Title"
- * extra-buttons="extraButtons" properties="properties">
- * </md-wavesurfer-player>
- * ```
- *
- * @param {string} url the URL of the audio file
- * @param {string} title title of the audio track
- * @param {object} properties an object specifying init options for WaveSurfer
- * @param {boolean} auto-play specifies if the player should start as soon as it's loaded.
- * @param {object[]} extra-buttons a list of extra buttons to add to the control panel
- * each button should be an object with the following properties:
- * {
- * title: "button title"
- * action: "call back to call when button is clicked, executed in parent scope",
- * icon: "md-font-icon parameter for the button"
- * class: "extra classes to add to the button."
- * }
- *
- * Every other attribute passed to this directive is assumed to a WaveSurver init parameter.
- */
- app.directive('mdWavesurferPlayer', function () {
- return {
- restrict: 'E',
- templateUrl: 'md-player.partial.html',
- scope: {
- src: '@url',
- title: '@',
- extraButtons: '=',
- toolbarClass: '@',
- autoPlay: '=',
- properties: '='
- },
- controller: 'mdWavesurferPlayerController',
- controllerAs: 'control',
- bindToController: true
- };
- });
- ;
- })();
|