使用VueJS

时间:2017-08-25 19:15:13

标签: javascript vue.js webrtc vuejs2 vuex

设置" src" html视频元素的属性不适用于Vue.js和Vuex:

<video id="myVideoEl" :src="myStreamSrc" autoplay="autoplay">

myStreamSrc是一个计算值,由事件处理程序设置为突变:

AddStream: function (state, plMyStream) {
  state.myRTCPeerConnection.addStream(plMyStream)
  state.myStreamSrc = plMyStream
}

当我使用该代码运行我的应用程序时,出现以下错误:

  

不支持“text / html”的HTTP“Content-Type”。载入媒体   资源http://localhost:8080/[object%20MediaStream]失败。

当我执行以下操作时:

state.myVideoEl = document.querySelector('#myVideoEl')
state.myVideoEl.srcObject = payloadWithMyStream

我没有收到任何错误,显示了流。问题是,我不能使用剪切的工作代码,因为引用的元素稍后会添加到DOM中。当我使用v-if Vuex.js属性绑定div中的html视频元素时,此代码段不起作用。然后我得到&#34; undefined&#34;结果(因为在页面加载时,视频元素的div元素不存在)。

设置srcObject和设置src属性之间有区别吗?我认为当我设置srcObject时,视频元素将具有src属性,但它没有。

是否可以在视频html属性中设置srcObject

欲了解更多信息,请访问我在Vue.js论坛中的theard: https://forum.vuejs.org/t/reference-elements-when-they-rendered-with-v-if/16474/13

4 个答案:

答案 0 :(得分:1)

srcObject是修饰符,而不是html属性,因此您需要编写

<video :srcObject.prop="myStreamSrc" autoplay/>

答案 1 :(得分:0)

你试过吗

<video v-if="myStreamSrc" id="myVideoEl" :srcObject ="myStreamSrc" autoplay="autoplay"> ?

否则我建议您为该案例编写一个组件:

var videoComponent = {
  template: '<video ref="myVideoEl" :srcObject ="myStreamSrc" autoplay="autoplay">'
  props: ['myStreamSrc']
}
Vue.component("video-component", videoComponent)

在父模板中

<video-component v-if="myStreamSrc" :myStreamSrc="myStreamSrc"></video-component>

在父级中你可以只为srcObject放一个观察者,我假设它等于假,直到加载了正确的视频源。在这种情况下,您可以等到设置源目标,然后以工作方式执行。

...
watchers:{
    myStreamSrc: function (newValue, oldValue) {
      if(!oldValue && !!newValue){
        this.nextTick(function () {
          state.myVideoEl = document.querySelector('#myVideoEl')
          state.myVideoEl.srcObject = payloadWithMyStream
        })
      }
  }
}

提示: 将$refs.myVideoEl设置为html-element而不是document.querySelector('#myVideoEl')时,可以使用ref="myVideoEl"代替id="myVideoEl"。这只是一种品味。

PS:我在没有拼写检查程序的情况下直接在stackoverflow中编写代码......

答案 2 :(得分:0)

希望与我的(类似)解决方案配合使用。我正在将Nuxt框架用于Vue。通过Vuex设置MediaStream对我也不起作用。通过在非子组件中单击按钮来启动网络摄像头的状态,我需要在另一个组件中设置视频对象的媒体流。

在单击按钮切换我的视图以及启动navigator.mediaDevices时运行的方法中,我最终这样做了(可能不是最干净的?)。

let constraints = (window.constraints = {
        audio: false,
        video: {
          facingMode: "user"
        }
      });

      navigator.mediaDevices
        .getUserMedia(constraints)
        .then((stream) => {
          let videoTracks = stream.getVideoTracks();
          if (this.$store.state.debug) console.log("Got stream with constraints:", constraints);
          if (this.$store.state.debug) console.log("Using video device: " + videoTracks[0].label);
          stream.oninactive = function() {
            if (this.$store.state.debug) console.log("Stream inactive");
          };
          // NOTE: this is done this way because I couldnt set it via Vuex state
          document.getElementById('user-media__source').srcObject = stream;
        })
        .catch((error) => {
          if (error.name === "ConstraintNotSatisfiedError") {
            if (this.$store.state.debug) console.log(`The resolution ${constraints.video.width.exact} "x" ${constraints.video.width.exact} px is not supported by your device.`);
          } else if (error.name === "PermissionDeniedError") {
            if (this.$store.state.debug) console.log(`Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.`);
          }
        });

因此,由于我需要在其中设置源的组件已经创建/挂载,因此我只用了普通的document.getElementById('XXXX').srcObject =,它可以按我的意愿工作。

答案 3 :(得分:0)

为新版本的Vue发布更新的解决方案,以防任何人遇到此问题并遇到与我相同的错误。

2019年更新:

<video :src-object.prop.camel="stream">

第一个更改是使用v-bind绑定到srcObject,这是速记示例:

<video :srcObject.prop="stream">

但是srcObject是用驼峰大小写的,因此在HTML中只是变成srcobject(小写),这被认为是不同的属性,因此不会触发视频。

如果您使用的是Vue <2.1,则必须使用document.getXXXXX(...).srcObject = stream手动将其触发。

但是,如果您使用的是Vue v2.1 +,那么您会很幸运,因为现在也有针对此的API修改器:

<video :src-object.prop.camel="stream">

.camel将kebab-case转换为驼峰式,因此要获得srcObject,我们要进行相反的操作并得到src-object.camel。将其与.propv-bind结合使用,我们得到了上面的语法。