I'm not sure if what I'm doing is allowed or possible but basically I have a simple audio player using the html5 audio element.
app.factory('audio', function($document) {
var audio = $document[0].createElement('audio');
return audio;
});
Then on my view, I have a range input for seeking
<input id="seek" type="range" min="0" ng-model="seek" ng-change="seeked()" max="{{max}}" value="{{seek}}">
On my controller, I have the following:
app.controller('PlayerController', function($rootScope, $scope, audio) {
//triggered by ngChange to update audio.currentTime
$scope.seeked = function(){
audio.currentTime = this.seek;
};
$scope.updateUI = function(seek, max){
$scope.max = max;
$scope.seek = seek;
};
audio.addEventListener('timeupdate', function(){
seek = audio.currentTime;
max = audio.duration;
$rootScope.$apply($scope.updateUI(seek, max));
});
}
My problem is, when I hit play, the range input element is updating which is what I want. But when I change the input value (move the slider/seek), the song jumps exactly to where I placed the slider but the slider doesn't update anymore after.
Another approach I did for this was to use jqLite and update the input range value inside the 'timeupdate' event with the following:
angular.element('#seek').val(audio.currentTime);
This works great, but I want to avoid using jqLite as much as possible unless there's no other work-around for this. Can someone enlighten me about this? BTW, I'm using Ionic Framework and I'm fairly new to this.
Finally found the issue.
Source of answer can be found here.
According to him(Calendee), dot notation and prototypal inheritance should be observed always.
So I updated my view into the ff:
<input type="range" min="0" ng-model="data.seek" ng-change="seeked();" max="{{max}}" value="{{data.seek}}">
Then on my controller:
app.controller('PlayerController', function($timeout, $scope, audio) {
//init vars
$scope.data = {};
//triggered by ngChange to update audio.currentTime
$scope.seeked = function(){
audio.currentTime = this.data.seek;
};
$scope.updateUI = function(seek, max){
$scope.max = max;
$scope.data.seek = seek;
};
audio.addEventListener('timeupdate', function(){
seek = audio.currentTime;
max = audio.duration;
//did a little change here by using $timeout
$timeout(function(){
$scope.updateUI(seek, max)
}, 0);
});
}
Additional references can be found here.