Piloter Bernard Review depuis un script ou un logiciel du pipeline. Le protocole, le client Python, toutes les commandes par famille, les événements et des exemples complets.
Bernard Review se pilote depuis Python, Maya, Nuke, Houdini, un outil de suivi de production ou tout langage capable d'ouvrir une connexion TCP. Tout ce qu'un artiste fait à la main a sa commande : ouvrir des plans, lire, comparer, étalonner, exporter, lancer une séance, publier des notes. Cette page suffit pour automatiser le lecteur ; la référence exhaustive, champ par champ, est la référence de l'API, en anglais (aussi ouverte par Help > API Documentation).
127.0.0.1, port 5556 par défaut. Un lecteur lancé avec --ipc-port N écoute sur N : c'est ainsi que deux lecteurs tournent sur la même machine.\n, avec un champ "cmd" : {"cmd": "seek", "frame": 24}.{"status": "ok", "cmd": "seek", ...} ou {"status": "error", "cmd": "seek", "reason": "..."}. Une erreur porte toujours une raison en clair et n'attend jamais l'expiration du délai. Il n'y a pas d'identifiant de requête : on associe une réponse à sa requête par son "cmd".{"event": ...}) arrivent sur la même connexion, mêlés aux réponses (voir plus bas).Host:) est fermée sans rien exécuter : une page web ne peut pas piloter le lecteur. Une ligne fait au plus 16 Mio.Pour essayer sans écrire de code : Window > Console (Ctrl+Maj+C) envoie les mêmes commandes depuis le lecteur, avec complétion par Tab : status, seek {"frame": 24}, ou la forme JSON complète. Elle demande confirmation avant les commandes qui écrivent des fichiers, publient ou ferment le lecteur.

