「Mobile」カテゴリーアーカイブ

HTTP Live Streaming

ちょっと調べる機会あったので、メモ。
ライブ配信ではなく、動画のオンデマンド配信についてが中心になります。

HLS(HTTP Live Streaming)はサーバの特別な設定なしでストリーミングが出来るようです。
ライブ配信する時はリアルタイムで変換する必要があるのでFFMPEGと組み合わせて使用します。
クライアント側でやりくりしている部分があるためAppleのデバイス限定となります。

Appleの公式ドキュメントや参考にしたサイトは下記。
https://developer.apple.com/jp/devcenter/ios/library/documentation/StreamingMediaGuide.pdf (PDF)
http://venture-blog.blogspot.jp/2012/05/http-live-streaming.html

オンデマンドで動画を配信する際もライブ配信も、MPEGのTSフォーマットで10秒区切りとか細切れでファイルを用意して、m3u8 のプレイリストで配信するのは共通です。

1
2
3
4
5
6
7
8
9
10
11
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10, no desc
fileSequence0.ts
#EXTINF:10, no desc
fileSequence1.ts
#EXTINF:10, no desc
fileSequence2.ts
...
#EXT-X-ENDLIST

こんな感じでTSファイルの場所をリストにして指定していきます。
.htaccess や Apache のMIME Type設定も忘れずに。

1
2
AddType application/x-mpegURL .m3u8
AddType video/MP2T .ts

あとは、配信用のページを用意すればひとまず配信可能です。

1
<a href="playlist.m3u8"><video src="playlist.m3u8" autoplay="true" controls="false" width="320" height="180"></video></a>

ライブ配信の場合はリアルタイムでTSファイルを生成しつつ、こちらのプレイリストを更新します。
iPhoneやiPadから見るとこのm3u8ファイルに何度もリクエストがきます。
m3u8ファイル最後の #EXT-X-ENDLIST は配信が終わるまでは出力しないことになります。

で、ここからが今回調べた内容です。前置き長かったですが…
要求としては、なるべく動画を見てもらいたいので早送りできない方法はないものか?というものでした。

通常のオンデマンド配信だと動画のスキップ(早送り)が出来るのですが、擬似的にライブ配信ということにすれば早送りはしにくくなるのではないかと。
という訳で、PHPでサーバ側で動的にプレイリストを出力するというのを試してみました。
クライアント側からリクエストが何度も来るので、セッションで管理して最初のアクセスからの時間経過でプレイリストを更新するようにしました。

ただ、拡張子が .php のままだと、iPhone/iPad で見た時に再生してくれないようです。
なので、.m3u8 で PHP を実行するように .htaccess なり mod_rewrite で設定する必要があります。

今回調べてて思ったより<video>タグは使えるレベルになってる気がしました。
相変わらずデバイスやブラウザ間の調整は必要ですが、あんまり変わったことしなければ何とかなりそうですね。

擬似ライブ配信サンプル ※iPhone / iPad から見てください

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
$video = array(
    'fileSequence0.ts',
    'fileSequence1.ts',
    'fileSequence2.ts',
    'fileSequence3.ts',
    'fileSequence4.ts',
);
$num = count($video);
$maxLength = 50; // sec, 動画の長さ
$length = 10; // sec, 分割動画の長さ
$now = time();

session_name('videoCount');
session_cache_limiter('nocache');
session_cache_expire(60);
session_start();
session_regenerate_id();

if (isset($_SESSION['count'])) {
    if ($now - $_SESSION['count'] > $maxLength) {
        $_SESSION['count'] = $now - 1;
    }
} else {
    $_SESSION['count'] = $now - 1;
}

$page = ceil(($now - $_SESSION['count']) / $length);
if ($page > $num) {
    $page = $num;
}

header("Content-type: application/x-mpegURL");
echo '#EXTM3U';
echo "n";
echo '#EXT-X-TARGETDURATION:10';
echo "n";
echo '#EXT-X-MEDIA-SEQUENCE:0';
echo "n";
echo '#EXT-X-ALLOW-CACHE:NO';
echo "n";

for ($i = 0; $i < $page; $i++) {
    echo '#EXTINF:10, no desc';
    echo "n";
    echo $video[$i];
    echo "n";
}
if ($page == $num) {
    echo '#EXT-X-ENDLIST';
}

iPadで加速度センサー / jQueryゼロから

iPad/iPhoneでiOS4.2以降はブラウザでも加速度センサーの値がとれるのでちょっとテストした時のをまとめます。
javascriptではdevicemotionイベントで取れます。

1
2
3
4
5
6
7
8
$(window).bind('devicemotion', function(e){
    // 加速度
    var a = e.originalEvent.acceleration;
    // 重力加速度
    var g = e.originalEvent.accelerationIncludingGravity;
    // 回転加速度
    var r = e.originalEvent.rotationRate;
}

重力加速度で画面を傾けるとコリント的な動きさせる場合は、下記の感じ。

1
2
3
4
5
6
$(window).bind('devicemotion', function(e){
    // left, top が対象の左上の x, y 座標
    var g = e.originalEvent.accelerationIncludingGravity;
    left += g.x;
    top -= g.y;
}

これだけだとよくあるので、画面を傾けると回転しちゃう場合も考慮に入れてみます。
※画面ロックしなかった時にぐるっと回っちゃうので…
画面の回転はwindow.orientationから0, 90, 180, -90で取れます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(window).bind('devicemotion', function(e){
    var g = e.originalEvent.accelerationIncludingGravity;
    var dx, dy = 0;
    if (window.orientation == 0) {
        dx = g.x;
        dy = -g.y;
    } else if (window.orientation == 90) {
        dx = -g.y;
        dy = -g.x;
    } else if (window.orientation == 180) {
        dx = -g.x;
        dy = g.y;
    } else {
        dx = g.y;
        dy = g.x;
    }
    left += dx;
    top += dy;
}

あとは画面からはみ出ないようにとかする場合は orientationchange イベントで調整できます。
例えば canvas を画面いっぱいにした場合は、canvasサイズも変更しつつ画面の右下の最大値を調整します。

1
2
3
4
5
6
7
$(window).bind('orientationchange', function(e){
// size は描画するオブジェクトの大きさ
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    maxX = canvas.width - size;
    maxY = canvas.height - size;
});

まあ、回転に対応するケースはなさそうだけど…

サンプル ※iPadでみてね

iPadでスワイプ / jQueryゼロから

ちょっと特殊だけど、iPadでスワイプ処理を自分で書くことがあったので。
たぶんGalaxyでもあんまり変わらないはず。

タッチイベントは touchstart, touchend, touchmove で拾えます。
touchmove の際に event.touches に座標が入ってます。
配列なのは5つまでデータが入っているから。
今回は、ただのスワイプなので touches[0] だけ使います。

とりあえず座標を拾ってみます。

1
2
3
// touchmove で座標を拾う
X = event.touches[0].pageX;
Y = event.touches[0].pageY;

サンプル ※iPadで見てください

touches には pageX, pageY, screenX, screenY, clientX, clientY があり、ページやスクリーンの相対座標として取得できます。
画面を固定する場合は特に変わりはないですが、スクロールする場合は使い分けが必要です。
※pageX, pageYはスクロールする場合は指に追従してページも移動するので

とりあえず、touchstart と touchend の時の座標の差でスワイプを判定してみます。
X方向に100px動いたらスワイプします。※値は適当です

1
2
3
4
5
6
// touchendで判定
if (startX - endX > 100) {
// prev
} else if (endX - startX > 100) {
// next
}

サンプル

これでもスワイプは出来るのですが、いくつか問題があるのでもう少し調整してみます。
・縦(斜め)にスワイプしても横移動が100px以上ならスワイプするのをやめる
→ touchstart と touchend の確度を小さくする(2点を結ぶ直線の傾きが0.5以下としてみる)
・速度が遅くてもスワイプするのをやめる
→ 0.7秒以内のみスワイプとする
・iPadだと画面がズレる(指に追従する)のをやめる
→ よく使われている方法を参考に preventDefault でブラウザの挙動を無視する

サンプル

jQuery Mobile / とりあえずページ作ってみる

あれこれ見つつまずは基本的なところからやってみる。
チュートリアルとしてこちら参考にしつつ。
jQuery Mobile [基礎編]

詳しくはリファレンスを日本語化されているこちらで。
jQuery Mobile リファレンス

あとは、こちらにリンク集がよくまとまってます。
jQuery Mobile が必須スキルになる!と思うのでこれから勉強する際に参考になる記事まとめ | バシャログ。

jQuery Mobileって名前がついてるけど、どちらかと言うとHTMLの記述メインかな。まだ深くはさわってないけど。

まずは、その前にHTML5で基本的なところを。
あと jQuery や jQuery Mobile を読み込みます。
※ 下記は jQuery のCDN使ってます

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>jQuery Mobile</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
    </head>
    <body>
        <!-- ここになんか書きます -->
    </body>
</html>

jQuery Mobie では、スマホでよく使う機能がテンプレの様にまとめられてます。
ヘッダ、フッタ、メインのコンテンツ部分などは以下の感じ。
※<body> タグ内に書きます。

1
2
3
4
5
6
7
8
9
10
11
<div data-role="page">
    <div data-role="header">
        <h1>ヘッダ</h1>
    </div>
    <div data-role="content">
        コンテンツ
    </div>
    <div data-role="footer">
        フッタ
    </div>
</div>

基本は<div>タグで data-role を指定するだけです。
<div class=”header”>みたいなマークアップとおんなじよね。
また、一画面は <div data-role=”page”> でくくる必要があります。
※ひとつのファイルに複数画面書けるので

これだけでもそれっぽいデザインになりますが、ボタンを追加してみます。
今回はボタン風のリンクを使用して、ダイアログを開きます。

1
<a href="dialog.html" data-role="button" data-rel="dialog" data-transition="pop">OPEN</a>

data-role=”button” でボタンのようなスタイルを指定、data-rel=”dialog” でJavaScript の alert 的なダイアログになります。data-transition=”pop” でアニメーションの指定をポップアップにします。
※アニメーションは他にも slide などイロイロ指定できます

ダイアログも同様に別ファイルで用意してみます。
※同一のファイルに設定することも出来ます

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title> Dialog | jQuery Mobile</title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
        <script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
    </head>
    <body>
        <div data-role="page" id="dialog">
            <div data-role="header">
                <h1>Dialog</h1>
            </div>
            <div data-role="content">
                <p>Dialog</p>
                <a href="index.html" data-role="button" data-rel="back">Back</a>
            </div>
        </div>
    </body>
</html>

data-rel=”back” を指定して、戻るボタンもつくっときます。

だいたいこんな感じで、基本的なページは作れます。普通のページなら、指定されたタグを書いてくだけ。

サンプル (ダイアログは別ファイル)
※スマホで見るか、Chrome or Safari で見て下さい

デモ (一ファイルに複数ページで記述)

Google Analytics Mobile 設定してみる

ガラケーでGoogleAnalytics設置の必要が出てきたので試してみる。
まずは普通にGoogleAnalyticsでプロファイルを作成する。んで、コードを生成するときに「Advanced」から「A site built for a mobile phone」を選択。

開発言語を選ぶと、画面右にコードが出てくるのでコピペして貼り付けます。自分の場合はPHPのコードを生成して、すべてのページから読まれている common.php に貼りつけました。WordPressのサイトなら header.php とかのテンプレかな。

もうひとつのコードはなるべく画面下の方に置くようにってことなので、こっちはテンプレの </body> タグの直前に貼り付けました。この辺はPCサイトに js 貼るのと同じくコンテンツの表示優先って事なんかね。

あとは ga.php をダウンロードして、指定のサイトのトップにアップしとけばOKかな。これでしばらく計測してみる。