Edited at

iOS 9以下でもiPhone safariでインラインで動画再生する方法第三弾

More than 1 year has passed since last update.

いよいよFelicaポート搭載のiPhone 7が発表されましたね!サプライズもありまだまだ日本でのiPhone一強は続くのではないかと感じさせられました。

さて、そのiPhone 7に搭載される予定のiOS 10ではいよいよsafariでも動画のインライン再生が可能になります。


iOS 9以下でもインライン再生する

以前書いたこの2つの記事で紹介した方法はいずれも、video要素のcurrentTimeを動かしてcanvas要素に描画するというものでした。


今更発見した新手法

今回見つけた手法では、canvas要素に描画するのはそのままですが、video要素はcurrentTimeを動かすのではなく普通に再生します。そのため、音声と同期を取る必要はなくなりました!


発見の経緯

確かAutoPagerizeみたいなことするbookmarkletをjQueryレスに書き換えるときにcreateHTMLDocumentを使ったのですが、その時にふと「これの中でvideoとかaudioとか再生したらどういう扱いになるんだろう」と思って試しにvideoを再生してみたところ、映像は当然見えませんが音声は流れてきたため、これはもしや再生中のvideoをcanvas要素のコンテキストに渡せばそのまま表示されるんじゃないかとやってみたら上手くいきました。


createHTMLDocument

DOMImplementation.createHTMLDocument() - Web API インターフェイス | MDN

現在の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日開始とのことで、この記事の賞味期限もあと一週間くらいですね!

あとこれバグ臭い気がする