ツイキャスの新しい API をつかってみた（ライブ配信サービス戦国時代2016）

おつかれさまです。この記事は [第2のドワンゴ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dwango2) の2日目です。今日は [ツイキャス](http://twitcasting.tv/) の OAuth を利用した新しい API を使ってみたいと思います。
[![image](https://qiita-image-store.s3.amazonaws.com/0/27471/6166ffa2-7516-efff-0181-ac86f45fd72e.png)](http://twitcasting.tv/)

# ライブ配信サービス戦国時代
ツイキャスの新しい API を使ってみる前に、使ってみたくなる話をします。

先日、ある配信者が「世はまさにライブ配信サービス戦国時代」と言っていたのが印象に残っています。たしかに、ただでさえ [ニコ生](http://live.nicovideo.jp/) で配信するかツイキャスで配信するか、はたまた [YouTube Live](https://www.youtube.com/live) か [Twitch](https://www.twitch.tv/) か [Periscope](https://www.periscope.tv/) か [takusuta](https://takusuta.com/) か、あるいは [SHOWROOM](https://www.showroom-live.com/) か [アフリカ TV](http://www.afreecatv.jp/) か [ふわっち](https://whowatch.tv/) かみたいなところがあった（既に多い）のに、 2016 年も多くの新サービスがリリースされたり新たにライブ配信機能をリリースするプラットフォームが次々出てきたりと、本当に面白い年でしたよね。そんな今年を振り返りながらサービスの開始や終了を守備範囲内で表にまとめたら面白かったので載せます。

## 2016年に開始したサービス
まずは2016年に開始されたライブ配信サービスあるいはライブ配信機能についての表です。一般ユーザーが配信できない [AbemaTV](https://abema.tv/) や [生テレ](https://namatv.jp/) は意図的に外しています。表におかしなところがあったら教えてください。

| いつ | 出来事 | 運営 | 参考 |
| --- | --- | --- | --- |
| 1月 | AmebaFRESH! (現 FRESH! by AbemaTV) リリース | サイバーエージェント | [「Ameba」が映像配信プラットフォーム「AmebaFRESH!」を提供開始](https://www.cyberagent.co.jp/newsinfo/press/detail/id=11544) |
| 1月 | Facebook Live 一般開放 | Facebook | [ライブ動画をより多くの方へ](http://ja.newsroom.fb.com/news/2016/02/livevideo_rollout/) |
| 3月 | VOX リリース | エクシング | [あなたとお話ししたい人が見つかるアプリ 音声コミュニケーションアプリ「VOX(ヴォックス)」配信開始！](http://www.xing.co.jp/news/archives/6068) |
| 3月 | BIGO LIVE リリース | Bigo | http://www.bigo.sg/products.html アジア各地で爆発している |
| 4月 | Bocci リリース| FACTORS | [仮想マスクで生配信をデコれる新感覚ライブチャット　無料iPhoneアプリがリリース](https://www.atpress.ne.jp/news/100340) |
| 4〜6月？ | OPENREC.tv が PC 配信機能をリリース | CyberZ | https://www.openrec.tv/ ｜資料が見つからない。自由に PC 配信できるようになったのは今年だったはず |
| 6月 | live.ly リリース | musical.ly | [Musical.ly launches live.ly for live streaming](https://techcrunch.com/2016/05/27/musical-ly-launches-live-ly-for-livestreaming/) |
| 7月 | メイキスリリース | シャープ | https://makexx.net/ ｜リリース資料がない。シャープのメイク配信特化型のサービス。 [AWS プロダクト](https://cloudpack.jp/casestudy/124.html) |
| 8月 | ちあスト（CHEERZ STREAMING）リリース | fogg | http://pdf.fogg.jp/20160804.pdf ｜ アイドル応援アプリ CHEERZ の配信機能 |
| 8月 | LINE LIVE 一般開放 | LINE | [【LINE LIVE】ライブ動画配信プラットフォーム「LINE LIVE」 近日アップデートを行い一般ユーザーも自由にライブ配信可能に](https://linecorp.com/ja/pr/news/ja/2016/1460) |
| 9月 | Stager Live リリース | Newestage | [いつでもどこでも自分の「瞬間」をシェアできる iOS無料ライブ動画配信アプリ「Stager Live」をリリース](http://www.asahi.com/and_M/information/pressrelease/CATP2016112126.html) |
| 9月 | Live.me 日本上陸 | キングソフト | [噂のライブ配信アプリ『Live.me』が緊急上陸！ 日常をシェアする、という新しい動画配信スタイルで NEXT SNSを目指す](https://www.kingsoft.jp/app/20160913.html) |
| 9月 | ドキドキ Live リリース | M&E Time Entertainment | https://twitter.com/dokidoki_live ｜資料がない。 AppStore には9月から並んでいた模様 |
| 10月 | MixChannel LIVE リリース | Donuts | [550万DLの動画コミュニティMixChannel、カラオケ機能を含むライブ配信をリリース！初回はファン数35万人超の「まこみな」が登場！](http://www.donuts.ne.jp/news/2016/1006-mixchannel-release-livechat/) |
| 10月 | FAN LIVE リリース | A | https://fanlive.tv/ ｜資料が見つからない。ふわっちなど jig.jp との関係が気になる、謎めきに満ちた A Inc. の運営 |
| 11月 | Instagram Stories のライブ動画機能リリース | Facebook | [インスタグラム ストーリーズにライブ動画機能を追加、ダイレクト機能でストーリーズ投稿のシェアがより自由に](http://ja.newsroom.fb.com/news/2016/11/instagram_live_direct/) |

Ameba や Facebook に LINE など大手プラットフォームがバンバンライブ配信機能をリリースするという異常事態にワクワクするような年でした。まとめてみるとこんなにあったんだなと驚きます。ちなみに YouTube Live は6月に [モバイルアプリの配信機能を実装予告](https://youtube-creators.googleblog.com/2016/06/well-do-it-livea-new-chapter-in.html) していましたが、まだリリースはされていないようです。

本当は、中国がこの分野での盛り上がりモノスゴイという噂なので気になるところですが、守備範囲外でした。

## 2016年に終了したサービス
やはり戦国時代なのか、2016年に終了等が発表されたサービスもけっこうありました。

| いつ | 出来事 | 運営 | 参考 |
| --- | --- | --- | --- |
|1〜2月| Ustream Asia 撤退と IBM の Ustream 買収 | Ustream | 終了ではない｜ [「Ustream」運営移管についてのお知らせ](http://www.ustream-asia.tv/news_20151201.html) ｜ [2016-01-25 IBM、Ustreamを買収](https://www-03.ibm.com/press/jp/ja/pressrelease/48861.wss)|
|5月| HiClub 終了 | バイドゥ | https://web.archive.org/web/20160425100022/http://www.hiclub.jp/news/newsDetail/68 |
|6月| twitcam 終了 | twitcam | https://twitter.com/twitcam/status/740186512789245952 |
|7月| キャスタウン終了 | ソニー | きれいになくなっている。スクショだけあった。 <img src="https://qiita-image-store.s3.amazonaws.com/0/27471/494fc2a8-6a63-f68c-f2bf-9c1c021aac11.png" width="150"> |
|8月| ラジ生終了| サイバーエージェント | [【重要】サービス終了のお知らせ](https://radio-nama.amebaownd.com/posts/1051088) |
|9月| ゴルスタ（ゴルキャス）終了 | スプリックス | https://sprix.jp/pdf/160905.pdf |
|10月| Meerkat 終了| Meerkat | https://twitter.com/benrbn/status/781914958401384450 |

あの Ustream がという話題だったり、長く運営されてきた twitcam が終了したりもありました。インターネットの温度が一番高まったのはゴルスタでしょうか。Meerkat は Twitter と Periscope の関係でツライ思い出がありそうですよね。 Meerkat チームがいま運営している [Houseparty](http://joinhouse.party/) というグループビデオ通話アプリは調子が良いらしいです。

## API が用意されているサービス
そんなアツいライブ配信サービス界隈ですから、何か面白いことができそうだしインターネットに携わるエンジニアならちょっとさわってみたいと思いますよね。ニコ生レベルの人気サービスだと良くハックされていて便利な野良ツールが開発されていたりもしますが、そっちの方向でさわっていくのは敷居が高いので、仕様の公開されている API があると嬉しいです。

そうやって見ていくと意外と整備されているサービスは少なくて、これくらいなものでした（おそらく）。

| サービス | API ドキュメント |
| --- | --- |
| Ustream | http://developers.ustream.tv/ ｜Contact が必要で手軽にさわれる感じではないかも |
| YouTube Live | https://developers.google.com/youtube/v3/live/getting-started |
| Twitch | https://dev.twitch.tv/docs |
| Facebook Live | https://developers.facebook.com/docs/videos/live-video |
| ツイキャス | http://twitcasting.tv/indexapi.php |

さて、英語が読めないのと Facebook はちょっと苦手なのとで、ツイキャスの API を使ってみたくなりますよね。

# ツイキャスの新しい API
以前からツイキャスでは API が用意されていたものの、精力的にメンテされているようには見えない状態だったのですが、最近「新しいAPI（ベータ）」の提供が開始されたようです。 [新しいAPI（ベータ） - ツイキャス](http://twitcasting.tv/indexapiv2.php) によると、 Twitter などと同様に OAuth で利用するものですね。

![image](https://qiita-image-store.s3.amazonaws.com/0/27471/94c5a99d-4ada-1792-e874-91364f35b78e.png)

ベータ版のためか、まだデータの write はなく read にしか対応していないようですが、 API の種類を書き出してみると、

- ユーザー情報の取得
- 配信情報の取得
- コメントの取得
- ユーザーの検索
- 配信の検索
- カテゴリ一覧の取得

といった機能があったので、現状でもそれなりの視聴アプリなら十分作ることができそうです。

## アクセストークンを取得して API にアクセスするまでのサンプル
[API ドキュメント](http://apiv2-doc.twitcasting.tv/) に OAuth のアクセストークン取得手順が書かれているので、それを見ながらサンプルを作ってみました。ちなみにこのドキュメントは見た感じから [Slate](https://github.com/lord/slate) で作られているようですね。

### アプリケーションの登録
まずは https://twitcasting.tv/developer.php の Create New App からアプリケーションを登録します。 localhost にサーバーを立てて試すつもりなので、 Callback URL はこのように入力しました。

![image](https://qiita-image-store.s3.amazonaws.com/0/27471/00278d5c-d378-a694-e4cb-9c317d217990.png)

Create すると一覧に戻るので、作成したアプリケーションの詳細に進み、 ClientID と ClientSecret を確認します。

![image](https://qiita-image-store.s3.amazonaws.com/0/27471/03a0f364-bf0b-de03-198e-edb33d81863d.png)

### ユーザーのアクセストークンを取得する
アプリケーションを登録して必要な情報が揃ったので、以下の処理をする簡単なサーバーを今回は PHP で書いてみます。

1. ユーザーを認可画面に飛ばす
1. コールバックを受け止めてアクセストークンを取得する API を叩く
1. アクセストークンを画面に表示する

CSRF 対策トークンは必須ではありませんが、サンプルでもイメージつかむために入れておきました。

```php:sample.php
<?php
$clientId = 'ClientIDをここに入れる';
$clientSecret = 'ClientSecretをここに入れる';
$callbackUrl = 'CallbackURLをここに入れる';
$state = 'ランダムな文字列(CSRFトークン)を入れる';

session_start();

// 最初に開いたとき、セッションにCSRF対策トークンを入れてツイキャスの認可画面に飛ばす
if (!isset($_GET['state'])) {
    $_SESSION['state'] = $state;
    $authorizationUrl = "https://apiv2.twitcasting.tv/oauth2/authorize?client_id=${clientId}&response_type=code&state=${state}";
    header("Location: ${authorizationUrl}");
    exit;
}

// コールバックで戻ってきたとき、CSRF対策としてstateを検証する
if ($_SESSION['state'] != $_GET['state']) {
    exit;
}

// アクセストークン取得APIで必要なパラメーター
$params = array(
    'code' => $_GET['code'], // コールバックで受け取ったcodeが必要
    'grant_type' => 'authorization_code',
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'redirect_uri' => $callbackUrl,
);

$data = http_build_query($params);

$context = stream_context_create(array(
    'http' => array(
        'method' => 'POST',
        'content' => $data,
        'header' => 'Content-Type: application/x-www-form-urlencoded',
    )   
));

$result = file_get_contents('https://apiv2.twitcasting.tv/oauth2/access_token', false, $context);

// サンプルなのでアクセストークンを画面に表示させてしまう
var_dump($result);
```

サーバーを立ち上げて、

```console
$ php -S localhost:8000 sample.php
```

ブラウザで開きます。

```console
$ open http://localhost:8000
```

リダイレクトされて許可を求められるので、許可します。現在は読み取りの権限しかないようですね。

![image](https://qiita-image-store.s3.amazonaws.com/0/27471/58375e8c-f1fa-49d2-d8c4-7badb93f9414.png)

許可ボタンを押すとコールバックが発動して、アクセストークン取得 API のレスポンス（の `var_dump` ）が画面に表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/27471/083dab56-836e-8c59-8019-40f4fb08a62e.png)

この `access_token` を使って、 API から情報を取得してみましょう。

### ユーザーのアクセストークンを使用して情報を取得する
curl で必要なヘッダーをつけ、[ `/verify_credentials` API](http://apiv2-doc.twitcasting.tv/#verify-credentials) でアクセストークンを検証してみます。

```console
$ ACCESS_TOKEN='ここにアクセストークンを入れる'
$ curl -X GET "https://apiv2.twitcasting.tv/verify_credentials" \
> -H "Accept: application/json" -H "X-Api-Version: 2.0" \
> -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq
```
```json
{
  "user": {
    "id": "241113884",
    "screen_id": "yonex",
    "name": "すごい名前",
    "image": "http://202-234-23-159.moi.st/image3s/pbs.twimg.com/profile_images/674914267317932032/74OEtNRy_normal.jpg",
    "profile": "すごいプロフィール",
    "last_movie_id": "233463429",
    "is_live": false,
    "created": 1390998881
  }
}
```

よさそうです。

ついでに、ここで返ってきた `"last_movie_id": "233463429"` を使って [`/movies/:movie_id` API](http://apiv2-doc.twitcasting.tv/#movie-info) から配信情報も引いてみます。

```console
$ curl -X GET "https://apiv2.twitcasting.tv/movies/233463429" \
> -H "Accept: application/json" -H "X-Api-Version: 2.0" \
> -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq
```
```json
{
  "movie": {
    "id": "233463429",
    "user_id": "241113884",
    "title": "Live #233463429",
    "link": "http://twitcasting.tv/yonex/movie/233463429",
    "is_live": false,
    "is_recorded": false,
    "comment_count": 2,
    "large_thumbnail": "http://202-230-12-92.twitcasting.tv/image3/image.twitcasting.tv/image55_1/85/5e/0dea5e85-1.jpg",
    "small_thumbnail": "http://202-230-12-93.twitcasting.tv/image3/image.twitcasting.tv/image55_1/85/5e/0dea5e85-1-s.jpg",
    "country": "jp",
    "duration": 1801,
    "created": 1452928534,
    "is_collabo": false,
    "is_protected": false,
    "max_view_count": 29,
    "current_view_count": 0,
    "total_view_count": 74,
    "hls_url": null
  },
  "broadcaster": {
    "id": "241113884",
    "screen_id": "yonex",
    "name": "すごい名前",
    "image": "http://202-234-23-159.moi.st/image3s/pbs.twimg.com/profile_images/674914267317932032/74OEtNRy_normal.jpg",
    "profile": "すごいプロフィール",
    "last_movie_id": "233463429",
    "is_live": false,
    "created": 1390998881
  },
  "tags": [
    "ゲーム",
    "雑談",
    "初見さん歓迎",
    "コメント歓迎"
  ]
}
```

よさそうです！

## リッチなアプリケーションを作る
新しい API と外部プレーヤーを使って、コメントをコンパクトに表示しながら視聴できるウェブアプリを試作しています。 API が返す HLS の情報を使って HTML や JS で player を作ってみるのも面白いかもしれません。やんごとなき事情によってチラ見せしかできないのですが、雰囲気だけ紹介します。

Sign in with TwitCasting ボタンの画像が http://twitcasting.tv/indexapiv2.php の案内にあるので使ってみると良い感じになりました。
![image.png (14.4 kB)](https://img.esa.io/uploads/production/attachments/1965/2016/12/02/6951/86436427-aa3c-41fc-b205-405a9e7800c5.png)

[`/categories` API](http://apiv2-doc.twitcasting.tv/#categories) を使ってカテゴリ選択できるようにしたり、 [配信検索 API `/search/lives`](http://apiv2-doc.twitcasting.tv/#search-live-movies) がサムネイルの URL も返すのでそれも一覧で表示したりできます。
![image.png (58.2 kB)](https://img.esa.io/uploads/production/attachments/1965/2016/12/02/6951/653fa9ee-ba40-4b28-9501-3a75d65f16ff.png)

コメントの書き込みがまだできないので、早く実装されたいです。
![image.png (177.0 kB)](https://img.esa.io/uploads/production/attachments/1965/2016/12/02/6951/0c733afd-69ed-4321-9083-c689bbef3180.png)

### Ruby 開発者向け omniauth-twitcasting
https://github.com/twitcasting/omniauth-twitcasting

ツイキャス OAuth 用に作られた omniauth モジュールが GitHub の twitcasting 本家 organization で公開されていました。 Rails などを使うなら超高速に開発を始められそうですね。

# おわり
ツイキャスの新しい API をつかってみました。ベータ版ということでまだ機能は多くないのですが、いまがホットなライブ配信サービスの公式 API ということでテンションが上がります。今後機能が増えてくればサードパーティアプリなどに活用の幅が広がっていく可能性を感じました。戦国時代をエンジョイしていきましょう。