diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0f95a21 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,75 @@ +name: CI + +on: + pull_request: + branches: + - main + - development + push: + branches: + - main + - development + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: 'npm' + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Cache Rust build + uses: swatinem/rust-cache@v2 + with: + workspaces: './src-tauri -> target' + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + curl \ + wget \ + file \ + pkg-config \ + libglib2.0-dev \ + libwebkit2gtk-4.1-dev \ + libssl-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + patchelf + + - name: Set PKG_CONFIG_PATH for Linux + run: | + echo "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:${PKG_CONFIG_PATH}" >> $GITHUB_ENV + + - name: Install frontend dependencies + run: npm ci + + - name: Check Rust formatting + working-directory: src-tauri + run: cargo fmt --all -- --check + + - name: Run Clippy + working-directory: src-tauri + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Build Rust code + working-directory: src-tauri + run: cargo build --release --all-features + + - name: Run Rust tests + working-directory: src-tauri + run: cargo test --all-features + + - name: Build frontend + run: npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..fb0716f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,86 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + +jobs: + release: + if: startsWith(github.ref, 'refs/tags/v') + strategy: + fail-fast: false + matrix: + include: + - platform: 'ubuntu-latest' + args: '' + - platform: 'windows-latest' + args: '' + - platform: 'macos-latest' + args: '' + + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: 'npm' + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Cache Rust build + uses: swatinem/rust-cache@v2 + with: + workspaces: './src-tauri -> target' + + - name: Install Linux dependencies + if: matrix.platform == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + curl \ + wget \ + file \ + pkg-config \ + libglib2.0-dev \ + libwebkit2gtk-4.1-dev \ + libssl-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + patchelf + # Verify pkg-config can find required libraries + pkg-config --modversion glib-2.0 || echo "ERROR: glib-2.0 not found" + pkg-config --modversion gobject-2.0 || echo "ERROR: gobject-2.0 not found" + pkg-config --modversion gio-2.0 || echo "ERROR: gio-2.0 not found" + + - name: Set PKG_CONFIG_PATH for Linux + if: matrix.platform == 'ubuntu-latest' + run: | + echo "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig:${PKG_CONFIG_PATH}" >> $GITHUB_ENV + + - name: Install frontend dependencies + run: npm ci + + - name: Build frontend + run: npm run build + + - name: Publish Tauri builds + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tagName: ${{ github.ref_name }} + releaseName: 'OBS Sync ${{ github.ref_name }}' + releaseBody: '🚀 Release version ${{ github.ref_name }}' + releaseDraft: false + prerelease: false + args: ${{ matrix.args }} diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md deleted file mode 100644 index aa91cea..0000000 --- a/DEVELOPMENT.md +++ /dev/null @@ -1,152 +0,0 @@ -# 開発ガイド - -## マルチインスタンス起動方法(Master/Slaveテスト用) - -OBS Syncの動作を確認するには、2つのインスタンスを同時に起動する必要があります。 - -### 前提条件 - -1. Node.jsとnpmがインストールされていること -2. Rustがインストールされていること -3. 依存関係がインストールされていること - -```bash -npm install -``` - -### 起動手順 - -#### ステップ1: 2つのターミナルを開く - -**ターミナル1(Master用):** -```bash -npm run tauri:master -``` - -**ターミナル2(Slave用):** -```bash -npm run tauri:slave -``` - -これにより、2つのインスタンスが異なるポートで起動します: -- Master: ポート1420 -- Slave: ポート1421 - -### 動作確認手順 - -#### 1. OBS Studioの準備 - -2つのOBS Studioインスタンスを起動します(異なるポートで): - -**OBS Studio 1(Master用):** -- WebSocketサーバー設定: ポート4455 - -**OBS Studio 2(Slave用):** -- WebSocketサーバー設定: ポート4456(または別のポート) - -> **Note:** OBS Studioで複数インスタンスを起動するには、`--multi`オプションを使用するか、異なるプロファイルを作成してください。 - -#### 2. Masterの設定 - -**ターミナル1のアプリで:** -1. **Masterモード**を選択 -2. OBS接続設定: - - ホスト: `localhost` - - ポート: `4455` - - パスワード: (設定した場合のみ) -3. 「OBSに接続」をクリック -4. 同期対象を選択(ソース、プレビュー、プログラム) -5. 「サーバーを起動」をクリック(デフォルトポート: 8080) - -#### 3. Slaveの設定 - -**ターミナル2のアプリで:** -1. **Slaveモード**を選択 -2. OBS接続設定: - - ホスト: `localhost` - - ポート: `4456` - - パスワード: (設定した場合のみ) -3. 「OBSに接続」をクリック -4. Master接続設定: - - Masterホスト: `localhost` - - ポート: `8080` -5. 「Masterに接続」をクリック - -#### 4. 動作確認 - -Master側のOBSでシーンを変更すると、Slave側のOBSが自動的に同じシーンに切り替わることを確認してください。 - -### トラブルシューティング - -#### ポートが既に使用されているエラー - -``` -Failed to start master server: Failed to bind to 0.0.0.0:8080 -``` - -**原因:** 前回起動したサーバーが正しく停止していません。 - -**解決方法:** -1. アプリで「モードを変更」ボタンをクリック -2. アプリを完全に終了して再起動 -3. 別のポート番号を使用(例: 8081) - -#### OBSに接続できない - -**確認事項:** -- OBS Studioが起動していること -- WebSocketサーバーが有効になっていること -- ポート番号が正しいこと -- ファイアウォールでブロックされていないこと - -#### Slaveがマスターに接続できない - -**確認事項:** -- Masterサーバーが起動していること -- IPアドレスとポート番号が正しいこと -- 同じネットワーク内にいること -- ファイアウォールでブロックされていないこと - -### 開発時のヒント - -#### ログの確認 - -アプリケーションのログは以下のコマンドで確認できます: - -```bash -# Rustのログ -RUST_LOG=debug npm run tauri:master - -# または -RUST_LOG=debug npm run tauri:slave -``` - -#### ホットリロード - -Viteのホットリロードが有効になっているため、フロントエンドのコードを変更すると自動的にリロードされます。 - -Rustコードを変更した場合は、アプリを再起動する必要があります。 - -#### デバッグモード - -開発者ツールを開くには、アプリ内で `Ctrl+Shift+I` (Windows/Linux) または `Cmd+Option+I` (macOS) を押してください。 - -### 単一インスタンスでの開発 - -機能開発時は単一インスタンスで十分な場合があります: - -```bash -npm run tauri dev -``` - -この場合、デフォルトでポート1420が使用されます。 - -## ビルド - -本番用のバイナリをビルドするには: - -```bash -npm run tauri build -``` - -ビルドされたファイルは `src-tauri/target/release/` に生成されます。 diff --git a/README.md b/README.md index 4d8e1a7..7fefeff 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # OBS Sync -LAN内の複数のOBS Studioを同期するシステム(イベント向け) +中規模~大規模イベント運営者向け +LAN内の複数のOBS Studioを同期するシステム ## 概要 -OBS Syncは、LAN内の複数のOBS Studio間で、画像ソース、シーン構成、ポジション情報などをリアルタイムで同期するためのデスクトップアプリケーションです。イベント制作現場での複数OBSのクライアントチェックや、複数配信環境の統一的な管理を想定しています。 +OBS Syncは、LAN内の複数のOBS Studio間で、画像ソース、シーン構成、ポジション情報などをリアルタイムで同期するためのデスクトップアプリケーションです。イベント制作現場での複数OBSのクライアントチェックや、複数配信環境の統一的な管理を想定しています。 ## 主要機能 @@ -13,89 +14,23 @@ OBS Syncは、LAN内の複数のOBS Studio間で、画像ソース、シーン - **Slaveモード**: Masterからの変更を受信し、ローカルのOBS Studioに自動適用。非同期があればアラートを表示 ### リアルタイム同期 -- 画像ソースの内容、サイズ、位置をリアルタイムで同期 -- 画像を差し替えたら自動的に全てのOBSに反映 -- 位置を調整したら自動的に全てのOBSに反映 +- 画像ソースの内容、サイズ、位置をWebsocketを使用し同期 +- 画像の差し替え、位置調整、フィルターの変更などが全てのOBSに反映可能 ### 柔軟な同期対象選択 以下の対象を個別に選択可能: -- ソース(Source) -- プレビュー(Preview) -- プログラム(Program/Live Output) +- ソース/シーン/フィルター +- Preview/Program ### 非同期検出とアラート Slaveモードでは、受信した変更とローカルのOBS状態に差異がある場合、UIでアラートを表示します。 ## 技術スタック -### フロントエンド -- **フレームワーク**: React 19.1.0 (TypeScript) -- **ビルドツール**: Vite 7.0.4 -- **UI**: CSS Modules -- **通知**: react-toastify 10.x -- **OBS通信**: obs-websocket-js 5.x +## ダウンロード -### バックエンド -- **フレームワーク**: Tauri v2.x -- **非同期ランタイム**: tokio 1.x -- **WebSocket**: tokio-tungstenite 0.21.x -- **シリアライゼーション**: serde 1.x, serde_json 1.x - -### プロトコル -- **OBS WebSocket**: v5.x (OBS Studio 28.x以降) -- **Master-Slave通信**: カスタムJSON over WebSocket - -## 必要要件 - -- Node.js LTS版 -- Rust 1.70以降 -- OBS Studio 28.x以降(OBS WebSocket v5.x対応版) - -## セットアップ - -### 1. リポジトリのクローン -```bash -git clone https://github.com/FlowingSPDG/obs-sync.git -cd obs-sync -``` - -### 2. 依存関係のインストール -```bash -npm install -``` - -### 3. OBS Studio側の設定 -1. OBS Studioを起動 -2. 「ツール」→「WebSocketサーバー設定」を開く -3. WebSocketサーバーを有効化 -4. ポート番号とパスワード(オプション)を設定 - -## 開発 - -### 開発サーバーの起動 - -#### 通常起動(1インスタンス) -```bash -npm run tauri dev -``` - -#### マルチインスタンス起動(Master/Slaveテスト用) -2つのターミナルを開いて、それぞれで以下を実行: - -**ターミナル1(Master用):** -```bash -npm run tauri:master -``` - -**ターミナル2(Slave用):** -```bash -npm run tauri:slave -``` - -### ビルド -```bash -npm run tauri build -``` +- [最新リリース](https://github.com/FlowingSPDG/obs-sync/releases/latest) +- [全リリース](https://github.com/FlowingSPDG/obs-sync/releases) ## 使い方 @@ -113,12 +48,6 @@ npm run tauri build 4. MasterノードのIPアドレスとポートを入力して接続 5. Masterからの変更が自動的にローカルOBSに適用される -## プロジェクト構造 - -詳細は以下のドキュメントを参照してください: -- [技術スタック](./technologystack.md) -- [ディレクトリ構造](./directorystructure.md) - ## ライセンス MIT License diff --git a/directorystructure.md b/directorystructure.md deleted file mode 100644 index 5fd12ad..0000000 --- a/directorystructure.md +++ /dev/null @@ -1,114 +0,0 @@ -# ディレクトリ構造 - -``` -obs-sync/ -├── src/ # フロントエンドソース -│ ├── components/ # Reactコンポーネント -│ │ ├── MasterControl.tsx # Masterモード制御UI -│ │ ├── SlaveMonitor.tsx # Slaveモード監視UI -│ │ ├── SyncTargetSelector.tsx # 同期対象選択 -│ │ ├── ConnectionStatus.tsx # 接続状態表示 -│ │ ├── AlertPanel.tsx # 非同期アラート表示 -│ │ └── OBSSourceList.tsx # OBSソース一覧 -│ ├── hooks/ # カスタムフック -│ │ ├── useOBSConnection.ts # OBS接続管理 -│ │ ├── useSyncState.ts # 同期状態管理 -│ │ └── useNetworkStatus.ts # ネットワーク状態管理 -│ ├── types/ # TypeScript型定義 -│ │ ├── obs.ts # OBS関連型 -│ │ ├── sync.ts # 同期関連型 -│ │ └── network.ts # ネットワーク関連型 -│ ├── utils/ # ユーティリティ関数 -│ │ ├── obsUtils.ts # OBS操作ヘルパー -│ │ └── syncUtils.ts # 同期処理ヘルパー -│ ├── styles/ # スタイルシート -│ │ ├── global.css # グローバルスタイル -│ │ └── components/ # コンポーネント別スタイル -│ ├── App.tsx # メインアプリケーション -│ ├── App.css # アプリケーションスタイル -│ └── main.tsx # エントリーポイント -│ -├── src-tauri/ # Tauriバックエンド -│ ├── src/ -│ │ ├── main.rs # メインエントリーポイント -│ │ ├── lib.rs # ライブラリルート -│ │ ├── obs/ # OBS WebSocket統合 -│ │ │ ├── mod.rs # OBSモジュール -│ │ │ ├── client.rs # OBS WebSocketクライアント -│ │ │ ├── events.rs # OBSイベント処理 -│ │ │ └── commands.rs # OBSコマンド実行 -│ │ ├── sync/ # 同期ロジック -│ │ │ ├── mod.rs # 同期モジュール -│ │ │ ├── master.rs # Masterモード実装 -│ │ │ ├── slave.rs # Slaveモード実装 -│ │ │ ├── protocol.rs # 通信プロトコル定義 -│ │ │ └── diff.rs # 差分検出ロジック -│ │ ├── network/ # ネットワーク通信 -│ │ │ ├── mod.rs # ネットワークモジュール -│ │ │ ├── server.rs # WebSocketサーバー (Master用) -│ │ │ └── client.rs # WebSocketクライアント (Slave用) -│ │ └── commands.rs # Tauriコマンド定義 -│ ├── Cargo.toml # Rust依存関係 -│ └── tauri.conf.json # Tauri設定 -│ -├── public/ # 静的ファイル -├── .gitignore -├── package.json # Node.js依存関係 -├── tsconfig.json # TypeScript設定 -├── vite.config.ts # Vite設定 -├── README.md # プロジェクト説明 -├── technologystack.md # 技術スタック詳細 -└── directorystructure.md # このファイル -``` - -## モジュール説明 - -### フロントエンド (src/) -- **components/**: UI コンポーネント - - Master/Slave モード切替と制御UI - - 同期状態の可視化 - - アラート表示パネル - -- **hooks/**: React カスタムフック - - OBS接続の管理と状態保持 - - 同期状態の管理 - - ネットワーク状態の監視 - -- **types/**: TypeScript 型定義 - - OBS WebSocketの型 - - 同期プロトコルの型 - - ネットワークメッセージの型 - -- **utils/**: ヘルパー関数 - - OBS操作の抽象化 - - 同期処理のユーティリティ - -### バックエンド (src-tauri/src/) -- **obs/**: OBS WebSocket統合 - - OBS Studioへの接続管理 - - イベントの監視と処理 - - コマンドの実行 - -- **sync/**: 同期ロジック - - Masterモード: 変更検出とブロードキャスト - - Slaveモード: 変更受信と適用 - - 差分検出アルゴリズム - -- **network/**: ネットワーク通信 - - WebSocketサーバー(Master) - - WebSocketクライアント(Slave) - - メッセージのルーティング - -- **commands.rs**: フロントエンドから呼び出せるTauriコマンド - -## データフロー - -### Masterモード -``` -OBS Studio → obs/client.rs → sync/master.rs → network/server.rs → Slave Nodes -``` - -### Slaveモード -``` -Master Node → network/client.rs → sync/slave.rs → obs/client.rs → Local OBS Studio -``` diff --git a/index.html b/index.html index 2dc612a..812b787 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ -