0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pygrabberを含むスクリプトをnuitkaでビルドする方法

Posted at

ソースコード

get_cam_devices.py
from pygrabber.dshow_graph import FilterGraph
import sys

def list_connected_cameras():
    """
    pygrabber.dshow_graph.FilterGraphを使用して、
    接続されているカメラデバイスの一覧を表示します。
    """
    print("接続されているカメラを検索しています...")

    try:
        # FilterGraphオブジェクトを初期化
        graph = FilterGraph()
        
        # 入力デバイス(カメラ)のリストを取得
        # (これはデバイス名の文字列リストを返します)
        device_list = graph.get_input_devices()

        if not device_list:
            print("  利用可能なカメラが見つかりませんでした。")
            return

        print("--- 接続されているカメラ一覧 ---")
        # device_listは文字列のリストなので、enumerateでインデックスを付けます
        for i, device_name in enumerate(device_list):
            print(f"  インデックス {i}: {device_name}")
        
        print("---------------------------------")
        print("※このインデックスがOpenCV等で使用できるIDに対応します。")

    except Exception as e:
        print(f"エラーが発生しました: {e}", file=sys.stderr)
        print("pygrabberはWindows環境(DirectShow)でのみ動作します。", file=sys.stderr)

if __name__ == "__main__":
    list_connected_cameras()

ビルドコマンド

nuitka --standalone --onefile --follow-imports --output-dir=build --include-package=pygrabber --include-package=comtypes --nofollow-import-to=comtypes.gen get_cam_devices.py

解説

まず、普通にpygrabberを含むスクリプトをビルドしても、モジュールが見つからないため、 --include-package=pygrabber のオプションが必要になる。
また、pygrabberはcomtypesというパッケージに依存しているので --include-package=comtypes も必要になる。
オプションを付けて、ビルドしたところ、次は以下のようなエラーとなった

C:\Users\1-10\Desktop>get_cam_devices.exe

Traceback (most recent call last):

  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\get_cam_devices.py", line 2, in <module>
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\pygrabber\dshow_graph.py", line 43, in <module pygrabber.dshow_graph>
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\pygrabber\dshow_core.py", line 41, in <module pygrabber.dshow_core>
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 126, in GetModule
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 238, in generate
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 126, in GetModule
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 239, in generate
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 211, in _create_module
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\client\_generate.py", line 25, in _my_impor
  File "importlib.py", line 88, in import_module
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\gen\_00020430_0000_0000_C000_000000000046_0_2_0.py", line 671, in <module>
  File "C:\Users\1-10\AppData\Local\Temp\ONEFIL~1\comtypes\_tlib_version_checker.py", line 18, in _check_version

ImportError: Typelib different than module

Geminiによると

  • comtypes のキャッシュ機構: pygrabber が内部で利用している comtypes は、WindowsのCOMライブラリ(DirectShowなど)と連携します。 comtypes は、初めてCOMライブラリにアクセスする際、その定義情報(タイプライブラリ)を読み取り、対応するPythonコードを動的に生成します。 そして、高速化のために、生成したコードを comtypes.gen というフォルダ(パッケージ)内にキャッシュファイル(.pyファイル)として保存します。

  • Nuitkaビルド時の問題: Nuitkaで --standalone ビルドを行う際、開発環境に**すでに存在していた古いキャッシュファイル(comtypes.gen フォルダの中身)**が、そのままexeファイル内にパッケージング(同梱)されてしまいます。

  • 他のPCでの実行時エラー: そのexeファイルを他のPCで実行すると、comtypes はexeに同梱されたキャッシュファイル(開発環境のCOMバージョンに基づくもの)を読み込もうとします。 しかし、実行PCの実際のCOMライブラリのバージョンが、キャッシュファイル作成時のバージョンと異なっています。 comtypes はこの矛盾を検知し、「タイプライブラリとモジュール(キャッシュ)が違う」という意味の ImportError: Typelib different than module エラーを発生させます。

ということらしい。

--nofollow-import-to=comtypes.genというオプションを追加すれば解決する。

  • --nofollow-import-to=comtypes.gen ご提示いただいたヘルプの「Control the following into imported modules:」セクションにある通り、このオプションは Nuitka に対して「comtypes.gen という名前のパッケージが import されていても、それを追いかけず、ビルドに含めない」よう指示します。

  • エラーの回避 comtypes が引き起こす ImportError: Typelib different than module エラーは、開発PCで生成されたキャッシュ(comtypes.gen の中身)が、実行PCのCOMライブラリとバージョン不一致を起こすことが原因です。

このコマンドでキャッシュ(comtypes.gen)を意図的に除外することにより、exe を実行したPC上で comtypes が実行時にそのPC環境に合った正しいCOM情報を(キャッシュを使わずに)生成するようになり、エラーが解決されます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?