All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 28s
5.5 KiB
5.5 KiB
sidebar_position, title, description, hide_table_of_contents, displayed_sidebar
| sidebar_position | title | description | hide_table_of_contents | displayed_sidebar |
|---|---|---|---|---|
| 99 | ローカルサーバーでマイク・カメラを使う方法 | HTTP + IPアドレスでブラウザのマイク・カメラが動かない問題の解決策 | false | null |
ローカルサーバーでマイク・カメラを使う方法
問題
ローカルネットワーク上のサーバー(例: http://192.168.1.100:7860)にブラウザからアクセスすると、マイクやカメラが使えない。
NotAllowedError: Permission denied
原因
ブラウザの セキュアコンテキスト 制限。getUserMedia()(マイク・カメラ API)は以下の条件でのみ動作:
https://— HTTPS接続http://localhost— ローカルホストhttp://127.0.0.1— ループバック
http://192.168.x.x は対象外。
解決策
方法1: SSHトンネル(推奨)
最も簡単。リモートサーバーのポートを localhost にフォワード。
ssh -L 7860:localhost:7860 user@192.168.1.100
その後 http://localhost:7860 でアクセス → マイク使用可能!
複数ポートの場合:
ssh -L 7860:localhost:7860 -L 8000:localhost:8000 user@192.168.1.100
方法2: Chromeフラグで許可
テスト用途に。特定のIPをセキュアコンテキストとして扱う。
- Chromeで
chrome://flagsにアクセス Insecure origins treated as secureを検索- 許可するURLを追加(例:
http://192.168.1.100:7860) - Chrome再起動
:::warning セキュリティが低下するため、開発・テスト用途に限定してください。 :::
方法3: 自己署名証明書でHTTPS化
チーム共有や本格運用向け。サーバー側でHTTPSを有効化。
Step 1: 証明書を生成
サーバー側で以下を実行:
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem \
-out cert.pem \
-days 365 \
-nodes \
-subj "/CN=192.168.1.100" \
-addext "subjectAltName=IP:192.168.1.100"
| オプション | 説明 |
|---|---|
-keyout key.pem |
秘密鍵ファイル(サーバーが使う、外部に漏らさない) |
-out cert.pem |
証明書ファイル(クライアントに配布可能) |
-days 365 |
有効期限(1年) |
-nodes |
パスフレーズなし(サーバー自動起動用) |
-subj "/CN=..." |
Common Name(IPアドレスまたはホスト名) |
-addext "subjectAltName=..." |
SANs(最近のブラウザで必須) |
生成されるファイル:
key.pem # 秘密鍵(絶対に公開しない)
cert.pem # 証明書(クライアントに配布OK)
Step 2: サーバーで証明書を使う
Gradio:
python app.py --ssl-keyfile key.pem --ssl-certfile cert.pem
FastAPI / Uvicorn:
uvicorn main:app --host 0.0.0.0 --port 8000 \
--ssl-keyfile key.pem --ssl-certfile cert.pem
Python http.server(簡易):
import ssl
import http.server
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('cert.pem', 'key.pem')
server = http.server.HTTPServer(('0.0.0.0', 8000), http.server.SimpleHTTPRequestHandler)
server.socket = context.wrap_socket(server.socket, server_side=True)
server.serve_forever()
Node.js / Express:
const https = require('https');
const fs = require('fs');
const app = require('./app');
https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
}, app).listen(8000);
Step 3: ブラウザでアクセス
https://192.168.1.100:8000 にアクセスすると警告が出る:
Chrome:
- 「この接続ではプライバシーが保護されません」と表示
- 「詳細設定」をクリック
- 「192.168.1.100 にアクセスする(安全ではありません)」をクリック
Firefox:
- 「警告: 潜在的なセキュリティリスクあり」と表示
- 「詳細」→「危険性を承知で続行」
Safari:
- 「この接続はプライベートではありません」と表示
- 「詳細を表示」→「このWebサイトを閲覧」
Step 4: 証明書を信頼済みに登録(オプション)
毎回警告を出したくない場合、証明書をOSに登録。
macOS:
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain cert.pem
Ubuntu/Debian:
sudo cp cert.pem /usr/local/share/ca-certificates/myserver.crt
sudo update-ca-certificates
Windows:
cert.pemをcert.crtにリネーム- ダブルクリック → 「証明書のインストール」
- 「ローカルマシン」→「信頼されたルート証明機関」に配置
:::tip
チームで共有する場合は cert.pem を配布し、各メンバーがOSに登録すると便利です。
:::
方法4: ngrok / Cloudflare Tunnel
外部サービス経由でHTTPS URL を取得。
ngrok http 7860
# → https://xxxx.ngrok.io が発行される
早見表
| 方法 | 難易度 | セキュリティ | 用途 |
|---|---|---|---|
| SSHトンネル | ★☆☆ | ◎ | 開発・日常利用 |
| Chromeフラグ | ★☆☆ | △ | 一時的なテスト |
| 自己署名証明書 | ★★☆ | ○ | チーム共有 |
| ngrok等 | ★★☆ | ◎ | 外部共有・デモ |
関連
- DGX SparkでVibeVoice ASRを動かす — リアルタイム音声認識