Recording a Video, and Speed
Every frame is exact
Every effect is worked out from the picture, its own last frame, its settings and the scene's clock, never from the time of day; grain and glitches come from a seed. So a scene stepped one frame at a time gives exactly the pictures it should: the same scene stepped twice gives the very same pixels, and a film at 30 frames a second matches one at 60 at the same moments.
A film, in JavaScript
On a page of your own, visualfx.js can make the film itself:
const film = await recordVideo({ seconds: 5, fps: 60 }) // a WebM, every frame exactly 1/60 apart
saveVideo(film, "my-scene.webm")
recordVideo needs a browser that can encode video (Chrome, Edge, Safari). There is no sound in the film.
renderFrames gives the frames one at a time instead, each on a canvas, for you to do as you like with:
let count = 0
await renderFrames({ seconds: 2, fps: 30, onFrame: (canvas, n, time) => { count = n } })
| Function | What it does |
|---|---|
recordVideo({ seconds, fps }) | A film of the scene as a WebM file. 5 seconds at 60 frames a second unless you say |
saveVideo(film, name) | Saves the film as a file the browser downloads |
renderFrames({ seconds, fps, onFrame }) | Each finished picture in turn: onFrame(canvas, n, time) |
These three are JavaScript's. pyvisualfx has none of them: a Python scene is recorded by whatever runs it.
In Circuitry
Record Video, under a preview, records a scene a frame at a time, on a stepped clock. The effects are made for that. They take their time from the scene's own clock, so a recording of a scene has the effects in it, on the right frame, with nothing more to do, in JavaScript and in Python, and they are the same every time.
The sound is stepped with the picture too, so effects that move to the music (bass(), pulse(), react) move to the music that is in the video. See A video with its sound.
The three names above (recordVideo, saveVideo, renderFrames) are for a page of your own that has no recorder. In Circuitry the button is the way.
How fast it is
The scene's canvas is handed to the graphics card once a frame, and each effect is then one or a few passes over the picture. The effects themselves are cheap everywhere. The hand-over is not cheap in Safari's engine, which every browser on an iPad and an iPhone uses, so the library works on fewer pixels there when it must:
effectsQuality("auto") // the default: fewer pixels when frames are late
effectsQuality(1) // every pixel
effectsQuality(0.5) // half each way"auto"starts a touch device at about a 1080p picture's worth of pixels, and whenever the hand-over takes too long it works on fewer, never fewer than one for each of the scene's points. The picture is stretched back on the screen.- Under a recorder's stepped clock nothing is ever late, so a recording keeps every pixel.
- A scene with no effect on costs what it did before: there is no second canvas and nothing on the graphics card.
- A few effects look at many places for every pixel and cost more than the rest. Every effect says which.
When a scene stops, everything it had on the graphics card is given back. If the graphics card takes its work away (a tablet does, to a tab in the background), the effects are made again when it comes back.