いよいよFelicaポート搭載のiPhone 7が発表されましたね!サプライズもありまだまだ日本でのiPhone一強は続くのではないかと感じさせられました。
さて、そのiPhone 7に搭載される予定のiOS 10ではいよいよsafariでも動画のインライン再生が可能になります。
- [iOS 10 Safari から video の inline 再生が可能になります - latest log]
(http://uupaa.hatenablog.com/entry/2016/08/29/171809)
##iOS 9以下でもインライン再生する
- [iPhone Safariで動画をインライン再生する方法 - Qiita]
(http://qiita.com/hadakadenkyu/items/75162099d0bf7cdcfdc7) - [【音声対応】 iPhone Safariで動画をインライン再生する方法続き - Qiita]
(http://qiita.com/hadakadenkyu/items/b8accc395ccfa8348faf)
以前書いたこの2つの記事で紹介した方法はいずれも、video要素のcurrentTimeを動かしてcanvas要素に描画するというものでした。
##今更発見した新手法
今回見つけた手法では、canvas要素に描画するのはそのままですが、video要素はcurrentTimeを動かすのではなく普通に再生します。そのため、音声と同期を取る必要はなくなりました!
##発見の経緯
確かAutoPagerizeみたいなことするbookmarkletをjQueryレスに書き換えるときにcreateHTMLDocument
を使ったのですが、その時にふと「これの中でvideoとかaudioとか再生したらどういう扱いになるんだろう」と思って試しにvideoを再生してみたところ、映像は当然見えませんが音声は流れてきたため、これはもしや再生中のvideoをcanvas要素のコンテキストに渡せばそのまま表示されるんじゃないかとやってみたら上手くいきました。
##createHTMLDocument
[DOMImplementation.createHTMLDocument() - Web API インターフェイス | MDN]
(https://developer.mozilla.org/ja/docs/Web/API/DOMImplementation/createHTMLDocument)
現在のHTMLDocumentとは異なるHTMLDocumentを作成するもので、受け取った文字列を安全にHTMLにパースするときとかに使います、確か。
Sample Code
var btn = document.querySelector('button');
btn.disabled = true;
var match = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
var majorVersion;
var isIOS = false;
var lte9 = false;
if (match !== undefined && match !== null) {
isIOS = true;
majorVersion = parseInt(match[1], 10);
if(majorVersion<10){
lte9 = true
}
}
var doc,video;
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
// スマホかどうかはまた別で判定するとして・・・
if(isIOS && lte9){ // iOS9以下なら
doc = document.implementation.createHTMLDocument(''); // 別HTMLDocumentを作成
video = document.createElement('video');
video.addEventListener('canplay',function(){ // 再生可能になったら別HTMLDocumentに移す
doc.body.appendChild(video);
},false);
var prms = new Promise(function(resolve, reject) {
video.addEventListener('canplay',function(){
resolve();
});
video.addEventListener('error',function(){
reject();
alert('failed loading video');
});
});
prms.then(function(){
btn.disabled = false;
});
video.src = 'test.mp4';
video.load();
togglePlay = function(){
if(video.paused){
video.play();
(function loop(){
ctx.drawImage(video, 0, 0, 480, 360);
if(!video.paused){
requestAnimationFrame( loop );
}
})();
} else {
video.pause();
}
};
btn.addEventListener('click',function(){
togglePlay();
},false);
} else { // androidやiOS10以上なら普通にvideoタグ使えば良い
// 省略
}
##DEMO
http://jsrun.it/hadakadenkyu/6YoX
##補足
- タップ無しで再生出来ません。つまり自動再生は出来ません。
- 自動再生が必要な場合は以前紹介した手法が使えます(但し音無し)。
- WebGLでもイケます。
#最後に
報道によると既存機種向けのダウンロードは14日開始とのことで、この記事の賞味期限もあと一週間くらいですね!
あとこれバグ臭い気がする