Nintendo Switchから投稿された動画に自分を探す(1/4)

## はじめに

ご存知のとおり、Nintendo Switchにはプレイ動画を保存し、Twitterに投稿する機能がありますね。以下は自分が投稿したSplatoon2のプレイ動画です。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">持ちアサリ数を全く把握していない。 <a href="https://twitter.com/hashtag/Splatoon2?src=hash&amp;ref_src=twsrc%5Etfw">#Splatoon2</a> <a href="https://twitter.com/hashtag/%E3%82%B9%E3%83%97%E3%83%A9%E3%83%88%E3%82%A5%E3%83%BC%E3%83%B32?src=hash&amp;ref_src=twsrc%5Etfw">#スプラトゥーン2</a> <a href="https://twitter.com/hashtag/NintendoSwitch?src=hash&amp;ref_src=twsrc%5Etfw">#NintendoSwitch</a> <a href="https://t.co/xhyzYCBLt7">pic.twitter.com/xhyzYCBLt7</a></p>&mdash; 大空を自由に舞う小鳥❄☃ (@floatnflow) <a href="https://twitter.com/floatnflow/status/1052227141805297664?ref_src=twsrc%5Etfw">2018年10月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

さて、もし自分と一緒にプレイした人が動画を投稿していたら、他人の視点で自分の動きが見れていいだろうな、と思ったのでなんとか検索できないものか考えてみました。

結論から言うと、「運がよければ自分がやられたときの動画なら見つかるかもね」、くらいの結果となりました。


## おおまかなアイディア

まず、投稿されたTweetや動画になんらかの付加情報(参加プレイヤー名など)が埋め込まれていれば話は簡単なのですが、どうせなんも埋め込まれてないであろうことが想像に難くないため、このセンはたいした検証もせず却下。

直接動画からプレイヤー名を抽出するしかないなと。(なお、プレイヤー全員の名前が固定位置に表示されるリザルト画面をプレイ動画に含む投稿はあまりないと思われるため、今回は対象外としました。)

しかし、プレイ中の動画に表示されるプレイヤー名はこんな感じ。(赤丸)
![capt01.png](https://qiita-image-store.s3.amazonaws.com/0/287199/73e63872-9e32-1f03-a6e3-5b2ff52a81d8.png)

場所も大きさも背景もランダムで、ここからプレイヤー名を拾い出すのはAIでも組まないと無理でしょう。しかたがないので、味方の表示は諦め、敵を倒したときのキル表示のみを検索対象とします。よって探せる動画は、**自分がやられたシーンを含む動画のみ**に絞られます。

…まぁそれでも少しはプレイの参考にはなるし、なにも検索できないよりはましかなと。

ところで似たようなアプリケーションにIkaLog(スプラトゥーンリアルタイム画像解析ツール)がありますね。参考にしようと解説を読ませていただきましたが、あちらは抽出対象が固定位置、固定文字列(ステージ名、ブキ名など)であるため、いくらでも組合せが可能なプレイヤー名に同じ方法(マスク)を適用することはできそうもありません。(自分の名前だけならいけそうだけど、それじゃつまらないし)

ということで、以下のような流れで実装することにしました。

1. Twitter APIでNintendo Switchから投稿されたSplatoon2の動画のみを検索
1. 単位時間ごとにキル表示を切り出し
1. 文字認識でプレイヤー名を抽出


## イカ動画を検索する

Twitter APIをすでに使えることが前提ですが、いろいろなトライアンドエラーの結果、以下のような条件を指定することでほぼノイズなく目的の投稿を取ってくることができました。ポイントはsourceの指定でしょうか。

```python
api = tweepy.API(auth)

statuses = api.search(q='#Splatoon2 filter:videos source:nintendo_switch_share lang:ja', count=10, result_type='recent')
```

取ってきたstatus(投稿)の中身を見てみると、(抜粋)

```code
{
:
'extended_entities': {
    'media': [{
        'type': 'video',
        'video_info': {
            'aspect_ratio': [16, 9],
            'duration_millis': 29764,
            'variants': [{
                'content_type': 'application/x-mpegURL',
                'url': 'https://video.twimg.com/ext_tw_video/1050.../pu/pl/ZZp....m3u8?tag=5'
                }, {
                'bitrate': 2176000,
                'content_type': 'video/mp4',
                'url': 'https://video.twimg.com/ext_tw_video/1050.../pu/vid/1280x720/hMd....mp4?tag=5'
                }, {
                'bitrate': 256000,
                'content_type': 'video/mp4',
                'url': 'https://video.twimg.com/ext_tw_video/1050.../pu/vid/320x180/Cm9....mp4?tag=5'
                }, {
                'bitrate': 832000,
                'content_type': 'video/mp4',
                'url': 'https://video.twimg.com/ext_tw_video/1050.../pu/vid/640x360/2Pu....mp4?tag=5'
                }
            ]
        }
    }]
},
'id': 1050...,
:
}
```

こんな感じなんで、一番高画質な動画を保存します。

```python
for variant in status.extended_entities['media'][0]['video_info']['variants']:
	if 'bitrate' in variant:
		if variant['bitrate'] == 2176000:
			url = variant['url']
			urllib.request.urlretrieve(url, savedir+'/'+str(status.id)+'.mp4')
            break
```

長くなったので続きはまたそのうちに。


続きはこちら。＞https://qiita.com/floatnflow/items/6d723739e7ed0221a3d2