開発者向けドキュメント

Python API と IPC

スクリプトやパイプラインのアプリケーションから Bernard Review を操作します。プロトコル、Python クライアント、ファミリー別の全コマンド、イベント、完全な例。

Bernard Review は、Python、Maya、Nuke、Houdini、制作トラッカー、あるいは TCP 接続を開ける任意の言語から操作できます。アーティストが手で行うことには、すべて対応するコマンドがあります。クリップを開く、再生する、比較する、グレーディングする、書き出す、セッションを開始する、ノートをパブリッシュする、などです。このページだけでプレーヤーの自動化ができます。フィールドごとの網羅的なリファレンスは、API リファレンス(英語。Help > API Documentation でも開きます)です。

プロトコル

  • アドレス:127.0.0.1、既定のポートは 5556 です。--ipc-port N で起動したプレーヤーは N で待ち受けます。これにより、同じマシンで 2 つのプレーヤーを動かせます。
  • 形式:JSON Lines です。各リクエストは、1 行の JSON オブジェクトで、\n で終わり、"cmd" フィールドを持ちます:{"cmd": "seek", "frame": 24}。
  • リクエストごとに 1 つの応答が、送信順に、通常は数ミリ秒以内に返ります:{"status": "ok", "cmd": "seek", ...} または {"status": "error", "cmd": "seek", "reason": "..."}。エラーには必ず平易な言葉の理由が付き、こちらのタイムアウトまで待たされることはありません。リクエスト ID はなく、応答は "cmd" によってリクエストと対応付けられます。
  • プレーヤーからのイベント({"event": ...})は、同じ接続で、応答と混ざって届きます(後述)。
  • 同時に接続できるクライアントは 1 つです。2 つ目の接続は、最初の接続が閉じるまで待たされます。
  • ローカルのみ。 ポートはループバックで待ち受けます。ブラウザーのリクエストに見える接続(HTTP の行、Host: ヘッダー)は、何も実行されずに閉じられます。Web ページからプレーヤーを操作することはできません。1 行は最大 16 MiB です。
  • トラッカーのシークレットはこのポートを通りません。トラッカーのパスワード、キー、トークンを含むリクエストは拒否されます。

コードを書かずに試す方法:Window > Console(Ctrl+Shift+C)は、プレーヤー内から同じコマンドを送信でき、Tab による補完も使えます。status、seek {"frame": 24}、または完全な JSON 形式です。ファイルを書き込む、パブリッシュする、プレーヤーを閉じるといったコマンドの前には、確認が表示されます。

Console に seek コマンドとその応答、続いて status への応答の冒頭が表示されている。

Python クライアント

bernard_api.py は、プロトコルを BernardClient という 1 つのクラスで包み、コマンドごとに 1 つのメソッドを用意しています。プレーヤーの隣の api フォルダーにインストールされます。

システム場所
WindowsC:\Program Files\Bernard Review\bin\api\bernard_api.py
Linux (RPM)/usr/share/bernardplayer/api/bernard_api.py
Linux (.sh アーカイブ)<install folder>/share/bernardplayer/api/bernard_api.py

必要なのは 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 does not answer on port 5556")

reply = client.open_media("D:/shots/SQ010_SH010_ANIM_v002.mov")
if reply is None or reply.get("status") == "error":
    print("refused:", reply and reply.get("reason"))
else:
    client.play()
  • request(dict) はコマンドを送り、そのコマンドの応答(dict)を待ちます。エラーも含みます。プレーヤーが拒否しても例外は発生せず、タイムアウトまたは接続が切れた場合は None を返します。
  • send_command(dict) は、待たずに送信します。
  • 名前付きのメソッド(play()、seek()、set_exposure()、export() など)は、そのどちらかを呼び出します。データを返すものは request() を経由します。
  • on("frame_changed", function) は、関数をイベントに登録します。バックグラウンドのスレッドが接続を読み取ります。

クライアントを使わなくても、数行で足ります。

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":      # skip the events
            print(msg["playback"]["currentFrame"]); break

スクリプトを書く前に知っておくこと

  • フレーム番号。 seek、set-in、set-out、および --frame オプションが受け取るのは、ルーラーに印字された番号ではなく、クリップ内の 0 から数えた位置です。1001 から始まるクリップでは、表示上のフレーム 1010 は位置 9 です。status は位置(playback.currentFrame)と最初のフレーム番号(playback.startOffset)を返します。
  • 非同期のもの。 open は、クリップを解析する前に応答します。クリップが画面に出るまで、status.playback.transitioning は true のままです。export はジョブをキューに入れます。export-status または export-done イベントで追跡してください。export-notes はバックグラウンドでファイルを書き込みます。set-proxy のあとは、status.viewport.retiering が false に戻るのを待ってください。
  • 新しいプロファイルでは、初回起動時の質問がモーダルウィンドウで表示されます。先に {"cmd": "set-ui-level", "value": "complete"} を送ってください。
  • quit は応答したあと、保存するかどうかを尋ねずに、プレーヤーを正常に閉じます。レビューが重要な場合は、先に save-playlist または export-notes を送ってください。
  • 同じ名前のリクエストを複数同時に送ると、区別できなくなります。1 つずつ順に送ってください。

