angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.82k stars 27.51k forks source link

ngSrc doesn't work properly with HTML5 Video Source tag #1352

Closed red-crown closed 9 years ago

red-crown commented 12 years ago

In firefox, ngSrc directive on video elements' tag doesn't work at all, and results in unsupported video format error. In chrome, updating ngSrc with data-binding doesn't update video, as it only loads video on page-load. i.e.

<video controls>
     <source ng-src="{{src}}">
</video>

doesn't work in Firefox at all, and in chrome it only works on first loading.

However,

<video ng-src="{{src}} controls></video>

works in both browsers, and it can be updated dynamically with no problems.

This is a problem, when having multiple video formats in order to support all browsers.

Related: #339

pkozlowski-opensource commented 9 years ago

@IDontEatSoap I'm not sure why I you bringing this question, just check the list of commits and releases. Given a new release every week and few commits a day, including weekends, it looks like pretty much maintained to me...

@phillip-haydon please keep the conversational professional and focused on technical matters, you are violating our code of conduct.

@IDontEatSoap @phillip-haydon if you truly interested in this issue being addressed the best way of moving forward is to send a pull request with code changes that make the future work in all browsers.

IDontEatSoap commented 9 years ago

And yet a simple video src tag isn't supported?

I've managed to get it working by exposing $sde and using src="{{$sce.trustAsResourceUrl(item.VideoUrl)}}"

Don't get me wrong, I'm really liking angular. But small things like video src and SVG tags not being supported and requiring workarounds is unexpected.

Keep up the good work :) :+1:

fredericpetit-gh commented 9 years ago

+1, impossible to add a livestream webcam with dynamic data.

phillip-haydon commented 9 years ago

@pkozlowski-opensource I'm no longer interested because I don't care for Angular now that you've ditched the community for V2. There's 0 point in wasting effort on it.

StevenDStanton commented 9 years ago

@phillip-haydon Thank you for that information. I was just looking into Frontend Frameworks to use with node.js. I had not heard about the V2 issue before. Me and my Team have decided to go with React.js due to how they are breaking compatibility between V1 and V2. You think the huge rift this type of thinking caused in the Python community would have taught everyone a lesson.

gkalpak commented 9 years ago

:disappointed:

petebacondarwin commented 9 years ago

@phillip-haydon and @StevenDStanton - I am sorry to hear that you have chosen to go with another framework but of course you must choose the tools that work best for your own development.

Just to be clear though, AngularJS has not ditched the community, in fact the community has been involved even more than ever in the on-going development of Angular 1.x. We are close to releasing AngularJS 1.4.0, which will be the shortest time between big version changes so far and has had more community members working on the core team that ever before. Once this version is released we will begin the development towards AngularJS 1.5, which should (all things being equal) be released well before the end of 2015. Remember also that Google, itself has literally hundreds of production use AngularJS 1.x applications in operation right now. It is in Google's interests to ensure that these applications, just the same as your applications, continue to have a life or a migration path.

Regarding Angular 2 - this development effort is precisely driven by feedback from the community. The aim is to provide a faster, smaller, more robust framework that will be able to support bigger more complex applications; to perform better on mobile devices; and to continue to embrace the evolution of web browsers with transparent support for Web Components.

To achieve this, it was not possible to continue to bolt things onto AngularJS 1.x, since we needed to rethink some of the fundamental building blocks, such as how the injector and compiler work. The result is a completely new framework that continues to push the same high level goals that made AngularJS as popular and reliable as it has become but also be able to provide a future proof path for years to come.

There may not be a turn-key upgrade solution to migrating from AngularJS 1.x to Angular 2, that is true. But it will certainly be easier to migrate from AngularJS 1.x to Angular 2 than it would be to migrate from AngularJS 1.x to a completely different framework.

petebacondarwin commented 9 years ago

It seems to me that the browser is not very good at watching the <source> element for changes to its src attribute. The Original Poster's issue can be worked around by using ng-if.

See http://plnkr.co/edit/rpiEg1ki7KXgD40zy8qV

tot-ra commented 9 years ago

I'm just using

        $timeout(function () {
            $("video source").attr("src", 'https:' + file.url);
            $("video").attr("src", 'https:' + file.url);
        }, 500);
petebacondarwin commented 9 years ago

@tot-ra - I believe your version works because the browser does watch the change to the src attribute on the <video> element as can be seen here: http://plnkr.co/edit/6dNmNjAvZ8b6t09mUE65

petebacondarwin commented 9 years ago

From the HTML5 spec: http://www.w3.org/TR/2014/REC-html5-20141028/embedded-content-0.html#the-source-element

Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, just use the src attribute on the media element directly, possibly making use of the canPlayType() method to pick from amongst available resources. Generally, manipulating source elements manually after the document has been parsed is an unnecessarily complicated approach.

What this means is that you cannot expect the browser to cope with AngularJS (or anything else for that matter) changing the source elements dynamically. Instead, what we need is some media specific directives that will deal with updating the <video> tag's src property when appropriate. Perhaps something along the lines of @caitp's ng-media library.


Regarding the problem with the request for a video not being cancelled, I suggest that we could implement something like @kaiqigong's idea in https://github.com/angular/angular.js/issues/1352#issuecomment-58865425. Perhaps we could add a video element directive that sets its src to "" when it's element is being destroyed?

petebacondarwin commented 9 years ago

Other potential libraries that could be tried:

binarykitchen commented 9 years ago

Unsubscribe. Leaving AngularJS for React. Sorry guys but thanks for your hard work.

phillip-haydon commented 9 years ago

Yeah good idea, I'm unsubscribing too. I've ditched AngularJS for http://aurelia.io/

petebacondarwin commented 9 years ago

So back to the technical issue at hand:

There are actually two problems being discussed in this issue:

Neither of these issues is a bug in AngularJS per-se. But that doesn't mean that we can't do something about it.

Regarding the first problem: The only way to fix this, in Angular or any other framework, is to write JavaScript to deal with the dynamically changing sources, as described in the HTML5 spec. I have not seen a solution to this in any of the other major frameworks but in AngularJS the most attractive way is by building a set of directives. This is effectively what the people in the following projects have tried to do:

Depending upon community interest, we could look at develop something similar to this for Angular 1.5 and package it as its own module (similar to how ngCookies is packaged). Let's revisit this when doing the 1.5 planning. In the meantime, the best solution is to implement one of the libraries above and help them to make their library work for you.

Regarding the second problem: I don't seem to be able to reproduce this personally at the moment. In my Chrome, it does indeed continue to stream the previous <video> elements video even after we have destroyed the element, which after some switching back and forth results in numerous requests running in parallel, but these requests do not seem to prevent the new <video> element's video from loading.

screen shot 2015-02-26 at 11 14 02

Here, you can see the multiple simultaneous video downloads.

I believe that this is really a bug in the browser, but in the meantime, you can workaround this by providing your own video directive (see http://plnkr.co/edit/QLMJd24rxvklr638e57Q?p=preview):

  .directive('video', function() {
    return {
      restrict: 'E',
      link: function(scope, element) {
        scope.$on('$destroy', function() {
          element.prop('src', '');
        });
      }
    };
  })

screen shot 2015-02-26 at 11 17 32

Here, you can see that the video download now stops when we navigate away from the video view.

For the time being, this is the recommended workaround for this problem.

daleyjem commented 9 years ago

@petebacondarwin ... From looking at the w3c spec, it seems that a user agent abort on the document will cause the stream load to abort also. Calling a window.stop() cancelled any further network streaming for me.

Ultimately, it's not the most ideal thing if you want other resources, but it provides some level of workaround.

petebacondarwin commented 9 years ago

@daleyjem thanks for this idea. We can't do this in a core directive as it would stop other videos from streaming.

jubins-sdn commented 9 years ago

Just Create a Filter: app.filter("trustUrl", ['$sce', function ($sce) { return function (recordingUrl) { return $sce.trustAsResourceUrl(recordingUrl); }; }]);

In View File: < audio src="{{Your_URL | trustUrl}}" audioplayer controls></ audio>

NOTE: mind the space in audio tag

2fdevs commented 9 years ago

Hi, I'm the creator of Videogular.

As @petebacondarwin explained, this is not an issue with AngularJS but mostly a problem of how video works on HTML5 and how the browsers deal with video requests. And it gets even more weird when you need to have it working on mobile devices.

I fought a lot with video and HTML5 with Videogular and I must say that is hard to get it working seamlessly across all browsers, but not impossible.

So, if anyone at the AngularJS team wants help on this I would be glad to share my humble knowledge on this and contribute to fix it. This is something that really annoys me and in Angular 2 I'm not having problems with this so it would be great to have a similar approach in both frameworks.

Code-Crash commented 9 years ago

+1

kmturley commented 9 years ago

If you have a directive on your video player, you can watch the src url variable and update it manually:

link: function (scope, element, attrs) {
    var video = element.find('video')[0];
    scope.$watch('source.url', function (val) {
        video.src = val;
    });
}
jfbloom22 commented 9 years ago

After a ton of trial and error I finally have video playing back reliably on Android 4.2.2, 4.3, 4.4.4, 5.0.0, and 5.1.0. Install Crosswalk and use Videogular

Civile commented 8 years ago

Fixed with a custom directive

<source ng-repeat="source in sources" vsrc="{{ source.path }}" type="{{ source.type }}" html5vfix>

//Html5 video fix
eshop.directive('html5vfix', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
            attr.$set('src', attr.vsrc);
        }
    }
});
oliver134 commented 8 years ago

İ parse url video in db with json , but not work((( please help

christianraj commented 8 years ago

when i click my play button the video displays upside down and when pressing fullscreen its getting to its position any suggestion to this issue

PunkHaz4rd commented 7 years ago

+1 there's no parsing the url be it with src or ngSrc. Has this error been abandonned ?

benayah commented 6 years ago

I am having this same problem has there been a solution yet

SmileOffline commented 6 years ago

This solutions works very well.

http://www.rubencanton.com/blog/2014/07/adding-video-src-with-angular.html