Streaming

WebSocket経由でブラウザのビューポートをストリーミングし、ライブプレビューまたは「ペアブラウジング」を実現します。 人間がAIエージェントと一緒に動作を観察・操作できるようにします。

ストリーミングの有効化

AGENT_BROWSER_STREAM_PORT 環境変数を設定して、WebSocketサーバーを起動します:

AGENT_BROWSER_STREAM_PORT=9223 agent-browser open example.com

このサーバーはビューポートフレームをストリーミングし、マウス、キーボード、タッチ入力イベントを受け入れます。

WebSocketプロトコル

ws://localhost:9223 に接続して、フレームを受信し、入力を送信します。

フレームメッセージ

サーバーはベース64エンコードされた画像を含むフレームメッセージを送信します:

{
  "type": "frame",
  "data": "<base64エンコード済み-jpeg>",
  "metadata": {
    "deviceWidth": 1280,
    "deviceHeight": 720,
    "pageScaleFactor": 1,
    "offsetTop": 0,
    "scrollOffsetX": 0,
    "scrollOffsetY": 0
  }
}

状態メッセージ

接続状態およびスクリーンキャスト状態:

{
  "type": "status",
  "connected": true,
  "screencasting": true,
  "viewportWidth": 1280,
  "viewportHeight": 720
}

入力注入

入力イベントを送信して、ブラウザを遠隔から制御します。

マウスイベント

// クリック
{
  "type": "input_mouse",
  "eventType": "mousePressed",
  "x": 100,
  "y": 200,
  "button": "left",
  "clickCount": 1
}

// リリース
{
  "type": "input_mouse",
  "eventType": "mouseReleased",
  "x": 100,
  "y": 200,
  "button": "left"
}

// 移動
{
  "type": "input_mouse",
  "eventType": "mouseMoved",
  "x": 150,
  "y": 250
}

// ホイールスクロール
{
  "type": "input_mouse",
  "eventType": "mouseWheel",
  "x": 100,
  "y": 200,
  "deltaX": 0,
  "deltaY": 100
}

キーボードイベント

// キー押下
{
  "type": "input_keyboard",
  "eventType": "keyDown",
  "key": "Enter",
  "code": "Enter"
}

// キー解放
{
  "type": "input_keyboard",
  "eventType": "keyUp",
  "key": "Enter",
  "code": "Enter"
}

// 文字入力
{
  "type": "input_keyboard",
  "eventType": "char",
  "text": "a"
}

// モディファイア付き(1=Alt, 2=Ctrl, 4=Meta, 8=Shift)
{
  "type": "input_keyboard",
  "eventType": "keyDown",
  "key": "c",
  "code": "KeyC",
  "modifiers": 2
}

タッチイベント

// タッチ開始
{
  "type": "input_touch",
  "eventType": "touchStart",
  "touchPoints": [{ "x": 100, "y": 200 }]
}

// タッチ移動
{
  "type": "input_touch",
  "eventType": "touchMove",
  "touchPoints": [{ "x": 150, "y": 250 }]
}

// タッチ終了
{
  "type": "input_touch",
  "eventType": "touchEnd",
  "touchPoints": []
}

// マルチタッチ(ピンチズーム)
{
  "type": "input_touch",
  "eventType": "touchStart",
  "touchPoints": [
    { "x": 100, "y": 200, "id": 0 },
    { "x": 200, "y": 200, "id": 1 }
  ]
}

プログラムインターフェース

高度な用途向けに、TypeScript APIを直接使ってストリーミングを制御できます:

import { BrowserManager } from 'agent-browser';

const browser = new BrowserManager();
await browser.launch({ headless: true });
await browser.navigate('https://example.com');

// コールバック付きでスクリーンキャストを開始
await browser.startScreencast((frame) => {
  console.log('フレーム:', frame.metadata.deviceWidth, 'x', frame.metadata.deviceHeight);
  // frame.data はベース64エンコードされた画像
}, {
  format: 'jpeg',  // または 'png'
  quality: 80,     // 0-100(jpegのみ)
  maxWidth: 1280,
  maxHeight: 720,
  everyNthFrame: 1
});

// マウスイベントを注入
await browser.injectMouseEvent({
  type: 'mousePressed',
  x: 100,
  y: 200,
  button: 'left',
  clickCount: 1
});

// キーボードイベントを注入
await browser.injectKeyboardEvent({
  type: 'keyDown',
  key: 'Enter',
  code: 'Enter'
});

// タッチイベントを注入
await browser.injectTouchEvent({
  type: 'touchStart',
  touchPoints: [{ x: 100, y: 200 }]
});

// シャッター中かどうかを確認
console.log('稼働中:', browser.isScreencasting());

// シャッターを停止
await browser.stopScreencast();

利用例

  • ペアブラウジング - 人間がリアルタイムでAIエージェントの作業を観察・支援
  • リモートプレビュー - 別のUIでブラウザ出力を表示
  • 録画 - 映像生成用のフレームをキャプチャ
  • モバイルテスト - モバイルエミュレーション用のタッチイベントを注入
  • アクセシビリティテスト - 自動テスト中に手動で操作を行う