サーバーで付近の情報を通知するサービスのつくり方

こんにちは。カヤック技術部の杉山です。 主にクライアントワークでサービスを開発しています。

今回は、とある「歩いていると付近の情報が通知されるアプリ」に関して書きます。

「歩いていると付近の情報が通知されるアプリ」のサービス概要

今回は、サーバーアプリケーションの実装に関して解説してみます。

利用技術

  • Ruby on Rails
  • AWS

主な処理

  • ユーザーがアプリ内のMapをタップし、緯度経度とともに、画像、テキストを保存する
  • アプリがバックグラウンド状態の時に、近くに保存した情報があれば、通知を表示する
  • 他のユーザーが保存した情報に対して、コメントを行う

それぞれの内容

ユーザーがアプリ内のMapをタップし、緯度経度とともに、画像、テキストを保存する

サーバーはアプリから緯度経度を受け取とり、それをGeohashの値に変換し保存しています。

Geohashとは、地図を細かい矩形に分割し、一つの文字列として表すことの出来るアルゴリズムです。 Geohashの文字列が長ければ狭い領域、文字列が短ければ広い領域を表します。つまり、文字列が長いほど、精度が高くなります。 詳しくはこちら

Geohashの欠点は、緯度経度が矩形内に入っていることがわかっても、矩形内のどこなのかはわからないという点と、1文字減らすと、精度が一気に下がってしまうという点です。

文字数 南北 東西
6 609.08m 988.77m
7 152.27m 123.60m
8 19.03m 30.90m
9 4.76m 3.86m
10 0.59m 0.97m

Geohashの利点は、文字列検索さえできれば、どんなデータベースからでも利用できる点です。 Geohashの値を生成する、Ruby Gem もいくつか公開されています。

アプリがバックグラウンド状態の時に、近くに保存した情報があれば、通知を表示する

アプリがバックグラウンドの時に、基地局の切り替わりによる座標変更イベントを利用し、WebAPIがスマートフォンの緯度経度を受け取ります。

サーバーは、受け取った緯度経度を元に、Geohashの値を生成し、文字列検索することで、付近のデータを探します。 このとき、同一の矩形内かどうかだけではなく、付近の矩形を合わせた9ブロック分、OR検索する必要があります。これは、矩形内の端に実際の座標が存在した場合、近くにあっても検索から漏れてしまうためです。

select した結果があれば、APNSまたはGCMでリモート通知を行います。

他のユーザーが保存した情報に対して、コメントを行う

コメントは、ポーリングを利用した簡易的なチャットになっています。

さいごに

以上、中身はこんな処理になっていました。

このプロジェクトは、社内でぴょんさんとサービスを作ろうと考えていたところ、ちょうど関連したこのプロジェクトの話しを受け、一緒に開発を行いました。

こんな仕事が面白そうだと思った人はこちらから! 杉山のブログを読んだと書いてもらえると、筆が進みます。

関連記事

techblog.kayac.com

techblog.kayac.com

サーバーで動画生成するサービスのつくり方

はじめまして。カヤック技術部の杉山です。 主にクライアントワークでサービスを開発しています。

今回は、とある動画生成サイトに関して書きます。

動画生成サイトのサービス内容

ユーザーの撮影した写真と、サイト内でいくつかの選択肢を選ぶと、オリジナルの動画が生成できるサービスです。 画像にはロゴなどの合成が出来、映像作家によるアニメーションと、ミュージシャンによるBGMがつきます。

今回は、サーバーアプリケーションの実装に関して解説してみます。

利用技術

  • Ruby on Rails
  • AWS
  • FFmpeg
  • ImageMagick

主な処理

  • クライアント側から画像を複数枚アップロードし、サーバーへ保存
  • 動画、画像、BGMを合成
  • 動画生成のチューニング

それぞれの内容

クライアント側から画像を複数枚、サーバーへ保存

画像をサーバーへアップロードする前に、ロゴやテキストの合成をフロント側で行っています。

動画、画像、BGMを合成

Amazon SQSを使い、Webサーバーとは分かれた、Workerサーバーでリクエストを受け取り、FFmpegを利用することで、動画を生成しています。

動画を構成する素材として、 背景になる動画、ユーザーの画像、画像に対するフィルター処理、上に重ねる背景透過の動画、BGM があります。 これらを合成して1つの動画を生成するのですが、ブラウザで再生するため最終的にmp4(H.264+aac)にエンコードする必要があります。

動画生成のチューニング

ユーザーは写真をアップロードした後に、動画が出来上がるまでWebサイト上で待機しているため、動画生成時間は少しでも短くする必要があります。 動画処理はどれも時間がかかりますが、部分的に処理を行う、短い動画に対して処理を行う、最後に連結する、というのが高速化のポイントです。

今回行っている流れとしては、

  1. 動画にoverlayする前に、画像としてImageMagickなどで加工する(フィルター処理)
  2. FFmpeg で背景動画、画像、透過動画 を短い動画の状態でoverlay合成
  3. FFmpeg での処理時は、mp4への変換に再エンコードが不要で、連結が高速な、tsファイルとして出力する
  4. tsファイルをまとめて concat し、さらに aac 音声と結合する

さらに、

  • 事前に、素材となる動画・画像のクオリティー・動画の長さ・フレーム数・動画の分割を試行錯誤する
  • 素材の動画は、シンプルなエンコードの方がデコードが高速ではあるが、ファイルサイズが増える
  • 加工するファイルサイズがおおきいと、ディスクのIOがボトルネックになり、処理が遅くなる
  • 事前にtsにする、透過が使いたい場合は、avi(png)にする

これらを考慮していい感じのところを探りました。

さいごに

以上、中身はこんな処理になっていました。

生成時間はサーバー費用に直結するので、動画のクオリティー、演出方法、さらにはユーザー体験や企画にも影響する、なかなか骨の折れる仕事ですね。

こんな仕事が面白そうだと思った人はこちらから! 杉山のブログを読んだと書いてもらえると、筆が進みます。

関連記事

techblog.kayac.com

techblog.kayac.com