Androidでvideoタグによる動画再生を実装する際の落とし穴

HTML5ではvideoタグにより、動画を簡単に埋込める。スマートフォンサイトで動画を埋込む方法は検索すれば、役に立つ情報を掲載しているサイトがいくつも出てくるので、詳しいことはそれらを参照してもらうとして、結論から言うと以下のタグでiPhoneおよびAndroidに対応できるようだ。

参考ページ
http://sogitani.baigie.me/2011/07/smart-phone-movie/
http://today-only.net/html5-video/
(この2ページがとくに分かりやすくまとまっている)

<video src=”xxxxx.mp4″ preload=”none” poster=”xxxxx.jpg” onclick=”this.play();” controls >
<source src=”xxxxx.mp4″$gt;
</video>

iOSだと比較的すんなりと実装できるのだが、Androidでは一筋縄ではいかない数々の罠がしかけてあって、全てをクリアしなければならない。
私は落とし穴にハマりまくったので、確認すべきポイントを列挙しておく。

  • ◆動画形式、コーデック

iOSでも再生させることを考慮すると、必然的に動画形式はmp4になだろう。コーデックはh.264
動画変換はMacならこれが良いと思う(というか私はこれで変換したもので実装できた)http://jp.any-video-converter.com/any-video-converter-free-for-mac.php

  • ◆videoタグにonclick="this.play();"を入れる

入れないとAndroidの端末によっては再生してくれない模様。

これはハマる。Basic認証が原因かもしれないという発想がそもそも湧かないわけで。

  • ◆sourseタグにはtype属性は入れてはいけない

この落とし穴にハマって抜け出るのにどれだけかかったか。type属性があるとタップしても無反応になってしまうとか、全く意味不明。

追記
Basic認証をかけている状態だと、iOSではposter属性で指定した画像が表示されないようだ。
どうやら動画再生にBasic認証は鬼門のようだ。

labelタグを設定した領域が、iPhoneでタップしても反応しない件

フォームでは、ユーザーがクリック(タップ)しやすいように、labelタグを使用してinput要素を選択しやすくします。

<label><input type="radio" name="hogehoge" />これ</label>
<label><input type="radio" name="hogehoge" />それ</label>
<label><input type="radio" name="hogehoge" />あれ</label>

      • -



とくにラジオボタンチェックボックスでは重要。labelタグをつけてないと、ラジオボタンの丸い部分を狙ってクリックしなければいけないため、結構なストレスなのだ。特にアンケート等で入力項目の多いフォームだと、イライラしてページを閉じてしまうこともあるかもしれない。(実際、私はよくやる)
labelタグをつけることで、そこに含まれる要素全体がクリック領域になってinputタグにフォーカスできる。ユーザビリティの向上として重要かつ常套の手段。

ところが、iPhoneおよびiPadではlabelでかこった部分をタップしても反応しないという問題がある。この件は以下のようにCSSで対処できる。

label {
cursor:pointer;
}

ちなみに、label要素にonclick="" 属性を追記しても同様の結果が得られるようだ。
要するに、label要素がタップ(クリック)するための要素として認識されてないということらしい。

謎のセッション切れは画像の読み込み失敗によるものかもしれない

あるサイトでなぜかセッションが切れてしまうという報告を受けた。問題切り分けの結果、特定のimgタグの有無でセッション切れ現象が発生するのだという。html要素によってセッションが影響を受けるなんてそんなばかな話があるかと思ったのだが・・・

問題のimgタグは以下のようなもの。
<img src="#" id="hogehoge" />
imgのsrc要素を、JavaScriptで動的に制御して画像を出し分けようとしていた。

しかし、ページレンダリング時に'#'というパスの画像を読みに行くと、当然エラーを受け取る。これによってセッションが断絶されてしまうという現象なのであった。
対処法としては、JavaScriptでsrc属性のみを書き換えるのではなく、imgタグそのものをJavaScriptで書き込んでやる(つまりhtmlにはこのタグは記述しない)ことで解決する。

twitter投稿ボタンではBasic認証のかかっているページURLは無視される

twitter投稿用のツイートボタンを作っていたが、ツイート内容にデフォルトで挿入させたいURLがどうしても入ってくれない。

<a href="https://twitter.com/intent/tweet?original_referer=「ページURL」&text=「ツイート文言」&url=「付記したいURL」">ツイート</a>

こんな感じ。括弧内はもちろんURLエンコードする。
twitter投稿画面を開くと、ツイート文言が入った状態なのだがURLが入ってくれない。
URLエンコードがどこか間違っているんだろうかといろいろやってみたが、URLがつかない。

原因は入れようとしたURLの当該ページにBasic認証がかかっていたから。

twitter投稿ではBasic認証のかかったページURLは無視される。

こういうくだらないことで時間を取られることがないよう、同じ症状の人がこの記事にたどり着きますように。

AndroidでjQueryが動かないなぁと思ったときに確認するべきかもしれない恐ろしい罠

jQuery を使っているスマートフォンサイトで、AndroidだけJavaScriptが機能しない事態が発生し原因の究明に相当の時間を要したのでメモ。

以下のようなJavaScriptコードがあるとAndroidで死亡するようです。(当該要素のclass属性に任意の文字列を指定するコード)

$("#hoge").attr({class:"hoge"});

問題のポイントは、attr()の引数に、添字にクオテーションで囲まないclassを含んだオブジェクトを指定すること。これでAndroidが動きません。
class以外の属性や、classをクオテーションで囲えば問題ないようです。

この箇所が実行されなくても、コード内にあるだけでダメです。たとえばこんな感じ・・・

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function(){
	$("#hoge1").bind("click",function(e){
		e.preventDefault();
		alert("ほげほげ");
	});
});
function hogehoge(){
	$("#hoge2").attr({class:"moge"});
}
</script>
</head>
<body>
<div class="wrap">
	<a href="#" id="hoge1">ほげ1</a>
	<p id="hoge2">ほげ2</p>
</body>
</html>


私の実行環境は、Android2.2.1、jQuery 1.7.2 です。

スマートフォンでopacityをtransitionさせるとちらつく件

jQueryでアニメーションさせるより、CSS3のtransitionを使った方がスムーズなのでできるだけそうしているが、スマートフォンではopacityをtransitionでCSSアニメーションさせるとちらちく。

iPhoneでは、アニメーションを始める瞬間に、一瞬opacity:0の状態になっているように見える。

htaccessを設置すると500 Internet Server Errorになるときに確認すべきこと

サイトのリニューアルしたのに伴い、検索結果に上がってしまう旧来のページをリダイレクトかけた。
が、恐怖の大王500が降臨して小一時間格闘した。いろいろ検索した結果確認すべきポイントがあったのでメモ。

しかしながら、今回の結論は単純なスペルミスだったorz
コピペしたからそれは大丈夫だと思っていたのに。。。。

スペルミスは、htaccess解説の老舗ページ。ここの中下段えんじ色の部分です。
http://www.shtml.jp/htaccess/redirect.html

誤:Reidrect permanent
正:Redirect permanent

コピペですまそうとした自分が悪いのだけどね。お気をつけ下さい。