Skip to content

Instantly share code, notes, and snippets.

@djvs
Last active August 12, 2021 06:31
Show Gist options
  • Save djvs/24006c975ff11fd889e3 to your computer and use it in GitHub Desktop.
Save djvs/24006c975ff11fd889e3 to your computer and use it in GitHub Desktop.
AngularJS (Angular) HTML5 Audio Player directive from scratch

Write your own HTML5 Audio/AngularJS audio player

example

I tried AudioJS, JPlayer, and a couple of the angular directives. Somehow they all sucked! And yet the HTML5 audio API was totally open and in theory should work fine with Angular. Time to get my hands dirty as usual....

Javascript:

app.directive('aplayer',function($interval) {
    return {
        restrict:'A',
        scope: {
            audobj: '='
        },
        templateUrl: '/partial/audioplayer', 
        link: function($scope, element, attrs){
        },
        controller: function($scope){
            if(typeof $scope.audobj == "string"){
              log("init audio");
              $scope.audio = new Audio();
              $scope.audio.src = $scope.audobj;
              $scope.vol = 0.6;
              $scope.audio.volume = 0.6;
            }
            $scope.play = function(){
                $scope.audio.play();
            };
            $scope.pause = function(){
                $scope.audio.pause();
            };
            $interval(function(){
                $scope.ctime = $scope.audio.currentTime.toFixed(1);
            },100);
            $scope.$watch('audio.duration', function(newval){
                $scope.duration = $scope.audio.duration.toFixed(1);
            });
            $scope.changetime = function(t){
                $scope.audio.currentTime = $scope.ctime;
            };
            $scope.changevol = function(t){
                $scope.audio.volume = $scope.vol;
            };
            $scope.ntot = function(secs) {
              var hr  = Math.floor(secs / 3600);
              var min = Math.floor((secs - (hr * 3600))/60);
              var sec = Math.floor(secs - (hr * 3600) -  (min * 60));
              if (min < 10){ 
                min = "0" + min; 
              }
              if (sec < 10){ 
                sec  = "0" + sec;
              }
              return min + ':' + sec;
            }
        }
    };
});

CSS:

$border:rgba(192,192,192,1);
.audiowrap{
    margin:5px 0;
    border:solid 1px $border;
    border-radius:3px;
    width:100%;
    overflow:auto;
    background-color:#efefef;
    > button{
       float:left; 
    }
    .time{
        float:right;
        background-color:white;
        color:black;
        text-align:center;
        font-size:0.8em;
        padding:2px 5px;
    }
    .rangewrap{
        background-color:white;
        border-right:solid 1px $border;
        border-left:solid 1px $border;
        padding:0 6px;
        overflow:hidden;
        input{
            width:100%;
        }
    }
    .volwrap{
        background-color:white;
        border-right:solid 1px $border;
        float:right;
        padding:0 6px;
        width:100px; 
        overflow:auto;
        .wrap2{
          overflow:hidden;
          input{
          }
        }
        img{
          float:left;
          height:19px;
        }
    }
}

HTML (must be accessible at /partial/audioplayer, otherwise change the code up above):

<div class="audiowrap">
  <button class="btn btn-xs btn-default" ng-click="play()">
    <span class="glyphicon glyphicon-play"></span>
  </button>
  <button class="btn btn-xs btn-default" ng-click="pause()">
    <span class="glyphicon glyphicon-pause"></span>
  </button>
  <div class="time">{{ ctime }} / {{ duration }}</div>
  <div class="volwrap">
    <img src="/img/vol/0.png" ng-if="vol == 0.0">
    <img src="/img/vol/33.png" ng-if="vol > 0.0 && vol <= 0.33">
    <img src="/img/vol/66.png" ng-if="vol > 0.33 && vol <= 0.66">
    <img src="/img/vol/100.png" ng-if="vol > 0.66">
    <div class="wrap2">
      <input type="range" min="0.0" max="1.0" step="0.05" ng-model="vol" ng-change="changevol()">
    </div>
  </div>
  <div class="rangewrap">
    <input type="range" min="0.0" max="{{ duration }}" step="0.1" ng-model="ctime" ng-change="changetime()">
  </div>
</div>

and to actually use the directive:

  <div aplayer="showobj.url"></div>

Jesus, so easy right?

Audio volume image assets (you'll need these too, though you can use your own):

0.png 0.png

33.png 33.png

66.png 66.png

100.png 100.png

@acaballero-en
Copy link

This was very helpful, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment