Angular.js: ngSrc无法与HTML5 Video Source标签一起正常使用

创建于 2012-09-09  ·  78评论  ·  资料来源: angular/angular.js

在firefox中,视频元素的ngSrc指令标签根本不起作用,并导致不受支持的视频格式错误。 在chrome中,使用数据绑定更新ngSrc不会更新视频,因为它只会在页面加载时加载视频。 IE

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

在Firefox中根本不起作用,而在chrome中,它仅在首次加载时起作用。

然而,

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

在两种浏览器中均可使用,并且可以毫无问题地动态更新。

当具有多种视频格式以支持所有浏览器时,这是一个问题。

相关:#339

misc core moderate investigation broken expected use bug

最有用的评论

用自定义指令修复

<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);
        }
    }
});

所有78条评论

我也有问题,但是我认为问题出在Angulars ng-repeat中。
如果我从该示波器中删除视频,则播放效果很好,否则,任何控件都将无法加载。

我也是。

我也是! 帮我

+1

我正在使用ng-repeat设置ng-src源,并且它们在页面加载时正确加载,但是如果视频通过ng-show隐藏,然后再次显示,则源不会重新加载(在Chrome中)。

我可以确认sourcec0de的观察-如果我删除ng-repeat并使用单个ng-src源(或多个ng-src源),则视频会在重新显示后正确重新加载。

我有同样的问题。 目前有人在调查吗?

不论是否使用ng-src ,无论是否使用ng-repeat ,Chrome浏览器返回页面后都反复无法重新加载HTML5视频。

从干净的缓存中,我看到2个请求(第一个请求Pending ),第二个请求206 Partial Content 。 如果刷新,则会看到一个带有304 Not Modified请求。 当我离开视频视图导航然后返回时(通过链接或使用后退按钮),我收到两个对视频的请求,它们的状态仅为Pending 。 其中一个将具有mime类型的video/mp4 (正确),另一个仅显示Pending

有人在看这个问题吗???

您能否提供此问题的运行示例?
它完全可以在某些浏览器上运行吗?
您是否检查过浏览器是否支持在渲染后更改HTML5视频元素的src属性?

抱歉,示例应用尚未发布。
在Safari中可以正常工作。
如上所述,我同时使用了ng-src指令和硬编码的src属性,结果相同。

如果使用直接jQuery更改src会发生什么?
我想知道这是否实际上是浏览器而不是AngularJS的错误?

2013年7月16日22:31,Paul Grenier [email protected]写道:

抱歉,示例应用尚未发布。
在Safari中可以正常工作。
如上所述,我同时使用了ng-src指令和硬编码的src
属性具有相同的结果。

-
直接回复此电子邮件或在Gi tHub上查看它

即使我没有更改src(例如,对视频src属性进行硬编码),也会出现问题。 由于Angular控制内容,因此我无法从Angular模拟问题。 我同意,这可能只是Chrome中的问题,但我不确定如何测试。

您是什么意思Angular控制内容?

当使用Angular的控制器更改内容并加载另一个视图时,就会出现问题。 使用后退按钮或指向上一条路线的链接可显示前一内容,但每次都无法加载视频。 如果是Angular问题,则可能仅在Chrome中。 我的猜测是,Chrome的激进缓存和Angular的更改视图方法无法就应加载的内容达成共识。

@AutoSponge我的测试用例是:
第1页,并带有按钮以转到第2页
第2页,带有videojs播放器和返回第1页的按钮

导航至第1页,然后至第2页,视频已正确加载。
点击按钮返回第1页,然后转到第2页,google chrome停止使用videojs。 之所以会发生这种情况,是因为按预期的角度将元素从DOM中删除时,未删除videojs对象。 这不是angularjs(是的!)

在初始化videojs播放器之前将其删除。 我这样做是因为我有一个添加播放器的指令。 例如,如果在指令中使用:

