[Python] How to Continuously Record High-Quality APNG from a Webpage Like a Video Recorder?

Discussão em 'Python' iniciado por Stack, Março 13, 2025.

  1. Stack

    Stack Membro Participativo

    I have written a Python script that records high-quality APNG frames from the first page of a given URL. The script captures frames at 60 FPS and saves them as PNG images, which I later convert into an APNG video.

    Here is my code:

    from playwright.sync_api import sync_playwright
    import keyboard
    import time
    import os
    import threading
    import queue
    from PIL import Image
    import io

    # Output folder
    output_folder = r"E:\Desktop\New folder (4)\New folder (3)"
    os.makedirs(output_folder, exist_ok=True) # Ensure directory exists

    capturing = False # Flag to control capturing state
    frame_count = 0
    screenshot_queue = queue.Queue()
    lock = threading.Lock() # Prevent race conditions

    # Function to listen for keyboard inputs
    def listen_keys():
    """ Listens for keyboard input to start/stop capturing or exit script. """
    global capturing
    while True:
    if keyboard.is_pressed("F3"): # Start capturing
    if not capturing:
    print(" Starting 60 FPS screenshot recording...")
    capturing = True

    if keyboard.is_pressed("F4"): # Stop capturing
    if capturing:
    print(" Stopping screenshot recording...")
    capturing = False

    if keyboard.is_pressed("F5"): # Close browser
    print("❌ Closing browser...")
    os._exit(0) # Force close script

    time.sleep(0.02) # Reduce CPU usage while keeping responsiveness

    # Function to process and save screenshots from the queue
    def save_screenshots():
    """ Saves screenshots from the queue to disk asynchronously. """
    while True:
    frame_data = screenshot_queue.get()
    if frame_data is None:
    break # Exit thread if None is received

    frame_number, image_data = frame_data
    screenshot_path = os.path.join(output_folder, f"frame_{frame_number:04d}.png")

    try:
    # Convert in-memory image to file
    image = Image.open(io.BytesIO(image_data))
    image.save(screenshot_path, "PNG")
    print(f"✅ Saved: {screenshot_path}")
    except Exception as e:
    print(f"⚠️ Error saving frame {frame_number}: {e}")

    screenshot_queue.task_done()

    # Start the screenshot saving thread
    saver_thread = threading.Thread(target=save_screenshots, daemon=True)
    saver_thread.start()

    with sync_playwright() as p:
    browser = p.firefox.launch(headless=False) # Launch Firefox (visible)
    context = browser.new_context(device_scale_factor=4) # High-quality scaling
    page = context.new_page()

    print("Loading page...")
    page.goto("https://public.flourish.studio/visualisation/21660262/", timeout=60000)
    page.set_viewport_size({"width": 1920, "height": 1080}) # Maximize viewport

    print("Press F3 to start recording screenshots at 60 FPS...")
    print("Press F4 to stop recording...")
    print("Press F5 to close browser...")

    # Start key listener in a separate thread
    key_listener = threading.Thread(target=listen_keys, daemon=True)
    key_listener.start()

    while True:
    if capturing:
    start_time = time.time()
    for _ in range(60): # Capture 60 frames per second
    with lock:
    frame_count += 1

    # Capture screenshot into memory (buffer)
    try:
    buffer = page.screenshot(full_page=True) # Removed omit_background=True
    screenshot_queue.put((frame_count, buffer)) # Push to queue
    except Exception as e:
    print(f"⚠️ Screenshot failed: {e}")

    # Maintain 60 FPS timing
    elapsed_time = time.time() - start_time
    sleep_time = (1 / 60) - elapsed_time % (1 / 60)
    if sleep_time > 0:
    time.sleep(sleep_time)

    else:
    time.sleep(0.1) # Reduce CPU usage when idle


    The Issue:

    I want this script to behave like a real screen recording tool, continuously capturing every frame from the webpage. However, the script only records 60 frames total and then stops after 5-7 seconds, instead of continuing indefinitely at 30 FPS or more.

    My Goal:

    I need my script to record the entire animation of the bar chart race on the website (example: Flourish Studio Bar Chart Race) frame by frame in very high-quality PNG sequences, which I can later convert to APNG.

    What I Need Help With:


    1. Why is my script only recording 60 frames and stopping instead of continuing like a video recorder?


    2. How can I modify my script so that it continuously records at 30 FPS or 60 FPS without stopping until I press F4?


    3. If there is a better way to achieve high-quality frame-by-frame recording directly from a webpage, please suggest it.

    Important Notes:


    • I do not want to use external screen recording tools (they do not match the quality of my script).


    • This script captures images directly from the webpage and maintains ultra-high quality, even when zooming in on frames.


    • If there is a better method to improve my script, I would appreciate suggestions.

    Continue reading...

Compartilhe esta Página