ファミリー別のコマンド

プレーヤーの 115 のコマンドです。括弧内のフィールドは主なものです。track は "A"(既定)または "B" です。

再生と範囲

コマンド効果
play, pause, reverse-play再生、一時停止、逆再生
seek (frame)位置(0 から)へ移動
step-frame (delta)delta フレーム進む、または戻る
toggle-loop範囲をループ
set-playlist-playback (loop_mode 0, 1, 2, dont_wait_incomplete_shots)ループなし、クリップでループ、プレイリストでループ
set-in, set-out (frame, 省略可)イン点とアウト点。frame を省略すると再生ヘッドの位置
clear-in-out, set-in-out-lock (value)範囲を解除。マウスで動かないようにする
set-fps (value), set-start (value)フレームレート、最初のフレーム番号
set-volume (value 0 〜 1), set-mute (value), toggle-mute音声

クリップとプレイリスト

コマンド効果
open または load (path)ファイルまたは連番をトラック A で開き、プレイリストに追加
load-playlist (path).bpl、.otio、.csv、.json、.edl のプレイリストを読み込む
save-playlist (path)プレイリストを .bpl として書き出す(ノート、ステータス、グレード、描画)
playlist-add (path), playlist-play (index), playlist-remove (index), playlist-move (from, to), playlist-clearプレイリストの管理(インデックスは 0 から)
drop (paths, at: track_a, track_b, viewport_b)ファイルマネージャーからのファイルのドロップと同じ

比較とバージョン

コマンド効果
set-ab-mode (value), toggle-abA/B モード
set-track-b (path)トラック B にファイルを置く
set-ab-view (value: a, wipe, b), ab-flipA のみ、ワイプ、B のみ。A/B の切り替え
set-wipe (position 0 〜 1, angle 度)ワイプの位置と角度
cycle-b (direction: prev, next)B の前または次のバージョン
pin-track-b (value), set-b-version-preload (value)B を固定。前後のバージョンを先読み
set-ab-label-mode (interaction, always, never), set-metadata-track (a, b, ab)A/B の文字。Metadata タブのトラック
build-matrix (sequence, id, shots), get-matrixVersion Board への入力と読み取り(連携を参照)

カラー

コマンド効果
set-exposure, set-gamma (value, track)露出(ストップ単位)、ガンマ
set-white-balance (temp, tint -1 〜 1, track), set-offset (value: [r, g, b], track)ホワイトバランス、オフセット
set-colorspace (value)トラック A の入力スペース:ACEScg, sRGB, AP0, AdobeRGB, ProPhoto, Rec709, LogC3, LogC4、または Auto
set-channel (value: RGBA, R, G, B, A, L; track)表示するチャンネル
set-stage (stage, on, track)ステージのオフ / オン(exposure, levels, curves, gamma...)
set-curve (channel: master, r, g, b; points または reset)カーブ。ACEScct 軸上の [x, y] の点
set-hue-range (range, hue, saturation, lightness)色相範囲
color-panel (target, before_after, picker, levels_auto, preset_save, preset_apply...)カラーパネル。フィールドなしで読み取り
scopes (open, kind)スコープと直近の測定値(ヒストグラム、クリッピング)
set-layer (track_idx, layer_idx), layer-info (track)マルチレイヤー EXR のパス

ビューア、インターフェース、ウィンドウ

コマンド効果
zoom (value, 1 = ソースの 1 ピクセルが画面の 1 ピクセル), pan (x, y), fit, flipフレーミング
set-fullscreen (value), set-window-size (width, height), set-ui-scale (percent)メインウィンドウ
set-theme (dark, light, neon, system、または sombre, clair, systeme), set-ui-level (essential, complete)表示モードとインターフェースのレベル
reset-layout, new-window (view), close-window (name または all), windowsレイアウトとパネルのコピー
contact-sheet (open, mode, card_w...)コンタクトシート
set-tool (tool: pen, text, arrow, rect, laser, eraser, pipette, select)ペイントツール
debug-mouse (x, y, down, alt, release)マウス操作のシミュレーション(インターフェースのテスト用)

ノート、キャプチャ、書き出し

コマンド効果
export-notes (output_dir)ダイアログなしで export.json と export.html を書き出す
screenshot (output, frame, annotations)トラック A のクリップの PNG(画面と同じグレード適用後)
export (output, preset, source, playlist, format, codec, color, burn_in, annotations, watermark, recipient...)フレームまたはムービーの書き出し。キューに入る
export-status, export-cancel, export-presets進行状況の確認、キャンセル、プリセットの一覧
export-recipe (action: list または run; name, file または recipe; clips, recipient)書き出しレシピ

メモリとデコード

