{"id":"cctv-night-cam","version":"1.0.0","title":"CCTV Night Cam (Security Camera Footage)","summary":"Makes any animation look like a security camera recording at night: wide-lens bulge, choppy frame rate, grain, blocky compression, a running timestamp, REC and a motion-detection box.","kind":"effect","target":"three","collections":["backgrounds","kinetic-text"],"tags":["cctv","security camera","surveillance","night vision","infrared","found footage","horror","halloween","analog horror","caught on camera","text overlay","timestamp","rec","motion detection","fisheye","liminal","backrooms","creepy","2d","canvas"],"loopable":false,"motion":"procedural","durationSeconds":10,"status":"published","media":{"poster":"https://aipixelwizard.com/media/cctv-night-cam/1.0.0/poster.webp","preview":"https://aipixelwizard.com/media/cctv-night-cam/1.0.0/preview.mp4","sample":"https://aipixelwizard.com/media/cctv-night-cam/1.0.0/sample.mp4","sampleBytes":3652203,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/cctv-night-cam","manifest":"https://aipixelwizard.com/api/v1/visuals/cctv-night-cam/versions/1.0.0","agentMd":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/agent.md","files":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/","demo":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/index.html"},"description":"The look behind the AI 'caught on camera' and found-footage horror clips that fill feeds every October. Whatever you draw goes through a cheap night-time security camera: the wide lens bulges the middle of the picture, the picture turns black-and-white infrared (or green night vision, or washed-out colour), fine detail goes soft but edges get the camera's over-sharpened halos, grain climbs as the auto-gain fights the dark, shadows break into blotchy compression blocks and lights bloom. The camera runs at a choppy 8–15 frames a second and now and then stalls on a frame. On top, the recorder's display stays crisp: date and a ticking clock, a blinking REC, the camera number and its name, and a motion box that blinks when something appears. The demo watches an empty corridor from a camera high in the corner at 3 a.m.; the lights cut out twice, and each time they come back a tall figure stands closer. Choose the place (Backrooms, office, hospital ward), the look, the date, time, camera name and how cheap the camera is.","role":"Full-frame finishing effect (Canvas 2D) plus a recorder display, a motion-detection box and a camera frame-rate helper.","useCases":["Found-footage or analog-horror shorts for Halloween ('something is in the hallway')","Framing an AI 'caught on camera' clip so it reads as security footage (label it as fiction)","Teasers and trailers for horror games, films and escape rooms","A creepy cold open or transition in a longer edit"],"synonyms":["cctv effect","cctv filter","cctv overlay","security camera effect","security cam footage","security camera filter","surveillance footage look","night vision effect","ir camera look","found footage effect","found footage horror","ai cctv footage","caught on camera","doorbell cam look","ring cam style","dvr timestamp overlay","camera timestamp","motion detected box","analog horror","backrooms footage"],"digest":"d306e71094d774d74f3f0bc16c5bcc221d7ee61b149e4688514e99807aa59aa8","implementation":{"target":"three","runtime":"browser","language":"javascript","module":"esm","entry":"src/cctv-night-cam.js","exports":[{"name":"createCCTV","signature":"createCCTV({ look?, fisheye?, softness?, sharpen?, noise?, compression?, bloom?, autoGain?, vignette?, seed? }) => { apply(ctx, width, height, info), lensPoint(x, y, width, height) }","description":"The camera. apply() reads the 2D canvas and replaces it with the recording: lens bulge, auto-gain, soft but over-sharpened picture, grain, compression blocks, bloom and the colour look. lensPoint() tells you where a scene point lands after the lens, for boxes and labels."},{"name":"cameraTime","signature":"cameraTime(info, { fps?, hiccups?, seed? }) => { ...info, time, frame, fps, sourceFrame }","description":"The recorder's choppy frame rate with the odd stalled frame. Draw your scene at the returned time and pass the result to apply() and the overlay."},{"name":"drawCCTVOverlay","signature":"drawCCTVOverlay(ctx, width, height, info, { date?, clock?, camera?, label?, rec?, color?, recColor?, scale? })","description":"The recorder display: date and running clock top left, blinking REC top right, camera number bottom left, its name bottom right, in a blocky outlined recorder font."},{"name":"drawMotionBox","signature":"drawMotionBox(ctx, { x, y, w, h }, info, { label?, color?, blink?, scale? })","description":"A motion-detection box: thin frame, heavy corner brackets and a label tag. Blinks while blink is true."},{"name":"drawPixelText","signature":"drawPixelText(ctx, text, x, y, { cell?, color?, outline?, tracking?, align? }) => width","description":"Any text in the built-in 5×7 recorder font (A–Z, 0–9, : - / . # ! ') with a dark outline."},{"name":"measurePixelText","signature":"measurePixelText(text, cell, tracking?) => width","description":"Width of text in the recorder font, for layout."}],"reusable":["src/cctv-night-cam.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"liminal-corridor","version":"1.0.0","scope":"demo","reason":"The demo films this corridor from a fixed corner camera. src/cctv-night-cam.js has no dependencies and works on any 2D canvas."},{"id":"three","version":"0.185.1","scope":"demo","reason":"Renders the demo's corridor."},{"id":"apw-runtime","version":"1.0.0","scope":"demo","reason":"Demo harness."}],"uses":[],"usedBy":[],"params":[{"key":"place","label":"Demo place","help":"Which corridor the camera watches. Your own project can put anything through the camera.","type":"select","default":"backrooms","options":[{"value":"backrooms","label":"Backrooms (yellow, carpet)"},{"value":"office","label":"Office after hours"},{"value":"hospital","label":"Hospital ward"}]},{"key":"look","label":"Camera look","type":"select","default":"ir","options":[{"value":"ir","label":"Infrared black and white"},{"value":"green","label":"Green night vision"},{"value":"color","label":"Cheap colour camera"}]},{"key":"figure","label":"Something in the hallway","help":"The figure that appears after each power cut. Turn off for an empty corridor.","type":"boolean","default":true},{"key":"motionBox","label":"Motion box","help":"The recorder's box around the figure, blinking when it first appears.","type":"boolean","default":true},{"key":"date","label":"Date","help":"Shown top left. Letters, numbers, spaces and : - / . work.","type":"text","default":"2026-10-31","maxLength":14,"sensitive":true},{"key":"clock","label":"Start time","help":"HH:MM:SS. The seconds tick on as the clip plays.","type":"text","default":"03:14:07","maxLength":8,"sensitive":true},{"key":"camera","label":"Camera number","type":"text","default":"CAM 04","maxLength":10,"sensitive":true},{"key":"label","label":"Camera name","help":"Shown bottom right. Leave empty to hide it.","type":"text","default":"HALLWAY B","maxLength":14,"sensitive":true},{"key":"rec","label":"Blinking REC","type":"boolean","default":true},{"key":"cameraFps","label":"Camera frame rate","help":"Security recorders store few frames a second; lower is choppier.","type":"integer","min":5,"max":30,"step":1,"default":12},{"key":"fisheye","label":"Wide-lens bulge","type":"number","min":0,"max":1,"step":0.05,"default":0.6},{"key":"noise","label":"Grain","help":"Sensor grain. It climbs on its own when the picture goes dark.","type":"number","min":0,"max":1,"step":0.05,"default":0.5},{"key":"compression","label":"Compression blocks","help":"How blotchy and blocky the shadows get.","type":"number","min":0,"max":1,"step":0.05,"default":0.55},{"key":"softness","label":"Softness","help":"How much fine detail the cheap camera loses.","type":"number","min":0,"max":1.5,"step":0.05,"default":0.7},{"key":"bloom","label":"Light glow","type":"number","min":0,"max":1.5,"step":0.05,"default":0.6},{"key":"seed","label":"Variation","help":"Changes the grain, the stalled frames, the flicker of the faulty light and the corridor's details.","type":"integer","min":1,"max":9999,"step":1,"default":4}],"presets":[{"id":"default","label":"Hallway B, 3:14 AM","params":{}},{"id":"office","label":"Office after hours","params":{"place":"office","look":"color","date":"10/31/2026","clock":"23:52:40","camera":"CAM 11","label":"LOBBY 2F","cameraFps":15,"fisheye":0.45,"noise":0.4,"compression":0.65,"bloom":0.45,"seed":21}},{"id":"ward","label":"Ward 7 night vision","params":{"place":"hospital","look":"green","date":"31.10.2026","clock":"02:47:19","camera":"CH-07","label":"WARD 7","cameraFps":8,"fisheye":0.8,"noise":0.7,"compression":0.5,"softness":0.9,"bloom":0.8,"seed":7}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":10,"posterSeconds":8.5,"alpha":false,"motion":"procedural","loop":{"seamless":false,"method":"A ten-second story beat (two power cuts, a figure that comes closer); it does not loop."},"seed":{"param":"seed","behavior":"Seed sets the grain, which camera frames stall, the faulty tube's flicker, the strobing of the power cuts and the corridor's details. Same seed, same frames."}},"composition":{"inputs":"Canvas 2D context, width, height and the frame info from cameraTime(). apply() takes whatever is already drawn on the canvas.","outputs":"apply() replaces the frame with the recording (opaque). drawCCTVOverlay and drawMotionBox draw on top without clearing.","coordinates":"Pixels. Effect sizes are tuned at 1080 wide and scale with the canvas. The display sits 5.5% in from the edges.","lighting":"None of its own. Auto-gain brightens dark frames and their grain; bloom makes bright areas glow.","timing":"Pure function of the camera frame from cameraTime(): grain changes every camera frame and is held on a stalled one; the clock ticks with time; REC blinks once a second.","compatibleWith":["liminal-corridor","vhs-camcorder","rain-window","thunderstorm","glitch-text"],"notes":["Draw your scene at cameraTime(info).time, not info.time, or the choppy frame rate is lost.","Draw the display and motion box after apply() so they stay crisp, as a recorder adds them. Use lensPoint() to bend a box measured in your scene so it sits on the bulged picture.","apply() reads pixels back, so the canvas must be same-origin. For three.js, render to its own canvas and drawImage it onto the 2D canvas first, as the demo does.","The date and time are plain text you choose; nothing reads the real clock, so renders stay repeatable."]},"reuse":["Turn any AI 'caught on camera' clip into convincing security footage: draw each frame of the clip at cameraTime(info).time, apply(), add drawCCTVOverlay with your own date and camera name, and say in the caption that it is fiction.","Watch Rain on a Window or Thunderstorm through the camera with look 'color' for a stormy-night doorbell-cam shot.","A horror title card: draw Glitch Text or a plain title, apply() with look 'green', and set the camera name to your film's title.","A four-camera DVR grid: render four scenes into quarters of the frame, call apply() on each quarter's canvas and give each its own CAM number."],"integration":{"newProject":"Create the camera once with createCCTV(options). Each frame: const cam = cameraTime(info, { fps: 12 }); draw your scene at cam.time; cctv.apply(ctx, width, height, cam); drawCCTVOverlay(ctx, width, height, cam, { date, clock, camera, label }); optionally drawMotionBox around something moving.","existingProject":"Copy src/cctv-night-cam.js. At the end of your 2D frame call cctv.apply(ctx, width, height, cameraTime(info)), then drawCCTVOverlay. For WebGL, render to its own canvas and drawImage it onto a 2D canvas each frame, then apply there."},"performance":{"notes":"One lens remap and a few running-sum blurs over every pixel, plus the demo's corridor shader: about 0.3–0.6 s a frame at 1080×1080 in headless Chrome on a CPU-only render machine. Fine for offline renders; live previews play at a few frames a second.","limits":"Cost grows with pixel count. For live use, render at 540 or 720 and scale up; a security camera was never sharp anyway."},"limitations":["It degrades what it is given: it cannot make an AI clip's motion believable or fix impossible physics. The camera angle has to be right in the scene you feed it (high, fixed, wide).","The demo's figure is a flat silhouette: it reads at corridor distance and through the camera, not in close-up.","The recorder font covers capital letters, digits and a few symbols only; there are no accented letters.","Footage this convincing can mislead. Label fictional clips as fiction, especially anything that looks like evidence of a real event."],"license":{"spdx":"MIT","notice":"Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.","thirdParty":[]},"rights":{"approvedForPublicRelease":true},"provenance":"Original code written for AI Pixel Wizard on 2026-10-09 by an automated agent (the daily trend routine), inspired by the AI security-camera and found-footage horror clips of the Halloween season (see content/trends/2026-10-09-cctv-night-cam.md). The list of tells to reproduce (timestamp and camera ID overlay, low resolution and 8–15 fps, grain, compression, lens distortion, high fixed corner angle, low light and fluorescent flicker) follows https://www.topmediai.com/video-tips/ai-cctv-footage/. Barrel distortion, unsharp masking, box blurs and block-wise quantisation are standard image-processing techniques; the code, the 5×7 recorder font and the figure were all written for this package. The demo's corridor is AI Pixel Wizard's own Liminal Corridor 1.0.0, imported unchanged. No code, images, fonts or shaders were copied.","changelog":[{"version":"1.0.0","date":"2026-10-09","notes":"Initial release."}],"verification":{"testedOn":"2026-10-10","inputs":{"cctv-night-cam@1.0.0":"d306e71094d774d74f3f0bc16c5bcc221d7ee61b149e4688514e99807aa59aa8","liminal-corridor@1.0.0":"10295ac2509bf13585d28f564c2b3f17662d1d0902ad362c8b696357bfc4aa74","three@0.185.1":"664ca387e5fab46ff2daaa6895e1d015426850891af5ea5082cbbcc3985b068c","apw-runtime@1.0.0":"5be859cdac74823ba0bcc32c6daf06688a871104d24db5d4ceaffffd84d7c40d"},"environment":"Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0","renderer":"WebGL 2 via SwiftShader (software)","width":1080,"height":1080,"fps":30,"frames":300,"renderSeconds":225.1,"loopCheck":{"checked":false,"seamless":null,"maxDifference":null,"note":"Asset does not claim a seamless loop."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/cctv-night-cam/1.0.0/poster.webp","preview":"/media/cctv-night-cam/1.0.0/preview.mp4","sample":"/media/cctv-night-cam/1.0.0/sample.mp4","sampleBytes":3652203}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/LICENSE"},{"path":"asset.json","size":15901,"sha256":"63ac406d823add030b30da253561d954eef58853cef1a33e9796141a8657178a","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/asset.json"},{"path":"demo.js","size":9945,"sha256":"8409d08cea8e471b31428fe3526717a1837ff67c2d74fa5cfea4dd48eebccc19","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/demo.js"},{"path":"index.html","size":528,"sha256":"9417787c3b092ef0c11749b7ff33b776ee204858f822d4dce2f38f5ab7ad6387","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/index.html"},{"path":"src/cctv-night-cam.js","size":24313,"sha256":"eff20104fe20d85d5c07ba6d3cffdd1ab1eca42d82ba016ba2b942c8424da895","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/cctv-night-cam/1.0.0/src/cctv-night-cam.js"}],"warnings":[]}