easymp
v0.2.0
Published
Unofficial TypeScript library for controlling and displaying images on classic Epson EasyMP projectors
Maintainers
Readme
easymp
古い Epson EasyMP プロジェクターを Bun / Node.js から操作する非公式TypeScriptライブラリです。電源・状態制御には ESC/VP.net、画像表示には EasyMP の EEMP/EPRD プロトコルを使います。
[!IMPORTANT] このプロジェクトはEpsonによる公式製品ではなく、Epsonとの提携・承認関係もありません。Epson、EasyMPおよび関連する名称は各権利者に帰属します。
現時点の映像プロトコルは EMP-1715 で実機確認した通信を基準にしています。ESC/VP.net 制御は同プロトコル対応機で利用できますが、映像表示は他機種では検証が必要です。
セットアップ
ライブラリとして利用する場合:
bun add easymp
# または
npm install easymp開発する場合:
git clone https://github.com/okakatsuo/easymp.git
cd easymp
bun install
bun run verify高レベル API
import { EpsonProjector } from "easymp";
const projector = new EpsonProjector({
host: "192.168.1.82",
// 通常は自動判定。必要なら localAddress: "192.168.1.17"
});
await projector.power.on();
console.log(await projector.status.power());
console.log(await projector.status.lampHours());
await projector.audio.setVolume(10); // EMP-1715: 0-20
await projector.audio.setOutput("internal");
await projector.audio.mute(); // EMP-1715では音声のみでなくA/Vミュート
await projector.audio.unmute();
await projector.display.connect();
try {
await projector.display.rectangle({
x: 104,
y: 104,
width: 128,
height: 128,
color: "#ff0000",
});
// 1024x768 に収め、128x128 JPEG タイルとして全面送信
await projector.display.show("./dashboard.png");
// 前回と同じタイルを省略して差分だけ送信
await projector.display.update("./dashboard-next.png");
} finally {
await projector.close();
}localAddress はプロジェクターと同じサブネットの IPv4 を自動判定します。EasyMP は UDP 3620 で接続要求を送り、そのアドレスの TCP 3620 へ折り返し接続を受けます。複数 NIC や特殊なルーティングで誤判定される場合は、Tailscale などの仮想 NIC ではなくプロジェクターと同じネットワーク上のアドレスを明示してください。
音声付き動画を再生する
EasyMP の動画再生モードでは、ffmpeg を使って入力ファイルを EMP-1715 用の MPEG-TS に変換しながら送信します。映像・音声とも EMP-1715 実機で確認済みです。play() は再生終了まで待機します。
import { EpsonProjector } from "easymp";
const projector = new EpsonProjector({
host: "192.168.1.82",
localAddress: "192.168.1.17",
// ffmpegPath: "C:/tools/ffmpeg/bin/ffmpeg.exe",
});
try {
await projector.movie.play("./movie.mpg");
} finally {
await projector.close();
}動画再生と通常の画像投写は同じ EasyMP セッション用ポートを使うため、同時には実行できません。変換済みの対応 MPEG-TS は playTransportStream() で直接送信できます。
電源だけ操作する
import { EscVpClient } from "easymp";
const control = new EscVpClient({
host: "192.168.1.82",
// 複数 NIC がある場合はプロジェクター側の LAN アドレスを指定
localAddress: "192.168.1.17",
});
await control.command("PWR ON");
console.log(await control.query("PWR")); // "01"
await control.command("PWR OFF");サンプル
# EMP-1715 に赤い 128x128 の矩形を表示
bun run dev
# 電源状態を表示。引数に on / off も指定可能
bun run example:power -- on
# 音声状態、音量、出力先、A/Vミュートを操作
bun run example:audio -- status
bun run example:audio -- volume 10
bun run example:audio -- output internal
bun run example:audio -- mute
bun run example:audio -- unmute
# 任意画像を全面表示
bun run example:image -- ./dashboard.png
# ffmpegで変換しながら音声付き動画を再生
bun run example:movie -- ./movie.mpg接続先はサンプル内の既定値を変更するか、EASYMP_HOST と EASYMP_LOCAL_ADDRESS を設定します。
公開レイヤー
EpsonProjector: 電源、状態、表示をまとめた高レベル APIEscVpClient: TCP 3629 の ESC/VP.net コマンドProjectorAudio: 音量、内蔵/外部音声出力、A/Vミュート制御EasyMPSession: UDP/TCP 3620 の EEMP セッションEasyMPMovie: 動画再生モードの折り返しHTTP配信とMPEG-TS変換EasyMPVideo: TCP 3621 の映像チャネルcreateEprdPacket: JPEG タイルから EPRD パケットを生成encodeFrame: 画像のリサイズ、タイル分割、差分検出、JPEG 化
制約
- 映像接続要求には EMP-1715 のキャプチャから得た未解析フィールドが残っています。
- 同一マシン上では TCP/UDP 3620 を使用する EasyMP セッションを同時に複数開始できません。
- プロジェクター実機を使う統合テストは自動テストに含まれません。パケット生成・画像処理は
bun testで検証できます。 - 通常のLAN画面投写では音声を転送できません。ネットワーク音声はEasyMPの動画再生モード専用です。
- 動画再生には別途
ffmpegが必要です。現在の変換プロファイルと通信手順は EMP-1715 のキャプチャから再現しており、他機種では未検証です。解析結果はdocs/audio-protocol.mdに記録しています。
対応環境
- Bun 1.3以降
- Node.js 20.9以降(ES Modules)
- EMP-1715:ESC/VP.net制御、EasyMP画像表示、音声付き動画再生を実機確認済み
- その他のESC/VP.net対応機:制御APIは利用できる可能性がありますが未検証
開発とリリース
変更を送る前に次を実行してください。
bun run verify
bun pm pack --dry-runリリースはSemantic Versioningに従います。GitHub Releaseを公開すると、npm Trusted Publishingを設定済みのリポジトリでは対応するバージョンがnpmへ公開されます。変更履歴は CHANGELOG.md を参照してください。
