直播 HTML5 视频绘制到画布不工作
Posted
技术标签:
【中文标题】直播 HTML5 视频绘制到画布不工作【英文标题】:Live stream HTML5 video draw-to-canvas not working 【发布时间】:2020-05-09 03:52:08 【问题描述】:我使用 ReactJS 来显示一个使用 html5 视频元素的实时流(来自我的网络摄像头)。 OpenVidu 媒体服务器处理后端。
我想使用 canvas
元素使用 drawImage() 方法将视频直播流绘制到画布上。
我见过其他示例,但其中的视频元素总是有来源。我的没有来源 - 当我检查视频元素时,我看到的是:
<video autoplay id="remote-video-zfrstyztfhbojsoc_CAMERA_ZCBRG"/>
这是我尝试过的,但是画布不起作用。
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 />
</>
)
更新:经过进一步调查,我意识到我需要使用 setInterval() 函数,因此提供了以下解决方案。
【问题讨论】:
【参考方案1】:您正在使用不带参数的 useEffect,这意味着您的 useEffect 将在每个渲染中调用
useEffect(() =>
// every render
)
如果你只想在挂载时运行你的 drawImage,那么使用 useEffect 和 []
useEffect(() =>
// run at component mount
,[])
或者如果您想在任何参数更改时运行drawImage,然后将您的参数传递给它
useEffect(() =>
// run when your streamManager change
,[streamManager])
根据您的要求使用它
【讨论】:
感谢您的观察,useEffect 确实缺少参数 [],但这不是问题,因为在这种情况下,组件不会多次重新渲染自身。经过进一步调查,我发现我的组件中只需要一个 setInterval() 函数,因此我提供了以下解决方案。【参考方案2】:解决方案是在自包含组件中提取canvas
逻辑,并使用setInterval()
以便它每100 毫秒(或根据需要)在canvas
上绘制视频元素。
视频组件
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 />
</>
)
画布组件
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 />
)
【讨论】:
以上是关于直播 HTML5 视频绘制到画布不工作的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS画布drawImage不显示html5视频元素