3

I'm having a problem trying to set a source to a video in AngularJS.

Here's the HTML code of the view:

<div class="row">
    <div class="col-lg-10 col-lg-offset-1">
    <video width="100%" controls>
        <source ng-src="{{levelContent.levelVideo}}" type="video/mp4">
        <!--<source ng-src="Content\img\cortes.mp4" type="video/mp4">-->
        Your browser does not support HTML5 video.
    </video>
    </div>
</div>

Here's the code of the controller of that view:

(function () {
    'use strict';

    angular
    .module('iziCooker')
    .controller('LevelController', LevelController);

    LevelController.$inject = ['$scope', 'LevelContentService', '$routeParams', 'LevelService', '$sce' ,'$location'];
    function LevelController($scope, LevelContentService, $routeParams, LevelService, $sce ,$location) {
        $scope.levelId = -1;
        $scope.levelContent = [];

        function GetLevelContent() {
            LevelContentService.SetLevelId($routeParams.levelId);
            $scope.levelId = LevelContentService.GetLevelId();
            LevelService.GetLevelContent($scope.levelId).then(function (data) {
                $scope.levelContent = data;
                LevelContentService.SetLevelName = data.name + " - " + data.description;
                $scope.levelContent.levelVideo = $sce.trustAsResourceUrl(data.levelVideo);
            });
        }

        GetLevelContent();
        console.log("Level Controller Loaded!");
    }

})();

I'm testing my application on IE and Chrome, with the first one it works properly but no with the second one which I mostly use.

On IE:

enter image description here

On Chrome:

enter image description here

I tested the video individually on Chrome and it works fine. Also I tried with the hardcoded src as you can see above and it works too. I thought it could be something with the $sce but seems it doesn't.

jmrivas
  • 129
  • 2
  • 11
  • 2
    have you tried setting the source directly on the video element? I vaguely remember having an issue like this and ng-src not working on the `` element. – Ronnie Feb 09 '16 at 00:09
  • https://github.com/angular/angular.js/issues/1352 – Ronnie Feb 09 '16 at 00:10
  • I tried setting setting the source directly and it worked like a charm. It's weird that behaviour with angular and HTML5. Thank you very much! – jmrivas Feb 09 '16 at 02:34

2 Answers2

3

I hope the issue is resolved, but just in case, if someone needs it. There is a workaround - HTML5 video element request stay pending forever (on chrome)

Once you assign the URL call the below method:

function loadVideos() {
    $("video").each(function () {
        $(this).get(0).load();
        $(this).get(0).addEventListener("canplaythrough", function () {
            this.play();
            this.pause();
        });
    });
}

This works in chrome as well as IE.

Community
  • 1
  • 1
Neal Gabriel
  • 114
  • 1
  • 9
1

If you call .load() on the video element after the src has changed the video will update. Here's a snippet that will replace your <video> tag with an Angular 1 component t

class VideoController {
    constructor(
        $element
    ) {
        this.$inject = [
            "$element"
        ];
        this.$element = $element;
        this.supportedVideoTypes = ["mp4", "webm"];
    }

    $onChanges($event) {
        this.supportedVideoTypes.forEach((type) => {
            if ($event[type] && $event[type].currentValue) {
                let source = this.$element[0].querySelector(`[type="video/${type}"]`);
                if (source) {
                    source.setAttribute("src", $event[type].currentValue);
                    this.$element[0].load();
                }
            }
        });
    }
}

angular.module("myApp")
    .component("video", {
        bindings: {
            mp4: "<",
            webm: "<"
        },
        controller: VideoController,
        template: `
            <source type="video/mp4"/>
            <source type="video/webm"/>`
    });
stwilz
  • 1,598
  • 1
  • 15
  • 19