スマホでコードが動かない
PCではHTMLファイルをブラウザで読み込んでアプリを起動し問題無く動くこのコードですが、 同じ様にスマホのブラウザで読み込んで実行したところ動かない事が分かりました。 今回はこの件の説明です。
スマホはコードの扱いが違う
コードをPCとスマホのブラウザで読み込み比べてみました。
立ち上がり時に要求されるマイク使用許可がスマホでは要求されません。 スマホではWebRTCが起動しないのです。そこでWebRTCの起動条件を調べてみると
- WebRTCをサポートしているブラウザ(Chrome、Firefox、Safari、Edgeなど)が必要
- セキュリティ観点からHTTPS接続が要求される
- ブラウザがファイルを読み込む場合はHTTPS接続を必要としない
一見スマホも全ての条件を満たしている様に思えるのですが、よく見たら上記3がスマホとPCで違っている事が分かりました。
両者ブラウザのURL欄を見ると
PC側ブラウザ :/Documents/intercom/intercom.html
スマホ側ブラウザ:127.0.0.1:12389/main/0/storage/emulated/0/Documents/intercom/intercom.html
PCはファイルの保存場所なのですがスマホは先頭に”127.0.0.1:12389/main/0/storage/emulated/0/” が付いていました。スマホ(OSがAndroid)の場合、ストレージに保存されたファイルの 読み出しはエミュレータを通して行われ、そのためURLが上記の様になるようです。 コードがエミュレータを通して読み込まれる為WebRTCが使えない様です。
HTTPSサーバ製作と準備
スマホでこのコードを実行させる方法は下記の2つ。
- エミュレータを通さずに直接コードを読み込む
- HTTPSサーバを上げる
HTTPSサーバを上げるを参考にサーバを製作して行きます。
- Homeディレクトリの下にinterフォルダを作成( $ mkdir inter)し移動( $ cd inter)
- 前回使用したファイル、intercom.html、intercom.js、intercom.cssをここにコピー。
- ”favicon.ico”(新規作成)をinterフォルダに作成
- ブラウザのファビコン用のファイルです。今回新規に作成しました。
- Raspberry Pi のアドレスを固定
- 同一LAN内でもスマホではDNSが使用出来ずサーバのアドレス固定が必要。
- IPアドレスを固定するにしたがってアドレスを固定。
- ”今回は192.168.1.200に固定しています。(ルータに合わせて調整して下さい)
sudo nmcli connection modify preconfigured ipv4.method manual ipv4.addresses 192.168.1.200/24 - アドレス固定に伴いファイル”intercom.js”を修正
81行 ws = new WebSocket(protocol + ‘//rasp.local:8090/stream/webrtc’);の rasp.local:8090 を 192.168.1.200:8090 と変更
- 証明書作成の作成
- SSLで使用する認証ファイルを作成
- interフォルダにlocalhost-key.pem と localhost.pemの2つのファイルを作成。
- UV4Lコンフィグファイル”/etc/uv4l/uv4l-uvc.conf”の修正
- SSLに対応する為コンフィグファイルの下記を変更
- 81行のコメントを外して --use-ssl=yes。
- 82、83行で認証ファイルの場所を指定
-
/etc/uv4l/uv4l-uvc.conf(part) text
# server-option = --config-password=myp4ssw0rd ### HTTPS options: server-option = --use-ssl=yes server-option = --ssl-private-key-file=/home/kita/inter/localhost-key.pem server-option = --ssl-certificate-file=/home/kita/inter/localhost.pem ### WebRTC options:
- Https Serer(inter.py)の作成
-
inter.py python
from http.server import HTTPServer, SimpleHTTPRequestHandler import ssl class MyHandler(SimpleHTTPRequestHandler): def do_GET(self): self.send_response(200) if self.path == "/": self.path = "/intercom.html" dataType = "text/html" elif self.path.endswith(".css"): dataType = "text/css" elif self.path.endswith(".js"): dataType = "application/javascript" elif self.path.endswith(".ico"): dataType = "text/plain" self.path = "." + self.path f = open(self.path,'rb') self.send_header('Content-type', dataType) self.end_headers() self.wfile.write(f.read()) f.close() host = '' port = 443 httpd = HTTPServer((host, port), MyHandler) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile='./localhost.pem', keyfile='./localhost-key.pem') httpd.socket = context.wrap_socket(httpd.socket, server_side=True) print("HTTPS Server running on https://X.X.X.X>:443") httpd.serve_forever() - 31行:SSLを使用する事を宣言
- 32行:認証用ファイルの指定
- 33行:ソケットの宣言
-
- interフォルダにPython仮想環境を作成します。仮想環境をinterとします。
python3 -m venv inter
これで準備完了です。この時点で ”inter” フォルダは以下の様になっています
今回のコードはここー> inter.zip
確認
先にRaspberry PIでサーバを上げ、その後スマホからアクセスします。
- サーバ立ち上げ手順
- Raspberry PIを上げ、interフォルダに移動
- 仮想環境を有効にし実行する。
- . inter/bin/activate
- sudo python3 inter.py
- モニタに”HTTPS Server running on https://X.X.X.X>:443″と表示されれば立ち上げ完了
$ cd inter /inter $ . inter/bin/activate /inter $ sudo python3 inter.py HTTPS Server running on https://X.X.X.X>:443
- スマホ側
- Webを立ち上げURL欄に ”192.168.1.200:433”と入力
- プライバシーエラーが表示されますが、HTTPSサーバを上げる と同じ様にHPの登録を行って下さい。
- 登録完了後、以下の様にマイクの使用許可が表示されます。
スマホで起動する事が確認出来ました。
終わりに
PCとスマホ両方でこのコードが動きました。