コマンド効果
set-proxy (proxy_idx: 0 = 1/1, 1 = 1/2, 2 = 1/4, 3 = 1/8, 4 = Smart RAM-Fit)表示中のクリップのデコード解像度
set-slow-decode-tier (auto, off)デコードが追いつかないとき
set-gpu-decode (value)NOVA の GPU デコード(ベータ):オン、オフ、または状態の取得
set-gpu-yuv (value)ムービーの GPU YUV アップロード(ベータ):オン、オフ、または状態の取得
set-gpu-video-decode (value)GPU ビデオデコード(ベータ):オン、オフ、または状態の取得
set-gpu-prores (value)GPU ProRes デコード(ベータ):オン、オフ、または状態の取得
set-ram-limit-gb, set-vram-ring-limit-gb (value; VRAM では 0 = Auto)メモリの予算
set-hardware-decode (value)ハードウェアデコード
ram-fit-apply, precache-playlist (value), full-quality (value), cache-clip-frames (clip_id)Smart RAM-Fit、先読み
ram-info (frames)クリップごとのメモリ使用量
cache-info, cache-purge (scope)圧縮キャッシュ:存在するが、このバージョンではまだ空

レビューセッション

コマンド効果
session-create (name, user_name, password, reach: network または this_computer)ホスト。応答にリンクが含まれる
session-join (address, user_name, password), session-leave参加、退出
session-statusセッション全体の状態:参加者、パイロット、音声など
session-pass-baton (participant_id), session-set-sync (locked)操作権を渡す。Local Review
chat-send (text), chat-log (last)チャット
laser (x, y, active), laser-statusレーザーポインター
voice-test (seconds)音声用スピーカーでテスト音を鳴らす
stream-enable (on, width, height), stream-statusWeb ゲスト向けのストリーミング

トラッカー(どのリクエストにもシークレットは含めない)

コマンド効果
tracker-sitestrackers.json のサイト
tracker-connect (site), tracker-disconnect (site, forget)接続
tracker-projects, tracker-playlists (project_id)参照
tracker-load-playlist (playlist_id, mode: replace または append)プレイリストの読み込み
tracker-publish (items, status, dry_run)ノートをパブリッシュ
tracker-download-media (index), tracker-cancelプレビューのダウンロード。キャンセル

診断

コマンド効果
statusプレーヤーの状態全体(後述)
system-infoバージョン、システム、グラフィックスカード、ライブラリ。名前もパスも含まない
dump-thumbnails (output, track)タイムラインのサムネイルを PNG のシートとして出力
quitプレーヤーを正常に閉じる

イベント

プレーヤーは、これらの行を、要求されなくてもクライアントにブロードキャストします。

イベントフィールド
play, pause—
frame_changedframe:位置。変化するたびに(再生、ドラッグ、ジャンプ)送られる
export-doneok, cancelled, error, frames_written, output, jobs, seconds, encoder
tracker-connectedok, site, user, reason
tracker-projects, tracker-playlistsok, projects または playlists, reason
tracker-loadedok, items, missing_media, reason
tracker-publish-donepublished, skipped, failed, dry_run
tracker-download-doneindex, ok, path または reason

status

{"cmd": "status"} は、状態全体を返します。特に有用なブロックは次のとおりです。playback(state、currentFrame、startOffset、fps、ab_mode、ab_view、transitioning、late_frames と lost_frames のカウンター)、color(トラック A のグレード、チャンネル)、viewport(デコード後とオリジナルの解像度、proxy_idx、retiering、zoom)、decode(デコード時間、too_slow)、track_b、ram_fit、playlist(クリップごとに 1 エントリ)。

例

最新のレンダリングを開いて再生する(たとえば Nuke のボタンから):

client.open_media("D:/renders/SQ010_SH010_COMP_v003/SQ010_SH010_COMP_v003.1001.exr")
client.set_colorspace("ACEScg")
client.play()

再生ヘッドに追従する(たとえば Maya のタイムラインを同期させる場合):

client.on("frame_changed", lambda e: print("position", e["frame"]))
client.on("play", lambda e: print("playing"))

デイリーズを書き出して、終わるまで待つ:

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"))

レビューのノートを収集する:

import json, os, time
out = "D:/review/SQ010_notes"
client.export_notes(out)
time.sleep(2)  # the files are written in the background
notes = json.load(open(os.path.join(out, "export.json"), encoding="utf-8"))

パスワード付きのレビューセッションを開始する:

r = client.session_create(name="SQ010 dailies", password="...")
for link in r["links"]:
    print(link["kind"], link["link"])   # lan, vpn...

ファイルフォーマット

api フォルダーには、やり取りされるファイルの JSON スキーマが入っています。playlist.schema.json(.bpl プレイリスト。トラッカーの識別子を持つ x_tracking ブロックを含む)、notes_payload.schema.json(ノートの export.json)、export_recipe.schema.json(書き出しレシピ)、そして export_examples/ の書き出しジョブのサンプルです。

関連項目:コマンドラインとヘッドレス書き出し、連携。