Merge pull request #419 from rajtiwariee/fix/video-blur

fix: resolve blurry screen recordings and video editor previews
This commit is contained in:
Sid
2026-04-25 16:52:48 -07:00
committed by GitHub
4 changed files with 32 additions and 16 deletions
+19 -2
View File
@@ -753,7 +753,6 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
blurFilter.resolution = app.renderer.resolution;
blurFilter.blur = 0;
const motionBlurFilter = new MotionBlurFilter([0, 0], 5, 0);
videoContainer.filters = [blurFilter, motionBlurFilter];
blurFilterRef.current = blurFilter;
motionBlurFilterRef.current = motionBlurFilter;
@@ -801,7 +800,7 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
videoContainer.mask = null;
maskGraphicsRef.current = null;
if (blurFilterRef.current) {
videoContainer.filters = [];
videoContainer.filters = null;
blurFilterRef.current.destroy();
blurFilterRef.current = null;
}
@@ -858,6 +857,7 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
state.appliedScale = appliedTransform.scale;
};
let lastMotionBlurActive: boolean | null = null;
const ticker = () => {
const { region, strength, blendedScale, transition } = findDominantRegion(
zoomRegionsRef.current,
@@ -1015,6 +1015,23 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
motionIntensity,
motionVector,
);
const isMotionBlurActive = (motionBlurAmountRef.current || 0) > 0 && isPlayingRef.current;
if (isMotionBlurActive !== lastMotionBlurActive && videoContainerRef.current) {
if (isMotionBlurActive) {
if (blurFilterRef.current && motionBlurFilterRef.current) {
videoContainerRef.current.filters = [
blurFilterRef.current,
motionBlurFilterRef.current,
];
lastMotionBlurActive = true;
}
} else {
videoContainerRef.current.filters = null;
lastMotionBlurActive = false;
}
}
};
app.ticker.add(ticker);
+6 -2
View File
@@ -122,11 +122,15 @@ export function useScreenRecorder(): UseScreenRecorderReturn {
}, []);
const selectMimeType = () => {
// H.264 first: hardware-accelerated on all modern devices, gives sharp
// real-time output. AV1/VP9 are great for distribution but too
// CPU-intensive for live 60 fps capture — they produce blurry frames
// when the software encoder can't keep up.
const preferred = [
"video/webm;codecs=av1",
"video/webm;codecs=h264",
"video/webm;codecs=vp9",
"video/webm;codecs=vp8",
"video/webm;codecs=vp9",
"video/webm;codecs=av1",
"video/webm",
];
+6 -1
View File
@@ -7,5 +7,10 @@
"allowSyntheticDefaultImports": true,
"strict": true
},
"include": ["vite.config.ts"]
"include": [
"vite.config.ts",
"electron-builder.json5",
"playwright.config.ts",
"vitest.config.ts"
]
}
+1 -11
View File
@@ -9,25 +9,15 @@ export default defineConfig({
react(),
electron({
main: {
// Shortcut of `build.lib.entry`.
entry: "electron/main.ts",
vite: {
build: {},
},
},
preload: {
// Shortcut of `build.rollupOptions.input`.
// Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
input: path.join(__dirname, "electron/preload.ts"),
},
// Ployfill the Electron and Node.js API for Renderer process.
// If you want use Node.js in Renderer process, the `nodeIntegration` needs to be enabled in the Main process.
// See https://github.com/electron-vite/vite-plugin-electron-renderer
renderer:
process.env.NODE_ENV === "test"
? // https://github.com/electron-vite/vite-plugin-electron-renderer/issues/78#issuecomment-2053600808
undefined
: {},
renderer: process.env.NODE_ENV === "test" ? undefined : {},
}),
],
resolve: {