bernard_api.py emballe le protocole dans une classe, BernardClient, avec une méthode par commande. Il est installé à côté du lecteur, dans le dossier api :
| Système | Emplacement |
|---|---|
| Windows | C:\Program Files\Bernard Review\bin\api\bernard_api.py |
| Linux (RPM) | /usr/share/bernardplayer/api/bernard_api.py |
Linux (archive .sh) | <dossier d'installation>/share/bernardplayer/api/bernard_api.py |
Il n'a besoin que de la bibliothèque standard de Python 3.
import sys
sys.path.append(r"C:\Program Files\Bernard Review\bin\api")
from bernard_api import BernardClient
client = BernardClient(host="127.0.0.1", port=5556)
if not client.connect():
raise SystemExit("Bernard Review ne répond pas sur le port 5556")
reply = client.open_media("D:/shots/SQ010_SH010_ANIM_v002.mov")
if reply is None or reply.get("status") == "error":
print("refusé :", reply and reply.get("reason"))
else:
client.play()
request(dict) envoie une commande et attend sa réponse (un dict), erreurs comprises : elle ne lève pas d'exception pour un refus du lecteur, et renvoie None en cas d'expiration ou de connexion perdue.send_command(dict) envoie sans attendre.play(), seek(), set_exposure(), export()...) appellent l'une ou l'autre ; celles qui renvoient des données passent par request().on("frame_changed", fonction) abonne une fonction à un événement ; un fil de fond lit la connexion.Sans le client, quelques lignes suffisent :
import json, socket
with socket.create_connection(("127.0.0.1", 5556)) as s:
f = s.makefile("rw", encoding="utf-8", newline="\n")
f.write(json.dumps({"cmd": "status"}) + "\n"); f.flush()
for line in f:
msg = json.loads(line)
if msg.get("cmd") == "status": # on saute les événements
print(msg["playback"]["currentFrame"]); break
seek, set-in, set-out et l'option --frame prennent la position dans le plan comptée à partir de 0, pas le numéro affiché sur la règle. Sur un plan qui commence à 1001, l'image affichée 1010 est la position 9. status donne la position (playback.currentFrame) et le numéro de départ (playback.startOffset).open répond avant que le plan soit sondé : status.playback.transitioning reste true jusqu'à ce que le plan soit à l'écran. export met un travail en file : suivez-le avec export-status ou l'événement export-done. export-notes écrit ses fichiers en arrière-plan. Après set-proxy, attendez que status.viewport.retiering repasse à false.{"cmd": "set-ui-level", "value": "complete"}.quit répond, puis ferme le lecteur proprement, sans demander s'il faut enregistrer : envoyez save-playlist ou export-notes avant si la revue compte.Les 115 commandes du lecteur. Les champs entre parenthèses sont les principaux ; track vaut "A" (par défaut) ou "B".
Lecture et plage
| Commande | Effet |
|---|---|
play, pause, reverse-play | Lire, mettre en pause, lire à l'envers |
seek (frame) | Aller à une position (à partir de 0) |
step-frame (delta) | Avancer ou reculer de delta images |
toggle-loop | Boucle de la plage |
set-playlist-playback (loop_mode 0, 1 ou 2, dont_wait_incomplete_shots) | Boucle désactivée, sur le plan ou sur la playlist |
set-in, set-out (frame, facultatif) | Points d'entrée et de sortie ; sans frame, la tête de lecture |
clear-in-out, set-in-out-lock (value) | Effacer la plage ; interdire à la souris de la déplacer |
set-fps (value), set-start (value) | Cadence ; numéro de la première image |
set-volume (value 0 à 1), set-mute (value), toggle-mute | Son |
Plans et playlist
| Commande | Effet |
|---|---|
open ou load (path) | Ouvrir un fichier ou une séquence sur la piste A, en l'ajoutant à la playlist |
load-playlist (path) | Charger une playlist .bpl, .otio, .csv, .json ou .edl |
save-playlist (path) | Écrire la playlist en .bpl (notes, statuts, étalonnage, dessins) |
playlist-add (path), playlist-play (index), playlist-remove (index), playlist-move (from, to), playlist-clear | Gérer la playlist (index à partir de 0) |
drop (paths, at : track_a, track_b ou viewport_b) | Comme un dépôt de fichiers depuis l'explorateur |
Comparaison et versions
| Commande | Effet |
|---|---|
set-ab-mode (value), toggle-ab | Mode A/B |
set-track-b (path) | Mettre un fichier sur la piste B |
set-ab-view (value : a, wipe, b), ab-flip | A seul, volet, B seul ; basculer A/B |
set-wipe (position 0 à 1, angle en degrés) | Position et angle du volet |
cycle-b (direction : prev, next) | Version précédente ou suivante sur B |
pin-track-b (value), set-b-version-preload (value) | Épingler B ; précharger les versions voisines |
set-ab-label-mode (interaction, always, never), set-metadata-track (a, b, ab) | Lettres A/B ; piste de l'onglet Metadata |
build-matrix (sequence, id, shots), get-matrix | Remplir et lire le tableau des versions (voir Intégrations) |
Couleur
| Commande | Effet |
|---|---|
set-exposure, set-gamma (value, track) | Exposition (en diaphs), gamma |
set-white-balance (temp, tint de -1 à 1, track), set-offset (value : [r, g, b], track) | Balance des blancs, offset |
set-colorspace (value) | Espace d'entrée de la piste A : ACEScg, sRGB, AP0, AdobeRGB, ProPhoto, Rec709, LogC3, LogC4, ou Auto |
set-channel (value : RGBA, R, G, B, A, L ; track) | Canal affiché |
set-stage (stage, on, track) | Couper ou rétablir une étape (exposure, levels, curves, gamma...) |
set-curve (channel : master, r, g, b ; points ou reset) | Courbes, points [x, y] sur l'axe ACEScct |
set-hue-range (range, hue, saturation, lightness) | Plages de teintes |
color-panel (target, before_after, picker, levels_auto, preset_save, preset_apply...) | Panneau couleur ; sans champ, le lit |
scopes (open, kind) | Scopes et leurs dernières mesures (histogramme, écrêtage) |
set-layer (track_idx, layer_idx), layer-info (track) | Passe d'un EXR multicouche |
Viewer, interface et fenêtres
| Commande | Effet |
|---|---|
zoom (value, 1 = un pixel source par pixel écran), pan (x, y), fit, flip | Cadrage |
set-fullscreen (value), set-window-size (width, height), set-ui-scale (percent) | Fenêtre principale |
set-theme (dark, light, neon, system ; ou sombre, clair, systeme), set-ui-level (essential, complete) | Affichage et niveau d'interface |
reset-layout, new-window (view), close-window (name ou all), windows | Disposition et copies de panneaux |
contact-sheet (open, mode, card_w...) | Planche contact |
set-tool (tool : pen, text, arrow, rect, laser, eraser, pipette, select) | Outil de dessin |
debug-mouse (x, y, down, alt, release) | Souris simulée, pour les tests d'interface |
Notes, captures et export
| Commande | Effet |
|---|---|
export-notes (output_dir) | Écrire export.json et export.html sans aucune fenêtre |
screenshot (output, frame, annotations) | Une image PNG du plan de la piste A, étalonnée comme à l'écran |
export (output, preset, source, playlist, format, codec, color, burn_in, annotations, watermark, recipient...) | Exporter des images ou un film ; mis en file |
export-status, export-cancel, export-presets | Suivre, annuler, lister les préréglages |
export-recipe (action : list ou run ; name, file ou recipe ; clips, recipient) | Recettes d'export |
Mémoire et décodage
| Commande | Effet |
|---|---|
set-proxy (proxy_idx : 0 = 1/1, 1 = 1/2, 2 = 1/4, 3 = 1/8, 4 = Smart RAM-Fit) | Résolution de décodage du plan affiché |
set-slow-decode-tier (auto, off) | Quand le décodage ne suit pas |
set-gpu-decode (value) | Décodage GPU de NOVA (bêta) : activer, désactiver ou lire l'état |
set-gpu-yuv (value) | Envoi YUV au GPU des films (bêta) : activer, désactiver ou lire l'état |
set-gpu-video-decode (value) | Décodage vidéo par la carte graphique (bêta) : activer, désactiver ou lire l'état |
set-gpu-prores (value) | Décodage ProRes par le GPU (bêta) : activer, désactiver ou lire l'état |
set-ram-limit-gb, set-vram-ring-limit-gb (value ; 0 = Auto pour la VRAM) | Budgets mémoire |
set-hardware-decode (value) | Décodage matériel |
ram-fit-apply, precache-playlist (value), full-quality (value), cache-clip-frames (clip_id) | Smart RAM-Fit, préchargement |
ram-info (frames) | Occupation de la mémoire, plan par plan |
cache-info, cache-purge (scope) | Cache de compression : présent, mais encore vide dans cette version |
Séances de revue
| Commande | Effet |
|---|---|
session-create (name, user_name, password, reach : network ou this_computer) | Héberger ; la réponse donne les liens |
session-join (address, user_name, password), session-leave | Rejoindre, quitter |
session-status | Tout l'état de la séance : participants, pilote, voix... |
session-pass-baton (participant_id), session-set-sync (locked) | Passer la main ; Local Review |
chat-send (text), chat-log (last) | Chat |
laser (x, y, active), laser-status | Pointeur laser |
voice-test (seconds) | Jouer une tonalité dans le haut-parleur de la voix |
stream-enable (on, width, height), stream-status | Diffusion aux invités web |
Trackers (sans aucun secret dans les requêtes)
| Commande | Effet |
|---|---|
tracker-sites | Les sites de trackers.json |
tracker-connect (site), tracker-disconnect (site, forget) | Connexion |
tracker-projects, tracker-playlists (project_id) | Parcourir |
tracker-load-playlist (playlist_id, mode : replace ou append) | Charger une playlist |
tracker-publish (items, status, dry_run) | Publier les notes |
tracker-download-media (index), tracker-cancel | Télécharger un aperçu ; annuler |
Diagnostic
| Commande | Effet |
|---|---|
status | Tout l'état du lecteur (voir plus bas) |
system-info | Version, système, carte graphique, bibliothèques ; sans nom ni chemin |
dump-thumbnails (output, track) | Les vignettes de la timeline dans une planche PNG |
quit | Fermer le lecteur proprement |
Le lecteur diffuse ces lignes à son client, sans qu'il les demande :
| Événement | Champs |
|---|---|
play, pause | — |
frame_changed | frame : la position, à chaque image où elle change (lecture, glisser, saut) |
export-done | ok, cancelled, error, frames_written, output, jobs, seconds, encoder |
tracker-connected | ok, site, user, reason |
tracker-projects, tracker-playlists | ok, projects ou playlists, reason |
tracker-loaded | ok, items, missing_media, reason |
tracker-publish-done | published, skipped, failed, dry_run |
tracker-download-done | index, ok, path ou reason |
status {"cmd": "status"} renvoie l'état complet. Les blocs les plus utiles : playback (state, currentFrame, startOffset, fps, ab_mode, ab_view, transitioning, les compteurs late_frames et lost_frames), color (étalonnage de la piste A, canal), viewport (résolution décodée et d'origine, proxy_idx, retiering, zoom), decode (temps de décodage, too_slow), track_b, ram_fit et playlist (un élément par plan).
Ouvrir le dernier rendu et le lire (par exemple depuis un bouton de Nuke) :
client.open_media("D:/renders/SQ010_SH010_COMP_v003/SQ010_SH010_COMP_v003.1001.exr")
client.set_colorspace("ACEScg")
client.play()
Suivre la tête de lecture (pour synchroniser une timeline Maya, par exemple) :
client.on("frame_changed", lambda e: print("position", e["frame"]))
client.on("play", lambda e: print("lecture"))
Exporter des dailies et attendre la fin :
client.export("D:/dailies/<clip>.mov", preset="dailies_prores_lt",
playlist=True, burn_in=True)
result = client.wait_for_export()
print(result["state"], result.get("error"))
Récupérer les notes d'une revue :
import json, os, time
out = "D:/review/SQ010_notes"
client.export_notes(out)
time.sleep(2) # l'écriture se fait en arrière-plan
notes = json.load(open(os.path.join(out, "export.json"), encoding="utf-8"))
Lancer une séance de revue protégée :
r = client.session_create(name="SQ010 dailies", password="...")
for link in r["links"]:
print(link["kind"], link["link"]) # lan, vpn...
Le dossier api contient les schémas JSON des fichiers échangés : playlist.schema.json (la playlist .bpl, avec le bloc x_tracking des identifiants de tracker), notes_payload.schema.json (le export.json des notes) et export_recipe.schema.json (les recettes d'export), ainsi que des exemples de travaux d'export dans export_examples/.
Voir aussi : Ligne de commande et export sans fenêtre, Intégrations.