首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >直播流HTML5视频画布绘制不起作用

直播流HTML5视频画布绘制不起作用
EN

Stack Overflow用户
提问于 2020-01-23 06:12:27
回答 2查看 1.2K关注 0票数 0

我使用ReactJS通过HTML5视频元素来显示实况流(来自我的网络摄像头)。后端由OpenVidu媒体服务器处理。我想使用canvas元素通过drawImage()方法将视频实时流绘制到画布上。

我见过其他示例,但在它们中,video元素总是有一个源。我的视频没有源代码-当我检查视频元素时,我看到的只有:<video autoplay id="remote-video-zfrstyztfhbojsoc_CAMERA_ZCBRG"/>

这是我尝试过的,但是画布不起作用。

代码语言:javascript
复制
export default function Video({ streamManager }) {
  const videoRef = createRef()
  const canvasRef = createRef()

  useEffect(() => {
    if (streamManager && !!videoRef) {

      //OpenVidu media server attaches the live stream to the video element 
      streamManager.addVideoElement(videoRef.current)

      if (canvasRef.current) {
        let ctx = canvasRef.current.getContext('2d')
        ctx.drawImage(videoRef.current, 0, 0)
      }
    }
  })

  return (
    <>
      //video element displays the live stream 
      <video autoPlay={true} ref={videoRef} />

      // canvas element NOT working, nothing can be seen on screen 
      <canvas autoplay={true} ref={canvasRef} width="250" height="250" />
    </>
  )
}

更新:经过进一步的研究,我意识到我需要使用setInterval()函数,因此提供了下面的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-24 04:31:46

解决方案是在一个自包含的组件中提取canvas逻辑,并使用setInterval(),以便它每隔100ms(或根据需要)在canvas上绘制一次视频元素。

视频组件

代码语言:javascript
复制
import React, { useEffect, createRef } from 'react'
import Canvas from './Canvas'

export default function Video({ streamManager }) {
  const videoRef = createRef()

  useEffect(() => {
    if (streamManager && !!videoRef) {

      //OpenVidu media server attaches the live stream to the video element 
      streamManager.addVideoElement(videoRef.current)
    }
  })

  return (
    <>
      //video element displays the live stream 
      <video autoPlay={true} ref={videoRef} />

      //extract canvas logic in new component
      <Canvas videoRef={videoRef} />

    </>
  )
}

画布组件

代码语言:javascript
复制
import React, { createRef, useEffect } from 'react'

export default function Canvas({ videoRef }) {
  const canvasRef = createRef(null)

  useEffect(() => {
    if (canvasRef.current && videoRef.current) {
      const interval = setInterval(() => {
        const ctx = canvasRef.current.getContext('2d')
        ctx.drawImage(videoRef.current, 0, 0, 250, 188)
      }, 100)
      return () => clearInterval(interval)
    }
  })

  return (
    <canvas ref={canvasRef} width="250" height="188" />
  )
}
票数 1
EN

Stack Overflow用户

发布于 2020-01-23 14:34:08

您正在使用不带参数的useEffect,这意味着您的useEffect将在每次渲染时调用

代码语言:javascript
复制
  useEffect(() => {
     // every render 
  })

如果只想在挂载时运行drawImage,那么可以使用带有[]的useEffect

代码语言:javascript
复制
  useEffect(() => {
      // run at component mount 
  },[])

或者,如果您想在任何参数更改时运行drawImage,则将参数传递给它

代码语言:javascript
复制
   useEffect(() => {
          // run when your streamManager change
      },[streamManager])

请按您的要求使用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59869004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档