iOS11がリリース(9月20日)されてから、はや1ヶ月半弱、
iPhone8が発売(9月22日)されてからも、はや1ヶ月半弱、
iPhoneXが発売(11月3日)されてしてから、はや3日が立ち、
32ビットアプリが動かなくなるという情報からか、リリース直後は若干苦戦していたiOS11のシェアも、
アナリティクスを確認する限りでは、着々と増えてきております。
さてさて、
New in Safari 11.0 – Camera and microphone access.
Added support for the Media Capture API.
Websites can access camera and microphone streams from a user's device (user permission is required.)
とあるように、iOS11からはウェブサイトからカメラとマイクにアクセスできるようになりました。
iOS11のシェアが増えてきたいまこそ、ウェブサイトからカメラやマイクにアクセスするサイトをつくるチャンスなのではないかと思い、
シンプルなサンプルを書いてみました。ソースはリポジトリにアップしております。
カメラにアクセス
github.com
マイクにアクセス
github.com
はじめに
- マイク、カメラにアクセスするためにはhttpsのサイトであることが必須条件です。
- Androidでは動作確認しておりません。
カメラにアクセス編
フロントカメラにアクセス
https://kimizuka.github.io/webcamera-preview-for-ios11/front-camera/
明示的にフロントカメラを渡していますが、
medias = {audio : false, video : true}
という感じで、明示的に渡さなくても基本的にフロントカメラが立ち上がります。
ソースコード
JavaScript
const medias = { audio: false, video: { facingMode: "user" // フロントカメラにアクセス } }; const video = document.getElementById("video"); const promise = navigator.mediaDevices.getUserMedia(medias); promise.then(successCallback) .catch(errorCallback); function successCallback(stream) { video.srcObject = stream; }; function errorCallback(err) { alert(err); };
HTML
<video id="video" autoplay playsinline></video><!--インライン再生を可能にしておく-->
CSS
body { margin: 0; background: #000; } #video { display: block; width: 100%;
リアカメラにアクセス
https://kimizuka.github.io/webcamera-preview-for-ios11/rear-camera/
ソースコード
JavaScript
const medias = { audio: false, video: { facingMode: { exact: "environment" // リアカメラにアクセス } } }; const video = document.getElementById("video"); const promise = navigator.mediaDevices.getUserMedia(medias); promise.then(successCallback) .catch(errorCallback); function successCallback(stream) { video.srcObject = stream; }; function errorCallback(err) { alert(err); };
HTML
<video id="video" autoplay playsinline></video><!--インライン再生を可能にしておく-->
CSS
body { margin: 0; background: #000; } #video { display: block; width: 100%;
応用例
https://kimizuka.github.io/webcamera-preview-for-ios11/carnvas-demo/
車窓とあわせる用の簡易ARのデモです。
すべてcanvasにレンダリングしても良かったのですが、カメラから取り込んだ映像以外はCSSで描画しています。
画面をタップするとジャンプします。
折角CSSを使っているので、targetセレクタをつかって、#reverseで反転させようと思ったのですが、
何故かiOSでうまくいきません。(原因調査中)
ソースはリポジトリを直接見ていただいたほうが早いと思います。
マイクにアクセス編
マイク入力をビジュアライズ
https://kimizuka.github.io/mic-preview-for-ios11/analyse/
iOSの制約で「ユーザージェスチャーきっかけで無いとオーディオを再生できない」という点に苦戦しました、
はじめに画面をタップさせることで制約を回避しました。
FFTを掛けて画面上にビジュアライスしています。
ソースコード
JavaScript
(function() { "use strict"; const btn = document.getElementById("btn"); const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(_handleSuccess).catch(_handleError); function _handleSuccess(stream) { btn.addEventListener("click", () => { _handleClick(stream); }, false); } function _handleError() { alert("Error!"); } function _handleClick(stream) { const LENGTH = 16; const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const options = { mediaStream : stream }; const src = audioCtx.createMediaStreamSource(stream); const analyser = audioCtx.createAnalyser(stream); const data = new Uint8Array(LENGTH); let w = 0; btn.classList.add("off"); analyser.fftSize = 1024; src.connect(analyser); setInterval(() => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; ctx.fillStyle = "#3e3e3e"; w = canvas.width / LENGTH, analyser.getByteFrequencyData(data); for (let i = 0; i < LENGTH; ++i) { ctx.rect(i * w, canvas.height - data[i] * 2, w, data[i] * 2); } ctx.fill(); }, 20); } })();
HTML
<canvas id="canvas"></canvas> <div id="btn">TAP TO START</div>
CSS
body { font: 20px "Rubik Mono One", sans-serif;; background: #e3e3e3; overflow: hidden; } #btn { display: flex; position: absolute; top: 0; bottom: 0; left: 0; right: 0; color: #3e3e3e; align-items: center; justify-content: center; opacity: 1; transition: opacity .2s ease-in-out; } #btn.off { opacity: 0; pointer-events: none; } #canvas { display: block; }
音声認識(失敗)
こちらでつくったサンプルをiOS11で試してみましたが、
残念ながら、動作しませんでした。
それもそのはず、SpeechRecognitionはまだ未実装ですね。
今回はiOS11に限ったコードを書きましたが、
実践に投入するにはAndroidやPCでも動くようにしなければならないですね。
それは、そのうち頑張って書こうと思います。今回は以上となります。
追記: 2018/02/17
Navigator.getUserMediaが非推奨となったため、MediaDevices.getUserMediaを使うように修正しました。