提问人:palomino 提问时间:11/16/2023 更新时间:11/16/2023 访问量:31
将 mapbox-gl 放在一个 worker 中,并使用 readpixels() 读取以在主线程中编码
put mapbox-gl in a worker and read with readpixels() to encode in the main thread
问:
这是我第一次在 Stackoverflow 上提问,这是因为我真的被卡住了。我在 mapbox 中有一个动画,它与 h264-mp4-encoder 视频编码器在同一线程上运行。我的代码可以工作并完成工作,但是在渲染地图框动画期间,您会看到小的跳跃,有时还会出现振动,我确信这是因为这两个任务都是在同一线程中执行的。我试图创建一个用于编码的工作器,但我有错误,因为编码器需要 mapbox 实例。我正在研究offscreencanvas,但关于使用webgl的信息并不多。也许你可以推荐一种不同的方法来处理这个问题,要么将编码器发送给一个工作线程,要么将映射框发送给另一个工作线程,或者如果你打开了一个更好的方法来解决这个问题,那就更好了。
map.on("load", async () => {
// add 3d, sky and fog
add3D();
await map.once("idle");
// don't forget to enable WebAssembly SIMD in chrome://flags for faster encoding
const supportsSIMD = await simd();
// initialize H264 video encoder
const Encoder = await loadEncoder({ simd: supportsSIMD });
const gl = map.painter.context.gl;
const width =
gl.drawingBufferWidth % 2 === 0
? gl.drawingBufferWidth
: gl.drawingBufferWidth - 1;
const height =
gl.drawingBufferHeight % 2 === 0
? gl.drawingBufferHeight
: gl.drawingBufferHeight - 1;
//create encoder
const encoder = Encoder.create({
width,
height,
fps: 30,
kbps: 2200,
rgbFlipY: true,
});
// stub performance.now for deterministic rendering per-frame (only available in dev build)
let now = performance.now();
//mapboxgl.setNow(now);
const ptr = encoder.getRGBPointer(); // keep a pointer to encoder WebAssembly heap memory
function frame() { //this function is called to read the pixels every time mapbox re-renders
//increment stub time by 16.6ms (60 fps)
now += 1000 / 30;
mapboxgl.setNow(now);
const pixels = encoder.memory().subarray(ptr); // get a view into encoder memory
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); // read pixels into encoder
console.log("inicia");
encoder.encodeRGBPointer(); // encode the frame
}
map.on("render", frame); // set up frame-by-frame
await playAnimations(geojson);//a call is made to the map animation function
// stop recording
map.off("render", frame);
mapboxgl.restoreNow();
setIsRunAnimate(false);
//encoded video
const mp4Blob = encoder.end();
setVideoBlob(mp4Blob);
})
这是一个相信的工人,认为他可以实现它。我尝试的是读取工作器内部的像素并对其进行编码,但它给了我一个错误,因为它需要 mapboxgl。
// encoderWorker.js
let encoding = false;
let now = performance.now();
let ptr;
onmessage = async (event) => {
const { width, height, fps, kbps, rgbFlipY } = event.data;
const { simd } = await import("wasm-feature-detect");
const Encoder = await import("../../assets/convertidor.js");
const encoder = Encoder.create({
width,
height,
fps,
kbps,
rgbFlipY,
});
ptr = encoder.getRGBPointer();
function encodeFrame() {
now += 1000 / fps;
mapboxgl.setNow(now);
const pixels = encoder.memory().subarray(ptr);
encoder.encodeRGBPointer();
}
onmessage = (event) => {
const { type } = event.data;
if (type === "start" && !encoding) {
// Start coding/frame-by-frame
encoding = true;
encodeFrame();
requestAnimationFrame(encodeFrame);
} else if (type === "finish" && encoding) {
// Stop encryption
encoding = false;
// Return the encoded blob to the main thread
const encodedBlob = encoder.end();
postMessage({ type: "complete", encodedBlob });
}
};
};
答: 暂无答案
上一个:WebGL 球体旋转
评论