Skip to content

Beginnercodinggamer228/CVRer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CVRer logo

CVRer

A Python library for creating videos that simulate typing code, with a smooth camera that follows the cursor.

Note: This is a reimplementation of the original CodeVideoRenderer and PypiProject by ZhuChongjing. The original uses manim as its rendering engine, which requires Microsoft C++ Build Tools to install on Windows. This version replaces manim entirely with Pillow + moviepy, so it works out of the box on any Python 3.8+ environment without any C++ compiler.


Differences from the original

Feature Original This version
Rendering engine manim Pillow + moviepy
Requires C++ Build Tools Yes No
Camera follow Smooth X+Y via manim scene Smooth X+Y via lerp per frame
Cursor blink Yes Yes
Glow effect moviepy moviepy (same)
reverse_typing No Yes
Custom font Yes (fonts/ folder) Yes (fonts/ folder)
Line numbers Yes Yes
center layout No Yes

Known limitations compared to the original:

  • No OpenGL renderer option (Cairo only in original, here it's Pillow)
  • No random typing interval variation per character (use interval_range=(0.08, 0.15) for variation — min/max are applied uniformly, not per-character randomly)
  • Camera follows cursor but does not do the subtle vertical oscillation the original does while typing a long line
  • formatter_style only supports pygments built-in styles — custom VS Code themes require passing color dicts manually

Requirements

Pillow>=9.0
pygments>=2.10
moviepy==1.0.3
rich>=13.0
proglog

Install:

pip install Pillow pygments "moviepy==1.0.3" rich proglog

Quick start

import sys
sys.path.insert(0, '/path/to/folder')  # folder containing CVRer/
from CVRer import CameraFollowCursorCV

cv = CameraFollowCursorCV(
    code=('string', """
def hello():
    name = "World"
    print(f"Hello, {name}!")
    return name

result = hello()
print(result)
"""),
    language='python',
    formatter_style='github-dark',
)
cv.render()

Output: CameraFollowCursorCV.mp4 in the current directory.


CameraFollowCursorCV

Constructor parameters

code — required

Source code to animate. Two formats:

# From a string
code=('string', 'print("hello")')

# From a file
code=('file', 'path/to/script.py')

The file must be UTF-8 encoded. Characters \r, \v, \f are not allowed.


language — required

Pygments language alias. Examples:

language='python'
language='html'
language='javascript'
language='typescript'
language='cpp'
language='rust'
language='go'
language='sql'
language='bash'
language='json'
language='yaml'

Full list: run from pygments.lexers import get_all_lexers; print(list(get_all_lexers())) or see CVRer/typing.py.


formatter_style — default: "github-dark"

Syntax highlight color theme. Must be a valid pygments style name.

formatter_style='github-dark'    # dark, GitHub-style
formatter_style='monokai'        # classic dark
formatter_style='dracula'        # purple dark
formatter_style='one-dark'       # Atom One Dark
formatter_style='nord'           # Nordic blue-grey
formatter_style='gruvbox-dark'   # warm retro dark
formatter_style='solarized-dark' # Solarized
formatter_style='vs'             # light, Visual Studio-like
formatter_style='xcode'          # light, Xcode-like

Full list:

from pygments.styles import get_all_styles
print(list(get_all_styles()))

font_size — default: 26

Font size in pixels. The library first looks for a .ttf file in CVRer/fonts/, then falls back to system fonts (Consolas, Courier New, Lucida Console).

font_size=20   # smaller, more code fits on screen
font_size=26   # default
font_size=32   # larger, easier to read

To use a custom font — place any .ttf file into CVRer/fonts/. It will be picked up automatically.


line_spacing — default: 1.5

Line height multiplier relative to the font's character height.

line_spacing=1.2   # compact
line_spacing=1.5   # default, comfortable
line_spacing=2.0   # spacious

interval_range — default: (0.15, 0.15)

Typing speed as (min_seconds, max_seconds) per character. This also determines the video FPS: fps = round(1 / min_seconds).

interval_range=(0.15, 0.15)   # 0.15s per char, ~7 fps — slow, readable
interval_range=(0.08, 0.08)   # 0.08s per char, ~12 fps — medium
interval_range=(0.05, 0.05)   # 0.05s per char, ~20 fps — fast
interval_range=(0.03, 0.03)   # 0.03s per char, ~33 fps — very fast

Currently both values must be equal. Per-character random variation is not yet implemented.


camera_scale — default: 1.0

Output video resolution scale.

camera_scale=1.0   # 1920x1080 (Full HD)
camera_scale=0.5   # 960x540
camera_scale=0.75  # 1440x810

camera_zoom — default: 2.0

How close the camera is to the code. Higher = more zoomed in, fewer characters visible at once.

camera_zoom=1.0   # wide view, lots of code visible
camera_zoom=1.5   # slightly zoomed
camera_zoom=2.0   # default, comfortable close-up
camera_zoom=3.0   # very close, ~20 chars per line visible

Internally this crops a smaller region of the canvas and upscales it to the output resolution.


camera_smooth — default: 0.25

Camera movement smoothing coefficient per frame. Range: 0.0 to 1.0.

camera_smooth=0.05   # very slow, cinematic drift
camera_smooth=0.15   # smooth, natural
camera_smooth=0.25   # default
camera_smooth=0.5    # snappy, follows cursor closely
camera_smooth=1.0    # instant, no smoothing

end_pause — default: 2.0

Seconds the video holds after all characters are typed. During this time the camera continues smoothly settling and the cursor keeps blinking.

end_pause=0.5   # quick cut
end_pause=2.0   # default
end_pause=5.0   # long hold

center — default: True

Whether to center the code block within the viewport. When True, the code appears in the middle of the frame rather than top-left.

center=True    # code centered in frame
center=False   # code starts at top-left

cursor_blink_rate — default: 0.5

Cursor blink period in seconds. The cursor is visible for half the period, hidden for the other half. Set to 0 to disable blinking.

cursor_blink_rate=0.5   # default, blinks every 0.5s
cursor_blink_rate=1.0   # slow blink
cursor_blink_rate=0.3   # fast blink
cursor_blink_rate=0     # no blinking, always visible

video_name — default: "CameraFollowCursorCV"

Output file name without the .mp4 extension. Can be an absolute path.

video_name='my_video'                          # saves as my_video.mp4 in cwd
video_name='C:/Users/User/Desktop/output'      # absolute path
video_name='renders/python_tutorial'           # relative subfolder

line_numbers — default: True

Show line numbers on the left side.

line_numbers=True    # show line numbers
line_numbers=False   # hide line numbers

glow — default: True

Apply a glow/bloom post-processing effect after rendering. Uses moviepy to process each frame with Gaussian blur + brightness boost. Adds noticeable processing time.

glow=True    # apply glow (slower, looks better)
glow=False   # skip glow (faster)

render() method

cv.render(
    output=True,           # print progress to console
    reverse_typing=False,  # erase code after end_pause
)

output — default: True

Print rendering progress, fps, resolution info and timing to the console.

reverse_typing — default: False

After the end_pause, erase all typed characters one by one in reverse order until the screen is completely empty. The cursor keeps blinking during erasure.

cv.render(reverse_typing=True)

Full example

import sys
sys.path.insert(0, 'C:/Users/User/Desktop/MPCode')
from CVRer import CameraFollowCursorCV

cv = CameraFollowCursorCV(
    code=('string', """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- Code -->
</body>
</html>
"""),
    language='html',
    formatter_style='github-dark',
    font_size=26,
    line_spacing=1.5,
    interval_range=(0.08, 0.08),
    camera_scale=1.0,
    camera_zoom=2.0,
    camera_smooth=0.15,
    end_pause=3.0,
    center=True,
    cursor_blink_rate=0.5,
    video_name='C:/Users/User/Desktop/output',
    line_numbers=True,
    glow=True,
)
cv.render(output=True, reverse_typing=False)

Load from file

cv = CameraFollowCursorCV(
    code=('file', 'C:/path/to/folder/script.py'),
    language='python',
    formatter_style='monokai',
    video_name='C:/Users/User/Desktop/script_video',
)
cv.render()

Available highlight styles

from pygments.styles import get_all_styles
print(sorted(get_all_styles()))
# ['abap', 'algol', 'arduino', 'autumn', 'dracula', 'emacs',
#  'friendly', 'fruity', 'github-dark', 'gruvbox-dark', 'gruvbox-light',
#  'inkpot', 'material', 'monokai', 'native', 'nord', 'nord-darker',
#  'one-dark', 'paraiso-dark', 'solarized-dark', 'solarized-light',
#  'tango', 'vim', 'vs', 'xcode', 'zenburn', ...]

About

f

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages