Automating Stockfish Evaluations for Chess Videos with Python
Rafael Vicente Leite
Entrepreneur | Founder of Chess Mentor LLC | Data Scientist | YouTube Creator | AI & Python Automation | Product Development | Open to Roles in Startups
As a chess content creator on YouTube, I always look for ways to enhance the viewing experience. One of the biggest challenges? Displaying Stockfish evaluations dynamically without spending hours manually editing graphics.
To solve this, I built a Python-based automation tool that: ? Detects the chessboard in video frames. ? Extracts the board position (FEN) automatically. ? Runs deep Stockfish evaluations (Depth 26). ? Generates SRT subtitles with evaluation bars for seamless overlay.
This allows viewers to toggle Stockfish evals on/off in the YouTube subtitle settings, letting them choose between pure analysis or engine-assisted insights. ????
?? GitHub Repo: github.com/rafaelvleite/youtube-eval-bar
?? Why Build This?
Manually adding evaluation graphics is slow and tedious. This system fully automates the process, making it easier to: ?? Analyze games efficiently in recorded videos. ?? Provide evaluation insights dynamically without editing. ?? Let viewers choose whether to see evals or just enjoy the commentary.
?? How It Works
The system follows four key steps:
1?? Frame Extraction & Chessboard Detection
The script analyzes video frames to detect the chessboard using OpenCV. Here’s the core function that finds the board in each frame:
import cv2
import numpy as np
def detect_chessboard(frame):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
largest_square = None
max_area = 0
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True)
if len(approx) == 4:
area = cv2.contourArea(approx)
if area > max_area:
max_area = area
largest_square = approx
if largest_square is not None:
x, y, w, h = cv2.boundingRect(largest_square)
return frame[y:y+h, x:x+w]
return None # No chessboard detected
2?? Extracting FEN from Video Frames
Once the board is detected, we convert it into FEN notation (the standard way to describe a chess position). This uses a deep learning model from board_to_fen.predict:
from PIL import Image
from board_to_fen.predict import get_fen_from_image
def extract_fen_from_frame(frame):
board_image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
detected_fen = get_fen_from_image(board_image)
return detected_fen.split(" ")[0] # Only board layout
It also automatically detects board orientation (White or Black) using OCR.
3?? Stockfish Evaluation at Depth 26
The extracted FEN is passed to Stockfish, the strongest open-source chess engine:
领英推荐
import chess
import chess.engine
STOCKFISH_PATH = "/opt/homebrew/bin/stockfish"
def evaluate_position(fen):
with chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH) as engine:
board = chess.Board(fen)
info = engine.analyse(board, chess.engine.Limit(depth=26))
eval_score = info["score"].white().score(mate_score=10000) / 100
return eval_score
The evaluation is stored, ready to be used in the subtitles.
4?? Generating SRT Subtitles with Evaluation Bars
The final step is generating a subtitle file (SRT) containing: ? A visual evaluation bar ? Numeric evaluation in full-width characters ? Time-synced entries
def draw_eval_bar(eval_score):
BAR_LENGTH = 24
ratio = min(1.0, max(0.0, (eval_score + 4) / 8.0)) # Normalize to range
filled = int(round(ratio * BAR_LENGTH))
return "▓" * filled + "?" * (BAR_LENGTH - filled)
def fullwidth_eval(eval_score):
mapping = {'0': '0', '1': '1', '2': '2', '3': '3', '4': '4',
'5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
'.': '.', '-': '-', '+': '+'}
return "".join(mapping.get(ch, ch) for ch in f"{eval_score:+5.2f}")
def write_srt_subtitle(start_sec, end_sec, eval_score, subtitle_index, srt_file):
start_tc = format_timecode(start_sec)
end_tc = format_timecode(end_sec)
bar = draw_eval_bar(eval_score)
numeric = f"[{fullwidth_eval(eval_score)}]"
srt_file.write(f"{subtitle_index}\n{start_tc} --> {end_tc}\n{bar} {numeric}\n\n")
Example output in an SRT file:
1 00:00:10,000 --> 00:00:20,000 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓?????? [+3.20]
This means White has a +3.20 advantage at this moment.
?? Final Output: A Fully Automated Chess Evaluation Overlay
With the generated .srt file, I can simply import it into YouTube or any video editor. The eval bar appears as subtitles, giving viewers the ability to toggle it on/off as they wish.
?? Full Project & Code
All the code for this project is available here: ?? GitHub Repo: github.com/rafaelvleite/youtube-eval-bar
?? What’s Next?
This system is already improving my chess videos, but I have plans to: ? Integrate it into live streams (Twitch/YouTube Live). ? Enhance board detection with deep learning. ? Add customization options for eval bar colors & animations.
?? Your Thoughts?
Would you use an automated Stockfish evaluation system like this for your chess videos? Let me know your thoughts & suggestions! ??????
Seasoned Engineering Leader
3 周Genial! Cada vez mais f?! O maneiro é que dá pra ver real time nas partidas que vc joga como ta!
Technology
1 个月Genial Rafa!
Sócio-Diretor @ Noale Energia | Engenharia e Finan?as | Professor do MBA Gest?o para o Setor Elétrico | Mestrando em Ciência da Computa??o com ênfase em Inteligência Artificial
1 个月Grande Rafa! Que demais ... muito útil e criativo!! parabéns ??
| Databricks | Data Engineering |
1 个月Amazing chess and tech content my friend!
Msc in Economics
1 个月Sensacional!! O melhor que temos