Open zypy333 opened 3 years ago
暂时还没计划
查了资料有3种办法可以从一个webgl上面截图,但是我们没法修改源码,经过不断尝试,我发现一种很hacky
的办法,成功率
几乎100%
。
// 获取截取到的pixels
const generatePixelsFromWebgl = webGlCanvas => {
if (!webGlCanvas) return
const gl = webGlCanvas.getContext('webgl', { preserveDrawingBuffer: true })
const { drawingBufferHeight: height, drawingBufferWidth: width } = gl
const pixels = new Uint8Array(4 * width * height)
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels)
return pixels
}
// 判断像素是不是空的
const judgeWetherCaptureSuccess = pixels => {
if (!pixels) return false
return !pixels.subarray(0, 128).every(pixel => pixel === 0) // 如果全部是0就是失败
}
// 等到下一帧绘制之前
const waitToNextFrame = () => {
return new Promise(resolve => {
requestAnimationFrame(resolve)
})
}
/**
* 该方法参数可以自行修改
* @param {easy player 实例} player
* @param {当前播放的设备名称,只是用来命名截图得到的图片} deviceName
*/
export const setH265PlayerCover = async function(player, deviceName) {
let MAX_CAPTURE_RETRY_COUNT = 10
const IMAGE_FORMAT = 'jpeg'
return new Promise(async (resolve, reject) => {
const playerUI = player?.playerUI
if (!playerUI) return reject(new Error('player ui is null'))
let isSuccess = false
let canvas = null
while (MAX_CAPTURE_RETRY_COUNT > 0 && !isSuccess) {
// 还有尝试次数并且没有成功就再次执行
MAX_CAPTURE_RETRY_COUNT -= 1
await waitToNextFrame()
canvas = playerUI.querySelector('canvas')
if (!canvas) {
return reject(new Error('cavans is null'))
}
const pixels = generatePixelsFromWebgl(canvas)
isSuccess = judgeWetherCaptureSuccess(pixels)
}
if (isSuccess) {
canvas.toBlob(
async blob => {
const snapFileName = `${deviceName}-${Date.now()}.${IMAGE_FORMAT}`
const url = URL.createObjectURL(blob)
const res = {url, name: snapFileName}
resolve(res)
},
`image/${IMAGE_FORMAT}`,
0.75
)
} else {
reject(new Error('reach max retry count'))
}
})
}
@zypy333
will snapshot be spported in the future?