3
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?

Mac の Electron アプリで app 実行したときにカメラにアクセスできない

Last updated at Posted at 2022-07-26

20240617 追記

Bartender 4 で案内されてはじめて知ったのだけれども、権限周りにおいて不具合があるよう。

Bartender 4 - Bartender and macOS Ventura and 12.6.1 Accessibility and Screen Recording Permissions bug

tccutil reset Accessibility com.surteesstudios.Bartender; tccutil reset ScreenCapture com.surteesstudios.Bartender; tccutil reset Accessibility com.surteesstudios.Bartender-setapp; tccutil reset ScreenCapture com.surteesstudios.Bartender-setapp


カメラとスクリーンキャプチャは異なるけれども、(スクリーンキャプチャの Electron アプリも権限で同様におかしかった)これが原因でおかしい可能性がある。
なので、tccutil で権限をリセットして試すのもひとつかもしれない。
Bartender 4 それ自体はこの案内の通りで正常に動作するようになった。
署名されているアプリでもこの辺は関係ないぽい。

20231204 追記

以下の方法では、macOS Sonoma バージョン 14.1 でうまくいかなかったです。
権限周りであるとは思うのだけれど・・・。

別のアプリで、同じように画面収録する権限もうまくいきませんでした。
systemPreferences | Electron
systemPreferences | Electron

アプリに署名したら多分いけると思います。

はじめに

Mac で動作する Electron アプリをビルドし、 xxx.app を実行したときにカメラにアクセスできずに困った。
結論、 Mac で動作するアプリはカメラアクセスの許可を取得すれば OK でした。

探せなかっただけかもしれないけれど、
英語でもこのことずばりで書いている Issue さくっとみつけられなかったのでメモ。

環境

  • OS: macOS Big Sur 11.3.1
  • Architecture: arm64
  • Runtime: node.js v16.15.0 (anyenv + nodenv)
  • Main Framework: Vue v3.2.13, Electron v13.0.0, vue-cli-plugin-electron-builder v2.1.1

カメラへのアクセス

Web Application では、 getUserMedia でデバイスのカメラにアクセスしてストリームオブジェクトを取得、
これを video.srcObject あたりにいれてやれば映像にアクセスできます。
MediaDevices.getUserMedia() - Web API | MDN

Electron で WebCam にアクセスするのはこれで OK です。
npm run electron:serve で実行したところ問題なく動作しました。

問題

じゃーこれで署名なしビルドしてとりあえず実行しているみかと思い、
npm run electron:build でビルドしたアプリを実行しました。

DOMException: Could not start video source


こんなエラーが JS ランタイムに表示され、カメラの映像が表示されません。
調べてみると getUserMediadeviceId を指定するとき、以前の MediaStream が開放されていないのが原因とあってこれかなーと思いやってみるもダメ。
Androidで getUserMedia() したら NotReadableError: could not start video source - console.lealog();
こちらは、 Android WebView でのはなしかな。

解決方法

JavaScript や DOM まわりの単純な不具合じゃないなーと思ったので、 Mac の権限まわりかなと思う。
Electron でカメラやマイクへのアクセス権限どうやって取得するかのドキュメントがあった。
systemPreferences | Electron

めっちゃこれっぽい。
てことで、メインプロセス(レンダラープロセスじゃない)でこれを実行してみた。
実行するタイミングあってるかは微妙だけどとりあえず、、、
(Android や iOS アプリ一般でいえば、必要になる箇所で権限取得するのがよいかも?)

import {app, systemPreferences} from 'electron'

~~~

app.on('ready', async () => {
  if (isDevelopment && !process.env.IS_TEST) {
    // Install Vue Devtools
    try {
      await installExtension(VUEJS3_DEVTOOLS)
    } catch (e) {
      console.error('Vue Devtools failed to install:', e.toString())
    }
  }
  await systemPreferences.askForMediaAccess('camera').then((e) => {
    console.log('success media access', e)
  }).catch((e) => {
    console.log('failed media access', e)
  })
  createWindow()
})


ready イベントでウィンドウ作成前に処理を await でブロックしてやってみた。
ドキュメントにも記載ありますが、 systemPreferences.askForMediaAccess を使用するには、 Info.plistNSCameraUsageDescriptionNSMicrophoneUsageDescription のプロパティが必要です。
これがないと権限取得 API コール時にアプリが(おそらく)クラッシュします。
iOS アプリでもこのへんは同様のやつですね。

なお、 systemPreferences.getMediaAccessStatus('camera') で現在の権限チェックもできるので、カメラアクセスが必要な Mac Electron アプリはこれをつかって権限チェックするのが適切ですね。

おわり。

3
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
3
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?