【问题标题】:How can I change a video's src to a blob, the angularjs way?如何以 angularjs 方式将视频的 src 更改为 blob?
【发布时间】:2014-01-14 15:19:29
【问题描述】:

我有一个 angularjs 设置,例如:

HTML:

<div ng-app="myApp">
  <div ng-controller="Ctrl">
   <span>{{config.localvideo}}</span>
     <video id="video" autoplay>    </video>
     <button ng-click="click()">Start</button>
  </div>
</div>

javascript 文件:

.controller('Ctrl', function($scope,$window){
 $scope.config = {localvideo:""} ;
  $scope.click = function(){
    navigator.webkitGetUserMedia( {video:true},function (stream) {
    var video = document.getElementById("video");
    video.src = $window.URL.createObjectURL(stream);
    $scope.config = {localvideo: video.src};
        $scope.$apply();
    },function (error) {
    console.log(error); 
    });
 }
});

这按预期工作:当页面加载时,视频只是一个黑色矩形。当我单击按钮时,我必须授予摄像头权限,然后视频显示摄像头。 span 显示了 blob url,这样我就可以看到它发生了。

但是,据我了解,这不是 angularjs 方式。我不应该使用 document.getElementById 或类似的东西,我应该更改 $scope 中的对象,并且 html 元素应该通过 ng-src 的 Angular 魔法进行更新。 我认为应该可以工作的 Javascript:

.controller('Ctrl', function($scope,$window){
 $scope.config = {localvideo:""} ;
  $scope.click = function(){
    navigator.webkitGetUserMedia( {video:true},function (stream) {
        $scope.config = {localvideo: $window.URL.createObjectURL(stream)};
        $scope.$apply();
    },function (error) {
    console.log(error); 
    });
 }
});

如果我使用它,向我的视频标签添加一个属性: ng-src="config.localvideo" ,我希望 $scope.config 会改变,ng-src 会选择它,视频会开始播放。这不会发生。但是,跨度确实会在单击按钮时更新,因此似乎 $scope.config 正在正确更新。谁能解释发生了什么,或者没有发生什么?

感谢您的帮助。 注意:我直接使用 chrome 版本的 getUserMedia,而不是 shim,只是为了在这一点上进行简洁和健全的检查。

【问题讨论】:

    标签: javascript angularjs html5-video webrtc


    【解决方案1】:

    要使用“Angular 方式”,您需要编写自己的指令。在指令中访问 DOM 是安全的,因为它们有一个 link 函数,您可以将其视为此特定元素的一种 document.ready。在链接函数中,您知道 Angular 已完成创建 DOM。不使用 getElementById,传递给下面链接函数的“元素”将是您应用此指令的任何内容。

    .directive("myStream", function(){
       return {        
          restrict: 'A',
          scope:{config:'='},
          link: function(scope, element, attributes){
           //Element is whatever element this "directive" is on
           navigator.webkitGetUserMedia( {video:true},function (stream) {
             element.src = $window.URL.createObjectURL(stream);
             scope.config = {localvideo: element.src};
             scope.$apply(); //sometimes this can be unsafe.
           });
          }
       }
    
    }
    

    现在在您的视频项目上,您只需添加“my-stream”作为属性并将其传递给 config="config"。

    <video my-stream config="config" /> {{config.localVideo}}
    

    【讨论】:

    • 好吧,我还是有点困惑。在我看来,这避免了我正在寻找的功能:按一个按钮,更改视频的来源。如果我想这样做,我仍然需要在该指令之外的某个地方编写一个函数吗?或者我应该在指令中定义一个函数,从外部调用它?
    • 问题是 Angular 不知道 webkitGetuserMedia 函数。因此,如果没有解释 DOM 的指令,就不会发生自动绑定。如果源来自除回调函数之外的任何其他地方,它会像您期望的那样工作。如果你想要一个按钮来触发这个行为,最简单的方法就是一个事件。从你的父控制器$scope.click = function(){ $scope.$broadcast('getUserMedia'); }; 然后在你的指令中你会做$scope.$on('getUserMedia', function(){ //navigaotr code }); 这就是你放置处理程序的地方。
    • 除了$broadcast,还有其他几种方法可以做到这一点,比如观察变量。但是 $broadcast 可能是最简单的。您还可以将按钮作为指令的一部分。指令可以有包含更多 HTML 的模板。
    • 非常感谢您的澄清!
    猜你喜欢
    • 2019-05-25
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多