... directive('mydir', ... {
    var vp;
    return {
        link: ..{ 
            if (vp) vp.dispose();
            vp = videojs("mp4video");
        }
    };`

就像OP一样,我没有使用包装对象。 该视频是通过HTML5视频标签加载的。 您是否建议将其单独移除?

好吧,videoJS跟踪添加到DOM中的播放器,但看起来好像没有在观察更改。 如果您从DOM中删除了该元素(例如,因为导航到另一条路线),videoJS将不知道,也不会再次对其进行初始化。 参见第17行: https :
如果您在videoJS之外将其删除,我想您应该调用播放器的dispose()方法。 我猜这就像包裹一个jQuery插件(?)时一样。 这就是让我认为这不是一个尖锐的问题。

也有这个问题。
将AV文件加载到src或ng-src并不能完成这项工作。 需要编写指令或工厂才能使其正常工作。
http://stackoverflow.com/questions/15485768/changing-html5s-source-src-attribute-takes-no-effect-wtih-angularjs

我也有这个问题。

视频无法在Chrome,Firefox和Safari中加载。 但是,它在IE中有效。

解决方法如下:http ://stackoverflow.com/questions/15728424/html5-video-is-not-working-with-angularjs-ng-src-tag

它会在页面加载时产生混乱的闪烁,但它可以工作。

+1

解决方法如下:

在你的控制器中设置一个函数在我的情况下是这样的:

    $scope.play = function(who) {
        var name = who.id.split('.')[0];
        $scope.audio.mp3 = name + '.mp3';
        $scope.audio.ogg = name + '.ogg';
        $scope.audio.play = 'views/audio.html?'+name;
    };

那么在我的模板中,我有以下内容:

<div ng-include src="audio.play"></div>

我在views / audio.html中的模板如下所示:

<audio ng-model="audio" controls autoplay >
    <source ng-src="{{audio.mp3}}" type='audio/mp3'></source>
    <source ng-src="{{audio.ogg}}" type='audio/ogg'></source>
</audio>

如果$ scope.audio.play不变,则不会重新加载,所以我使用的是文件名,这可能只是一个随机数,而不是

@caitp我以为您对此有公关,我的记忆让我失望吗?

@IgorMinar我正在研究它,但是我意识到我无法重现该问题(请参阅http://jsfiddle.net/J77gE/)。 我认为用更多绑定选项在核心之外构建媒体帮助器模块会很有趣。

但据我所知,ng-src对于现代浏览器和现代Angular的源代码都可以正常工作

我提到的问题具体是由于更改视图和使用后退按钮引起的。 我不确定jsfiddle如何尝试重现该问题。

并不是这样,重点是我们插入源代码没有问题,我认为这不是问题。 我根本无法重现您的特定问题

@AutoSponge您可以提供一个演示应用程序以及有关如何重现此内容的说明吗?

http://jsfiddle.net/AutoSponge/Yh9en/

单击视频链接。 它将在第一次加载。 单击主页,然后再次单击视频。 单击1或2次后,它可能会停止在Chrome中加载。

(不要判断,我根据8个月前的应用将其汇总!)

@AutoSponge这不是一个Angular问题。 这是Chrome的怪异行为,但它仍在插值您的源文件并获得正确的src。 缓存似乎是一个问题,这有点不幸。 (ngIf也存在此问题,但是可以通过使用ngShow +将音量设置为0来避免此问题)

我同意这是Chrome的不幸问题。 我认为这是此问题在没有任何工作的情况下保持9个月的主要原因。 由于Chrome不太可能修复它,因此您认为创建缓存清除选项是否不合理? 我在想它将只是在src后面附加一个随机字符串。

我还认为这可能与pushState有关-在Chrome中实现或在Angular中使用它。 但老实说,我认为现在就可以解决。

我觉得这个特定的问题可能属于Chrome问题跟踪器(我认为已经打开了几个与HTMLMediaElement缓存相关的问题,因此值得在此进行讨论)。

我不记得了,但这很可能是规范中定义的预期行为(并且这不是规范第一次要求怪异/不幸的行为)

这可能与我一直遇到的问题不同,但是我遇到了一个问题

希望这有点可理解和相关!

刚刚发现了一些解决方法。 它适用于Chrome浏览器,但不适用于其他浏览器(在某些情况下会不断更新,等等):)
最后评论
http://stackoverflow.com/questions/16137381/html5-video-element-request-stay-pending-forever-on-chrome

另外请注意,HTML5规范指出,动态修改标记将无效,但会对的src属性执行相同的操作

经过一番谷歌搜索后,我发现这很可能与chrome等待可用的插槽不成角度,并且在视频标签中添加preload =“ none”似乎可以解决此问题。

解决方法

在控制器中

$scope.mp3 = "http://download.jw.org/audio.mp3"

$scope.$watch('mp3', function() {
       $("audio").attr("src",$scope.mp3)
   });

的HTML:

<audio id="mejs" type="audio/mp3" controls="controls"></audio>

@agliottone您建议的解决方法使用了不良做法。 永远不要从这样的控制器向DOM写入数据。 考虑使用自定义指令。

@btford 1同意,但是..
他把最后的恶魔奉献给了补救措施

+1

我认为每次设置新的源时,都必须再次在本地视频元素上调用.load() ,以显示新的视频源。

嗨,我第一次加载HTML 5 Video时加载页面时,我在Google Chrome上遇到angularJS问题,但是当我用ng-view更改视图时却无法加载,但是在Firefox中,Internet Explorer可以很好地工作。

我不知道该怎么办!

这看起来与<embed>ngSrc类似。 参见#339

这需要固定ddddddddd :(

我写了一个plnkr
点击视频,视频就会加载。 单击其他链接,然后返回视频。 视频正在等待处理。 您可以在chrome network看到请求。 有两个请求,一个是前一个请求,现在仍然存在。 另一个是新的,有待解决。

@kaiqigong我上周通过将URL设置为视频受信任的方式使其正常工作,因为该视频不是网站本地的。

http://plnkr.co/edit/CL0Lh6VGMy0M3mR1SvVA?p=预览

我分叉了plnkr并对其进行了修改,以设置URL并信任它:

   .controller('VideoController', function($scope, $sce, $routeParams){
        $scope.name = "VideoController";
        $scope.params = {
          videoUrl: $sce.trustAsResourceUrl("http://www.videogular.com/assets/videos/videogular.mp4")
        };
   })

视频有延迟,但是对我有用。

@ phillip-haydon谢谢您的回复。
我尝试了您的plnkr,但仍无法正常工作。 (请尝试在链接之间快速切换。)
我发现的是,当我们删除视频标签(通过更改路线或其他一些DOM操作)时,浏览器仍在拉视频源。 当我们切换回视频时。 发出另一个视频请求,使网络流量阻塞。
如果在删除视频标签之前将视频的src设置为'' ,浏览器将停止拉动,从而解决了问题。 请尝试以下Codepen: http ://codepen.io/cagegong/pen/bJHAz

所以我的最终解决方案是:

$scope.$on '$destroy', () ->
  angular.element('video').attr 'src', ''

是的,我的作品行得通,但并非100%,为什么当请求它的dom元素被销毁时,浏览器为什么不会杀死请求本身,我不知道。 我不认为这是Angular本身需要处理的事情。

有趣的是,将其设置为空字符串会终止请求,我可能必须设置一些内容才能在项目中添加它。 谢谢。

@jharaujoads
希望这能解决您的问题

:+1:

哇,两年没事了。 是否完全保持角度?

Angular不值得花费时间和精力。 他们已经通过Angular 2.0向社区说了“操你妈”。

@IDontEatSoap我不确定为什么要提出这个问题,只需检查commitsreleases列表即可。 给定每周都有一个新版本,并且每天很少提交(包括周末),这对我来说似乎几乎可以维持...

@ phillip-haydon请保持对话的专业性,并专注于技术问题,因为您违反了我们的行为准则

@IDontEatSoap @ phillip-haydon如果您真的对解决这个问题感兴趣,最好的前进方法是发送一个带有代码更改的拉取请求,以使将来在所有浏览器中都能正常工作。

但是不支持简单的视频src标签吗?

我已经通过公开$ sde并使用src =“ {{$ sce.trustAsResourceUrl(item.VideoUrl)}}”来使其正常工作

别误会我,我真的很喜欢棱角分明。 但是,不支持视频src和SVG标签之类的小事情,并且需要变通办法。

保持良好的工作:):+1:

+1,无法添加带有动态数据的实时网络摄像头。

@ pkozlowski-opensource我不再感兴趣,因为既然您已经放弃了使用V2的社区,那么我不再关心Angular。 浪费精力在这里有0分。

@ phillip-haydon谢谢您提供的信息。 我只是在研究要与node.js一起使用的Frontend Frameworks。 我以前从未听说过V2问题。 我和我的团队已决定使用React.js,因为它们如何破坏V1和V2之间的兼容性。 您认为在Python社区中引起的这种思维裂痕会给每个人一个教训。

:失望的:

@菲利普-海顿和@StevenDStanton -我很抱歉,你选择去与另一个框架,但当然,你必须选择工具的工作最适合自己的发展。

只是要清楚一点,AngularJS并没有抛弃社区,实际上,社区比以往任何时候都更多地参与了Angular 1.x的持续开发。 我们即将发布AngularJS 1.4.0,这是迄今为止进行大版本更改之间最短的时间,并且以前有更多的社区成员在核心团队中工作。 此版本发布后,我们将开始向AngularJS 1.5进行开发,该开发应该(在所有条件不变的情况下)在2015年底之前发布。还要记住,Google本身实际上已经在使用数百种生产应用AngularJS 1.x应用程序马上。 确保与您的应用程序相同的这些应用程序继续存在或迁移路径符合Google的利益。

关于Angular 2-这项开发工作正是受社区反馈的推动。 目的是提供一个更快,更小,更强大的框架,该框架将能够支持更大,更复杂的应用程序。 在移动设备上表现更好; 并继续通过透明地支持Web组件来支持Web浏览器的发展。

为此,不可能继续将其附加到AngularJS 1.x上,因为我们需要重新考虑一些基本的构建块,例如注入器和编译器的工作方式。 结果是一个全新的框架,该框架继续推动相同的高级目标,这些目标使AngularJS变得既流行又可靠,而且还能够为未来几年提供未来的证明之路。

从AngularJS 1.x迁移到Angular 2可能没有完整的升级解决方案。 但是,从AngularJS 1.x迁移到Angular 2肯定比从AngularJS 1.x迁移到完全不同的框架要容易。

在我看来,浏览器不太擅长观察<source>元素对其src属性的更改。 可以使用ng-if解决原始海报的问题。

看到http://plnkr.co/edit/rpiEg1ki7KXgD40zy8qV

我只是在用

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

@ tot-ra-我认为您的版本适用,因为浏览器确实可以看到<video>元素上src属性的更改,如下所示: http :

根据HTML5规范: http

如果已将元素插入视频或音频元素中,则动态修改源元素及其属性将无效。 要更改正在播放的内容,只需直接在media元素上使用src属性,可能使用canPlayType()方法从可用资源中进行选择。 通常,在解析文档后手动操作源元素是不必要的复杂方法。

这意味着您不能期望浏览器能够应付AngularJS(或其他任何事情)动态更改源元素。 相反,我们需要的是一些特定于媒体的指令,这些指令将在适当时处理更新<video>标签的src属性。 也许类似于@caitpng-media库。


关于未取消视频请求的问题,我建议我们可以在https://github.com/angular/angular.js/issues/1352#issuecomment -58865425中实现类似@kaiqigong的想法。 也许我们可以添加一个video元素指令, ""在其元素被销毁时将其src""

其他可以尝试的潜在库:

取消订阅。 离开AngularJS进行React。 抱歉,谢谢您的辛勤工作。

是的,好主意,我也取消订阅。 我放弃了AngularJS的http://aurelia.io/

回到当前的技术问题:

本期中实际上讨论了两个问题:

  • <video>元素不会监视<source>标签上对src属性的更改,也不会做出反应。 这是HTML5规范的一部分,因此在不久的将来不太可能更改。 这意味着我们不能使用惯用的AngularJS动态指定<source>元素的方式,无论是否带有ngSrc 。 换句话说,我们根本无法在<source>标记的src属性中使用插值,因为<video>元素不会获取更改。
  • 在某些情况下(浏览器), <video>元素没有取消其正确下载视频的请求,因此将该元素从DOM中删除。 这样做的结果是,如果您的应用程序足够快地更改DOM,添加和删除<video>标签,从而使视频没有时间下载,则您可能会陷入新的<video>元素正在尝试访问先前已销毁的<video>元素仍在等待播放的视频。 如果在破坏元素之前将src (或currentSrc ?)属性设置为空字符串( "" ),似乎浏览器实际上将取消视频请求。 。

这些问题都不是AngularJS本身的错误。 但这并不意味着我们不能对此做任何事情。

关于第一个问题:
在Angular或任何其他框架中解决此问题的唯一方法是编写JavaScript以处理动态变化的源,如HTML5规范中所述。 我在其他任何主要框架中都没有看到解决此问题的方法,但是在AngularJS中,最吸引人的方法是构建一组指令。 这实际上是以下项目中的人们试图做的事情:

根据社区的兴趣,我们可以考虑为Angular 1.5开发与此类似的东西并将其打包为自己的模块(类似于ngCookies的打包方式)。 让我们在进行1.5计划时再次进行讨论。 同时,最好的解决方案是实施上述库之一,并帮助它们使您的库发挥作用。

关于第二个问题:
目前,我似乎无法亲自复制此内容。 在我的Chrome浏览器中,即使我们销毁了<video>元素后,它的确确实会继续流式传输视频,这在反复切换后会导致大量请求并行运行,但是这些请求似乎并没有阻止加载新的<video>元素的视频。

screen shot 2015-02-26 at 11 14 02

在这里,您可以同时看到多个视频下载。

我相信这确实是浏览器中的错误,但与此同时,您可以通过提供自己的video指令来解决此问题(请参阅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

在这里,您可以看到当我们离开视频视图时,视频下载现在停止了。

目前,这是针对此问题的推荐解决方法。

@petebacondarwin ...从w3c规范来看,似乎用户代理在文档上中止会导致流负载也中止。 呼叫window.stop()取消我的任何其他网络流。

最终,如果您需要其他资源,这并不是最理想的选择,但是它提供了一定程度的解决方法。

@daleyjem感谢您的想法。
我们无法在核心指令中执行此操作,因为它会阻止其他视频流式传输。

只需创建一个过滤器:
app.filter(“ trustUrl”,['$ sce',函数($ sce){
返回函数(recordingUrl){
返回$ sce.trustAsResourceUrl(recordingUrl);
};
}]);

在查看文件中:
<audio src =“ {{您的URL | trustUrl}}”音频播放器控件>音频>

注意:请注意音频标签中的空格

嗨,我是Videogular的创建者

正如@petebacondarwin解释的那样,这不是AngularJS的问题,而主要是视频在HTML5上的工作方式以及浏览器如何处理视频请求的问题。 当您需要使其在移动设备上运行时,它变得更加奇怪。

我为使用Videogular进行视频和HTML5进行了很多工作,我必须说,要使它在所有浏览器中无缝运行是很困难的,但并非没有。

因此,如果AngularJS团队中的任何人需要此方面的帮助,我将很高兴分享我对此的谦虚知识并为解决问题做出贡献。 这确实让我很烦,在Angular 2中我对此没有任何问题,因此在两个框架中都采用类似的方法将是一件很棒的事情。

+1

如果您的视频播放器上有指令,则可以观看src url变量并手动更新它:

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

经过大量的反复试验,我终于可以在Android 4.2.2、4.3、4.4.4、5.0.0和5.1.0上可靠地播放视频了。 安装Crosswalk并使用Videogular

用自定义指令修复

<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);
        }
    }
});

©使用json解析db中的url视频,但不起作用((((请帮助

当我单击播放按钮时,视频将上下颠倒显示;按全屏显示时,该位置的任何建议

+1没有解析网址,无论是src还是ngSrc。
是否已放弃此错误?

我有同样的问题,已经有解决方案

此页面是否有帮助?
0 / 5 - 0 等级