2013年04月20日

HTML5 Audio の tips【iOSの仕様 2】

昨日に引き続き HTML5 の Audio についての話。
iOS ではユーザの具体的なアクションがなければ、音声のダウンロードができないという仕様になっているということについては昨日書きました。
しょうがないので100歩譲って、最初のワンクリックはユーザにしてもらうとして、複数の音声をダウンロードすることはできるのか?というのが今日の話。
結論から言うと、可能ではありますが問題があります。

複数の音声のロードのサンプルは以下。
このコードだと実際に音声がロードできたか目で確認もできます。
<body>
<audio id="audio1" src="http://www.foo.com/1.mp3" controls></audio><br />
<audio id="audio2" src="http://www.foo.com/2.mp3" controls></audio><br />
<audio id="audio3" src="http://www.foo.com/3.mp3"" controls></audio><br />
<button id="pbutton">play</button>
<script type="text/javascript">
<!--
$(document).ready(function(){
    $('#pbutton').bind('click', function() {
        for (var i=1; i<4; i++) {
            $('#audio' + i).load();
        }
    });
});
//-->
</script>
</body>
上記コードを実行すれば分かりますが、複数の音声のロードは iPad などでもできるようです。
JavaScript で完全に裏側でもロードできますが、canplay イベントが常に発生するわけではないという bug があるせいで、すべての音声をきれいな方法で再生することはできません。
例えば、以下のコード。
音声がすべてロードされれ、canplay イベントが発生すれば、同時にいくつかの音声が聞こえるはずですが、
<body>
<button id="pbutton">play</button>
<script type="text/javascript">
<!--
$(document).ready(function(){
    var audioUrls = [ // データを入れておく ];

    $('#pbutton').bind('click', function() {
        for (var i=0; i<audioUrls.length; i++) {
            var audio = new Audio();
            audio.src = audioUrls[i];
            audio.load();
            $(audio).bind('canplay', i, function(event) {
                alert('canplay: ' + event.data);
                $(this).get(0).play();
            });
        }
    });
});
//-->
</script>
</body>
ブラウザではすべての音声が流れ出しますが、iPad などでは1つしか音が流れなかったり、全部流れたり、実行する度に結果が違うという羽目に。。。

解決策としては、複数の音声を1つにまとめる Audio Sprites という方法を取るしか無いです。
イメージ的には CSS Sprites と同じです。
Audio Sprites については以下の URL で。 http://remysharp.com/2010/12/23/audio-sprites/
posted by おちエン at 16:05| Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2013年04月19日

HTML5 Audio の tips【iOSの仕様】

HTML5 の Audio を使うという案件があって、これがなかなかはまったので備忘録として、色々書いておきます。
そもそも HTML5 の Audio はブラウザによって仕様がまちまちで、特に iPhone(iPad), Android の挙動にはかなり苦しめられました。

まず、一番重要なのはiOS ではユーザがクリックなどの動作を行わない限り、音声がダウンロードされないという点です。
たとえば、
$(document).ready(function(){
    var sound = new Audio();
    sound.autoplay = false;
    sound.src = "http://www.foo.com/hoge.mp3";
    sound.load();
    $(sound).bind('canplay', function(event) { event.target.play(); });
});
というコード、iPad では一生再生されません。
iPad などで再生させるためには、a タグ、img タグ、button タグなどの click イベントで駆動させるように書き換えないといけません。
$(document).ready(function(){
    var sound = new Audio();
    sound.autoplay = false;
    sound.src = "http://www.foo.com/hoge.mp3";
    $('#pbutton').bind('click', function() {
        sound.load();
        $(sound).bind('canplay', function(event) { event.target.play(); });
    });
});
当然ながら autoplay などはできないので iPhone/iPad 対応するのであれば、設計段階から念頭においておく必要があります。
ラベル:javascript HTML5
posted by おちエン at 22:19| Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年06月22日

JavaScript が Chrome で "Unexpected token ILLEGAL" というエラー

基本 Safari で開発してたので気がつかなかったのですが、Safari で正常に動く JavaScript が Chrome で動かすと、
Unexpected token ILLEGAL
というエラーで動かないことがわかりました。

やってることは、form を iframe 経由で送信して、エラーがあった場合は alert() でエラーを表示するだけのもの。
サーバ側は python + django で、python 側では、
error = self.__validate();
if len(error) != 0:
  data = {'error': "\n".join(error)};
としておいて、template では、
<script type="text/javascript">
<!--
    alert('{{error}}');
//-->
</script>
としているだけです。

google で検索したところ、JavaScript では改行はバックスラッシュを入れないといけないという。。。
error = self.__validate();
if len(error) != 0:
  data = {'error': "\\n".join(error)};
としてやれば正常に動きました。続きを読む
posted by おちエン at 03:13| Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年06月07日

iframeから親windowのdata()が利かない

iframe から親 window に保存しておいたデータを data() を使って取得しようとしましたが、全くうまくいきませんでした。

たとえば、親 window というかメインウィンドウで
$('body').data('hoge', '123');
などとしておいて、iframe で、
hoge = $('body', window.parent.document).data('hoge');
とやったのですが、hoge が undefined になってしまい全く値が取れませんでした。
しょうがないので、
$('body').attr('hoge', '123');
としておいて、
hoge = $('body', window.parent.document).attr('hoge');
とすれば望みどおりの動きはしてくれました。
ちなみに jQuery1.7.1 です。
ラベル:jquery javascript
posted by おちエン at 08:32| Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

2012年04月22日

JavaScript の parseInt で 08 と 09 が・・・

ユーザに西暦、月、日を入力してもらうフォームを作っていて、入力された値を JavaScript で
var $month = $form.find("input[name='month']");
var month = parseInt($month.val());
if (month > 12 || month < 1) {
   alert($month.attr('title') + "が不正です");
   return false;
}
という風に値のチェックをしていたのですが、08 や 09 と入力された場合、「不正です」のエラーが出るという問題が発生しました。
調べてみると、08 や 09 が入力された場合、parseInt() で 0 が戻っていました。

parseInt() を調べてみると、
  • 0から始まる場合は8進数
  • 0xから始まる場合は16進数
とみなすというのが仕様でした。
したがって、08 や 09 は 8進数とみなされますが、8進数は07までなので 8 や 9 は削除されて 0 とされたということなのでしょう。

対処方法は、
var month = parseInt($month.val(), 10);
という風に10進数であることを parseInt() で明示するということでした。

posted by おちエン at 19:44| Comment(0) | 開発 | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。