Skip to content

Instantly share code, notes, and snippets.

@leaysgur
Last active June 20, 2017 08:38
Show Gist options
  • Save leaysgur/44b6cff7b232751284fb4eb6903251ea to your computer and use it in GitHub Desktop.
Save leaysgur/44b6cff7b232751284fb4eb6903251ea to your computer and use it in GitHub Desktop.
iframe embed video player
window.handleMsg = function(ev, handler) {
// 同一ページ内イベントのみ受ける
if (ev.origin !== location.origin) { return; }
const { type, data } = JSON.parse(ev.data);
// そんなの待ち受けてないので無視
if (type in handler === false) { return; }
handler[type].call(handler, data);
};
window.createSender = function(win) {
return function(type, data) {
win.postMessage(JSON.stringify({
type,
data,
}), location.origin);
};
};
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Frame</title>
<style>
body { margin: 0; }
video { background-color: #000; }
</style>
</head>
<body>
<video id="v"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script src="./base.js"></script>
<script src="./frame.js"></script>
</body>
</html>
const { createSender, handleMsg, Hls } = window;
const msgSender = createSender(window.parent);
const isSafari = ((userAgent) => {
return userAgent.indexOf('Safari') !== -1
&& userAgent.indexOf('Chrome') === -1
&& userAgent.indexOf('Android') === -1;
})(navigator.userAgent);
const $video = document.getElementById('v');
$video.playsInline = true;
$video.addEventListener('timeupdate', () => {
msgSender('timeupdate');
}, false);
const hls = new Hls();
const handler = Object.assign({
init(size) {
// iframeのscrolling:noでスクロールできなくなるが、一応高さの保証をしたい
document.body.style.width = `${size.w}px`;
document.body.style.height = `${size.h}px`;
$video.style.width = `${size.w}px`;
$video.style.height = `${size.h}px`;
},
}, isSafari ? {
play({ url }) {
if ($video.src !== url) {
$video.src = url;
}
if ($video.paused) {
$video.play();
}
},
} : {
play({ url }) {
if ($video.src !== url) {
hls.stopLoad();
hls.loadSource(url);
hls.attachMedia($video);
}
if ($video.paused) {
hls.on(Hls.Events.MANIFEST_PARSED, () => {
$video.play();
});
}
}
});
window.addEventListener('message', ev => handleMsg(ev, handler), false);
const { createSender, handleMsg } = window;
const $form = document.getElementById('f');
const $iframe = document.getElementById('p');
const playerWidth = window.innerWidth;
const playerHeight = playerWidth * (9 / 16);
$iframe.style.width = `${playerWidth}px`;
$iframe.style.height = `${playerHeight}px`;
const msgSender = createSender($iframe.contentWindow);
$iframe.addEventListener('load', () => {
msgSender('init', {
w: playerWidth,
h: playerHeight,
});
// for autoplay
// msgSender('play', {
// url: $form.elements.url.value.trim(),
// });
}, false);
$form.addEventListener('submit', ev => {
ev.preventDefault();
msgSender('play', {
url: $form.elements.url.value.trim(),
});
});
const handler = {
timeupdate() { console.warn('watching..'); }
};
window.addEventListener('message', ev => handleMsg(ev, handler), false);
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Site</title>
<style>
body { margin: 0; }
input { width: 500px; }
iframe { background-color: #eee; }
ul { font-size: .5em; }
</style>
</head>
<body>
↓ここがiframe
<iframe
id="p"
src="./frame.html"
frameborder="0"
scrolling="no"
></iframe>
↑ここがiframe
<form id="f">
<input type="text" name="url" value="xxxxxxxxxxxxxxxxxxxx/master.m3u8">
<button type="submit">Submit</button>
</form>
<p>
HLSのURLを入れると、それが再生される`iframe`
</p>
<script src="./base.js"></script>
<script src="./main.js"></script>
</body>
</html>
@leaysgur
Copy link
Author

leaysgur commented Jun 20, 2017

  • iframeの高さ・スクロールバー問題は、内外のサイズが一緒なら問題なさそう
    • このコードは親側でiframeに指定したwidth / heightを、videoにも適用してる
  • PCだと自動再生できるが、モバイルではできない
    • mutedにすればモバイルでも自動再生できる
    • あとからユーザーイベントを受けてmuted = falseしても音は出る
  • postMessageを使う以外には、locationを操作すること、iframe.srcを書き換えでもやりとりできる
    • ?a=1みたいなのはリロードが発生する
    • #fooみたいなのはリロードしない(いつもと一緒)

  • macOS Siera 10.12.5 / Safari 10.1.1 | Chrome 60.0.3112.24
  • iOS 10.3.2 / Mobile Safari

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment