4

I am loading html5 mp4 video and I want to trigger function from angular scope when video end. I tried below simple code but onended event cannot find the function in angular scope.

HTML

<video controls="controls" autoplay="true" ng-show="showVideo" ng-src="{{vidSrc}}" vid-dir onended="vidEnded()">

Angularjs function added in main controller. onended event triggered but function is undefined

$scope.vidEnded = function(){
        console.log('vid ended')
    }

Also tried adding function in directory like this but the function is not triggered.

.directive('vidDir', [function () {
    return {
        restrict: 'A',
        link: function (scope, elem, attr) {
            console.log(elem)
            elem.onended = function(){
                console.log('vid ended')
            } 
        }
    };
}]);
2
  • check this link - stackoverflow.com/questions/28963530/… Commented Aug 23, 2016 at 4:15
  • Thanks Younis, I have seen this thread before. Its explain why its not working but no solution without plugin. I think Angular should have something that can track video elem onended but can't find any. Commented Aug 23, 2016 at 11:59

6 Answers 6

5

I believe the following code would achieve what you desire.

<video controls="controls" autoplay="true" ng-show="showVideo" ng-src="{{vidSrc}}" vid-dir (ended)="vidEnded()">
Sign up to request clarification or add additional context in comments.

1 Comment

thanks, working fine, in angular 9
1

Add the following in front of your angular function:

angular.element(this).scope().vidEnded()

The result:

<video controls="controls" autoplay="true" ng-show="showVideo" ng-src="{{vidSrc}}" vid-dir onended="angular.element(this).scope().vidEnded()">

1 Comment

onended="angular.element(this).scope().vidEnded()" worked for me :)
1

Another option would be to add a separate directive on-ended instead of the actual onended, like this:

/**
 * Handles onended event for video tags.
 * @example <video on-ended="awesomeFn()">
 */
.directive('onEnded', function () {
  return {
    scope: {
      onEnded: '&'
    },
    link: function (scope, element) {
      element.on('ended', scope.onEnded);
    }
  };
});

Comments

0
use this.vidEnded();
    .directive('vidDir', [function () {
        return {
            restrict: 'A',
            link: function (scope, elem, attr) {
                console.log(elem)
                this.vidEnded= function(){
                    console.log('vid ended')
                } 
            }
        };
    }]);

Comments

0

Worked at this issue for a while and found a hack to the same problem that worked for me. Uses jQuery $timeOut function (you could also use the vanilla JS timeout, both are a typical hack with angular I find), and the html5 video events: "duration", "currentTime", and "timeupdate", which you can learn more about here. Using those event values you can calculate the end of the video and simulate the html5 video "ended" event. Here's the code

myCtrl.myVideo = document.getElementbyId("my-video-id"); //you need to have an id for your html5 video

//function to define in the controller

myCtrl.videoListener = function()
{

 //javascript event listener function

 myCtrl.myVideo.addEventListener('timeupdate', 
 function() 
 {

     myCtrl.myVideo = this; //define "this"

     var videoDuration = this.duration;
     var videoCurrentTime = this.currentTime;


     if (videoCurrentTime >= videoDuration)
     {

       //wrapping in a $timeOut function is the only way this works!

        $timeout(function(){
          //do something when the video ends, set variables, etc.
        }, 0); 
     } 
     else if (videoCurrentTime < videoDuration)
     {

        //wrapping in a $timeOut function is the only way this works.

        $timeout(function(){
          //do something while the video is playing, set variables, etc.
        }, 0); 
     }

  });

}

Comments

-1

You actually do not need a directive or plugin to run the onended event.(if jquery is integrated) Here is some logic to add in your controller. Make sure the video tag has an Id.remove the on ended attribute if you already have one in there. Then within your controller add this

var jq = $;

jq('#IdOfVideo').on('ended', function(){
 //Whatever you want to happen after it has ended
});

2 Comments

$ is not defined. Angularjs is not based on JQuery though it has built in JQlite. Sure it may work if I include Jquery which I don't want to.
@alflashy Interesting, its always worked for me. Just a shot in the dark. If you added $.noConflict(); what does that get you?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.