2013年12月16日月曜日

HTML5でビデオや音楽を再生している時にスクリーンセーバーを無効にすることはできるか?

結論から言うと不明。現在のところは多分無理。

HTML5でビデオや音楽を再生している時にふと気づいた。スクリーンセーバーがいちいち起動するのがウザいなと。

Flashならフルスクリーン時には自動的にスクリーンセーバーを無効にしてくれるのだが、HTML5やJavascriptのレベルでスクリーンセーバーを無効にすることはできるのか?もしできないとすれば、HTML5のウェブアプリの非常に大きなUX的問題じゃないか?

と思って色々調べてみたら、2009年頃から問題になっていて4年経った今まで解決されていない問題らしい_| ̄|○

html5 - How to prevent a monitor from sleeping while watching html 5 animation - Stack Overflow

そう。Huluなんかでフルスクリーン時にスクリーンセーバーが起動しないのはFlashのおかげなんだよね。これもまだ脱Flashできない一つの理由になっていると思う。実際、この問題が発覚したためにFlashに戻ったと言ってる人も居た。

I have shifted back to flash plugins since I had this issue. Haven't gone back..

これは問題だよ。彼の意見に賛成だ。HTML5の仕様に書き加えられるべきだと思う。

517870 – Fullscreen video should disable screensaver during playback

It's not possible in pure HTML. Hulu does it because it's Flash-based, and the plugin has access to the OS layers, which is something JS or HTML does not have. So the only way to do this would be to have a new paragraph in the HTML5 spec.

ここまでのところで「まぁ大体ムリだろうな」ということは分かったのだけれど、彼らの議論の中でひとつ希望っぽいものがあった。

それは、「Javascriptから定期的に仮想的にマウスイベントやキーボードイベントを発行してみたらどうか?」というもの。なるほど。

ということでやってみた。結論から言うと役に立たなかった。

イベントの発行方法についてはこちらを参考にさせて頂いた。

JavaScript Tips – dispatchEvent を使いこなそう!! | TM Life

上のボタンで、仮想的に下のボタンを10秒に1回クリックするタイマーを開始・停止できる。





コードはこんな感じ。

<button id="btnTimer" onclick="onClickBtnTimer();>仮想クリックタイマー開始</button>
<button id="btnDummy" onclick="onClickBtnDummy();">ダミーボタン</button>
<script type="text/javascript">
  var timer = null;
  function onClickBtnTimer() {
    console.log("onClickBtnTimer()");
    var btnTimer = document.getElementById("btnTimer");
    if (timer) {
      console.log("タイマー停止!");
      clearInterval(timer);
      timer = null;
      btnTimer.innerHTML = "仮想クリックタイマー開始";
    } else {
      console.log("タイマー開始!");
      timer = setInterval(function() {
        console.log("インターバル!");
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        var btnDummy = document.getElementById("btnDummy");
        btnDummy.dispatchEvent(evt); //ここで仮想クリック!
      }, 10000);
      btnTimer.innerHTML = "仮想クリックタイマー停止";
    }
  }
  function onClickBtnDummy() {
    console.log("onClickBtnDummy()");
  }
</script>

つまり、目論見通りならば、仮想的にマウスクリックを起こすことでユーザーの手でマウスを動かしているのと同じことになって、スクリーンセーバーの起動を阻止できるんじゃないか?と。

確かに、ブラウザ内ではマウスイベントが起こっているように見えるが、それがOSレベルにまで伝わっている気配はない。

残念だ。