世界を動かす技術を、日本語で。

USB/IPを介してWebUSBに接続されたブラウザ内Linux仮想マシンで古いプリンターを救う

概要

  • Canon SELPHY フォトプリンターを偶然入手し、Linux環境で再活用した体験談
  • WebUSBv86エミュレーター を活用したクロスプラットフォーム印刷アプリ開発
  • CUPS, Gutenprint, Avahi などのOSS技術によるAirPrint共有
  • Claude Code と協働し、プリンター復活のためのネイティブ・Webアプリ開発
  • 今後の展望 や課題、オープンソース化への思い

古いCanon SELPHYプリンターの再活用ストーリー

  • Canon SELPHY フォトプリンターを友人Markから譲り受けた経緯
    • 3Dプリンターと交換で入手
    • eBay で消耗品より安価に流通する理由
  • MacやWindows ではドライバが未対応
    • Markは Linux ユーザーのため問題なし
  • 手元の Manjaro Linux マシンで動作確認
    • CUPSGutenprint で印刷成功
    • AvahiAirPrint 共有を実現
  • 家族全員が Mac/iPhone から写真印刷を楽しめる環境構築
    • 物理写真の手軽な印刷体験
    • CMY分解印刷 の工程観察

プリンターの「非オタク化」への挑戦

  • 両親にも同様の体験を提供したい思い
    • Raspberry Pi サーバー案はコスト・配線面で断念
  • ソフトウェアだけで簡単に使える方法の模索
    • Claude Code (AI)と共に開発開始
    • Macネイティブアプリ でLinux VMを仮想化しUSB転送
      • App Storeの制約やMac限定の課題

Webアプリへの転換と技術的工夫

  • ChromeのWebUSB に着目しWebアプリ化を決断
    • v86 エミュレーターでx86 Linux仮想環境をブラウザ内で実現
      • Alpine Linux, CUPS, Gutenprint を内蔵
    • プリンターの型番自動検出とドライバ自動インストール
    • ファイルアップロード→仮想Linuxで印刷コマンド発行
  • WebUSB 経由でプリンターへ直接バイナリデータ送信

CUPSとWebUSBの橋渡し

  • 最初は CUPSバックエンド を自作
    • v86のTTY経由でデータ転送
    • stty raw 設定でデータ化け解消
  • 2回目は v86の9pファイルシステム で大容量転送
    • Linux側で ファイル同期 の重要性を学ぶ
  • 課題:プリンターからのエラー情報が取得できない一方通行通信

双方向通信への進化とスキャナー応用

  • USB/IPtcpip.js を用いた双方向通信
    • v86内のLinuxで USB/IP、JS側で tcpip.js (lwIPをWASM化)
    • CUPS がプリンター状態を正確に把握可能
  • SANE を使ったスキャナー復活アプリも試作
    • yes-we-scan.app として公開予定

実用化への細かな工夫

  • JPEG埋め込みPDF 生成で印刷サイズ問題を解決
    • EXIF回転・ICCプロファイル 対応
  • HEIC→JPEG変換パイプライン もAIで自動生成
    • libheif-js, wasm-mozjpeg 連携
  • 消耗品アフィリエイトリンクや簡易テレメトリも実装
    • Neon Postgres DB でセッション・プリンター情報管理

今後の展望とオープンソース化

  • Gutenprint対応機種 なら他モデルでも動作可能性
    • 問題があれば連絡を呼びかけ
  • PPD追加 (brlaser, splix等)の余地
  • オープンソース化は未定
    • 商用連携 やホワイトラベル化の希望
    • 無料でforkされるよりも企業連携を優先

まとめ

  • 古いプリンターの再活用Web技術による新たな価値創出
  • Claude Code の活用による開発効率化
  • プリンター消耗品企業 との連携を模索する今後の展開

Hackerたちの意見

LLMを使ってるなら、関連するCUPSドライバーを見つけるか、USBトラフィックをキャプチャして、Goとかネイティブなもので書き直す方がずっと簡単だったんじゃない?(システムの印刷フレームワークを扱う必要もないし、目標はJPEG入力を受け付けるアプリだけだったし。)

面白い提案だね。確かにそれは可能だったかも。でも、これはもっと一般的な解決策だと思うし、無駄に車輪を再発明することも最小限に抑えられてるよ。

それか、エージェントにDockerfileを書かせて、CUPSやその周りのものをWASMで直接ビルドするようにしてもらうのもいいかもね。x86をターゲットにしてからWASMでエミュレートするんじゃなくて。

確かに、CUPS-rasterデータを入力として受け付けるシンプルなドライバー(CUPSフィルター)にはそれが可能だね。古いプリンターのドライバーの大半がそうだよ。

ありがとう、これめっちゃ良かった!思わず「なるほど!」って感じ。家に古めのSamsungレーザープリンターがあって、Linuxファイルサーバーもあるんだけど、そのプリンターはもうAirPrintをサポートしてないんだ。LinuxボックスをAirPrintサーバーとして使うなんて考えたこともなかった!これで子供たちからの変な印刷リクエストから解放されるかも!(多分)

まだ手放せないSamsung ML-1740があるんだ。ずっとRasPi化しようと思ってるんだけど、これがまた深い穴にハマりそうなプロジェクトなんだよね。

ドライバーをちゃんと揃えられれば、うまくいくよ。12年前のブラザーのレーザープリンターを何回か試してみたけど、毎回投げ出しちゃった。いつかLLMの助けを借りて再挑戦してみようかな。

サムスンのプリンターとCUPSを使って似たようなことを何年もやってるけど、めっちゃ便利だよ。設定ファイルを生成するのに役立つのを見つけたよ: https://github.com/tjfontaine/airprint-generate

これ、かなりの天才的アイデアだね。周りには古すぎたりニッチすぎて現代の何にも対応してないUSBデバイスが結構あるんだ。例えば、GameBoy Advanceのフラッシュカートリッジとか。

あ、そういえばv86は古いDOS/Windowsのバージョンもたくさんサポートしてるから、正しいポートを通せれば(USBなら多分簡単、他のものでも可能かも?)古いドライバーを使えるかもしれないね:)

これまでにオープンソースにしていない部分について謝らなきゃいけないね。主に、これがプリンター消耗品の会社が自社の販売サイトに統合するための素晴らしいウェブプロパティになると思ってるから。単にリポジトリをフォークして無料で手に入れるより、彼らが私にホワイトラベルで作らせてくれた方がずっといいな。彼らが自社のプリンターの使いやすさに少しでも興味があれば、きっと興味を持つだろうね。

それは、プリンターのOEMじゃなくて、アフターマーケットのインクカートリッジ会社のことを言ってるんだよ。

Hacker Newsで議論の続きを見る