首页 > 解决方案 > 设置视频的 src 会带来 DOMException 错误

问题描述

我正在尝试在 HTML 中设置 Video 元素的 src。这是创建 blob 并设置视频 src 的方法:

  startExternalVideo() {
    console.log(this.arrayBuffer);
    this.blob = new Blob([new Uint8Array(this.arrayBuffer)] , {'type' : 'video/webm; codecs=vp8'});
    console.log(this.blob);
    this.recordedVideo.src = window.URL.createObjectURL(this.blob);

    this.recordedVideo.play();
  }

但我得到了错误:

未捕获(承诺)DOMException

然后我尝试设置视频的 srcObject :

this.recordedVideo.srcObject = window.URL.createObjectURL(this.blob);

这给了我这个错误:

WebrtcComponent.html:16 错误类型错误:无法在“HTMLMediaElement”上设置“srcObject”属性:提供的值不是“MediaStream”类型。

视频来自节点服务器。节点服务器从 MediaRecorder 数据创建了一个 ArrayBuffer。

this.arrayBuffer 是一个 ArrayBuffer:

ArrayBuffer(612916) {}
[[Int8Array]]: Int8Array(612916) [0, 26, 1, 115, -59, -121, 63, -73, 46, -83, 11, -43, 101, -125, …]
[[Int16Array]]: Int16Array(306458) [6656, -8379, -24669, -31166, 385, -2238, 385, -3518, 1153, -3262, 2177, -32190, 30596, 25189, …]
[[Int32Array]]: Int32Array(153229) [0, -2068476447, 8403783, 1644265887, -1373601436, 42063785, 47865 -2092334464, …]
[[Uint8Array]]: Uint8Array(612916) [0, 111 …]
byteLength: (...)
__proto__: ArrayBuffer 

这是我真的认为没有必要的完整代码,但它确实显示了视频是如何使用 socket.io 录制并发送到节点服务器的......

declare var MediaRecorder: any;
@Component({
  selector: 'app-webrtc',
  templateUrl: './webrtc.component.html',
  styleUrls: ['./webrtc.component.scss']
})
export class WebrtcComponent implements AfterViewInit, OnInit {
  constraints; video; recordedVideo; mediaRecorder; options;
  streams: string[] = [];
  audioChunks: any[];
  videoChunks: any[];
  arrayBuffer: ArrayBuffer;
  sourceBuffer: any;
  blob:any;

  constructor(private signalHub: WebRTCServiceService) {
    this.constraints = { audio: true, video: true };
  }

  ngOnInit() {
    this.signalHub.getHubStream().subscribe(data => {
    });
    this.signalHub.currentarrBuffer.subscribe(data => {
      this.arrayBuffer = data;
    });
    this.video = document.getElementsByClassName('video')[0];
    this.recordedVideo = document.getElementsByClassName('other-video')[0];
  }

  ngAfterViewInit() {
  }

  successCallback(stream) {
    if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
      this.options = { mimeType: 'video/webm; codecs=vp9' };
    } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
      this.options = { mimeType: 'video/webm; codecs=vp8' };
    } else {
      // ...
    }
    this.video.srcObject = stream;
    this.video.play();
    this.mediaRecorder = new MediaRecorder(stream, this.options);
    this.mediaRecorder.ondataavailable = this.handleDataAvailable.bind(this);
    this.mediaRecorder.start(3000);
  }

  startExternalVideo() {
    console.log(this.arrayBuffer);
    this.blob = new Blob([new Uint8Array(this.arrayBuffer)] , {'type' : 'video/webm; codecs=vp8'});
    console.log(this.blob);
    this.recordedVideo.srcObject = window.URL.createObjectURL(this.blob);

    this.recordedVideo.play();
  }
  startStream() {
    this.signalHub.startStream();
    this.runMedia();
  }

  stopStream() {
    this.mediaRecorder.stop();
    this.signalHub.stopStream();
  }

  getStream() {
    this.signalHub.getStream(0);
  }
  handleDataAvailable(blob) {
    // POST/PUT "Blob" using FormData/XHR2
    this.signalHub.sendStream(blob.data);
  }

  errorCallback(error) {
    console.log('navigator.getUserMedia error: ', error);
  }

  runMedia() {

    navigator.mediaDevices.getUserMedia(this.constraints)
      .then((stream) => {
        this.successCallback(stream);
      })
      .catch(this.errorCallback);
  }

}

这是视频的html。

<video class="other-video" autoplay="true"></video>

标签: javascriptsocket.iohtml5-videowebrtc

解决方案


推荐阅读