将视频帧转换为流式视频

edk*_*ked 11 javascript html5-video angular

服务器正在发送视频帧.我想用它们来做流媒体.我想知道如何组装帧以创建流式视频.到目前为止,我可以将帧显示为图片.下面是我的角度代码

分量角

 getVideo() {
    interval(250).switchMap(() => this.appService.getPictures())
      .subscribe(data => {
        const file = new Blob([data], {type:'image/png'});
        this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
      })
  }
Run Code Online (Sandbox Code Playgroud)

模板html

<img div="test" [src]="url" width="400px" height="300px"/>
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用相机的帧速率更改图片.但我的图片没有更新,由于http请求数量很多,它冻结了我的浏览器.

我想要实现的是缓冲帧以便使用video标记而不是img标记,就像我使用设置为服务器的video标记连接到服务器的实时流式传输一样.srcurl

Github链接:https://github.com/kedevked/frameProcessing

edk*_*ked 5

与其以一定的时间间隔触发http请求,不如使用websocket。

通过逐帧显示图像,给人以现场视频的印象。唯一的问题是网络中可能存在延迟,这使得帧速率不稳定。但是,它适用于无法考虑缓冲视频服务器端的用例,例如当我们需要沿每个帧发送数据时。

使用 websocket 的服务

createStream(url) {
  this.ws = webSocket<any>(url);
  return return this.ws.asObservable()
}
Run Code Online (Sandbox Code Playgroud)

成分

constructor (private streamingService: StreamingService) {}
ngOnInit(): void { 
  this.getStream()
}

getStream() {
  this.streamingService.createStream().subscribe(data => {
    const file = new Blob([data], {type:'image/png'});
        this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
 })
}
Run Code Online (Sandbox Code Playgroud)

当我们不仅发送图像而且还沿着图像发送数据时,该解决方案非常适合。在这种情况下,图像需要以 base64 形式发送。

getStream() {
      this.streamingService.createStream().subscribe(data => {
            this.url = data.base64ImageData
     })
    }
Run Code Online (Sandbox Code Playgroud)

由于 base64 编码的有效负载为初始图像的 133%,因此在所有设置中使用它的成本可能会很高。如果图像需要与其他数据一起提供,则整个数据可以作为二进制文件发送。这将需要在服务器端对数据进行编码并在客户端进行解码。
由于这可能需要一些计算,因此可以考虑使用网络工作者不仅可以解码数据,还可以显示图像。

如果图像作为二进制发送,使用canvas进行渲染会更快

canvas.getContext('2d').putImageData(imageBinaryData, 0, 0)
Run Code Online (Sandbox Code Playgroud)


Llo*_*iol 1

我在这里看到两个问题,可能会改进这个解决方案。

首先,你怎么知道请求花费的时间会少于250毫秒?如果没有,你知道 switchMap 会取消它吗?如果您不想丢失当前请求,也许exhaustMapconcatMap可能更适合。

第二点是间隔(X)和HTTP请求位于角度区域内,因此它们将触发变化检测......这可能会给您带来一些性能问题。因此,您应该在区域外运行间隔和请求并手动检测更改

说我将采用这样的解决方案:

private subscription: Subscription;
cosntructor(public ngZone: NgZone, public cd: ChangeDetectorRef){
   getVideo();
}

getVideo() {
    this.subscription = this.ngZone.runOutsideAngular(() => 
         interval(250).pipe(exhaustMap(() => this.appService.getPictures()))
           .subscribe(data => {
              const file = new Blob([data], {type:'image/png'});
              this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
              // Do change detection in orther to actualize [url] binding
              this.cd.detectChanges();
           })
    );
}
ngOnDestroy() {
    // remember to unsubscribe from interval subscription
    this.subscription.unsubscribe()
}
Run Code Online (Sandbox Code Playgroud)

我不认为使用这段代码会遇到太多性能问题...尽管这种类型的长轮询从来都不好,但我不认为它会冻结您的应用程序。尝试一下并告诉我。

希望这可以帮助。