Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl で作るメディアストリーミングサーバー
Hideo Kimura
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
アジェンダ
 自己紹介
 ストリーミング技術の種類
 Perl + HTML5 での実装
 まとめ
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
自己紹介
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
自己紹介
 木村秀夫(@hidek)
 株式会社ディー・エヌ・エー
⁃ 技術系執行役員
⁃ Mobage オープンプラットフォーム統括
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ところで…
 とある転職サイトのインタビューでこんなことを言ってい
た…
 「コードを書かないマネージャーはありえない」
 今、仕事でコード書いてますか?
書いてますか?
書いてますか?
 …すみません
 …っていうか、仕事でコード書いたら怒られます><
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
この人に
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
実際…
 プレイングマネージャー難しい
 局所最適 vs 全体最適
 組織の規模が大きくなればなるほど薄く広く
見なければいけない
 だけどコード書きたい
 ジレンマ…
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
なので…
 家で細々と書いてます
「自分を支える技術」
 で、今回のお題は…
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
今回のお題
 会社で音楽聴きながら仕事したい
 家にある音楽ファイル全部はスマートフォンに入りきらない
 デスクトップもいいけどできればスマートフォンもデバイスとしたい
 そうだ!ストリーミングサーバーを作ろう!
 Perl で書く必要ないけど書きたいから書こう!
 ここまでスピリチュアルな話、こっから趣味の話
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミング技術の種類
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングとは
 マルチメディアコンテンツ(映像や音声)をダウンロードしながら再生す
る技術
 ストリーミングを支える技術
⁃ 圧縮 / 転送 / 制御
 圧縮プロトコル
⁃ MPEG-2 / AAC / Vorbis / WM(V|A)
 転送/制御プロトコル
⁃ 独自プロトコル(RTMP/MMS) vs HTTP
 今回のスコープは転送、制御プロトコルをどうするか
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: TCP/UDP Streaming
 専用プロトコルと専用ソフトを使うことによって実現する
 Adobe:
⁃ RTMP(E/S)
⁃ Flash Player & Flash Media Server
 Microsoft:
⁃ MMS
⁃ Windows Media Player & Windows Media Server
 Perl 実装: Kamaitachi by typester
⁃ FMS の Perl 実装
⁃ AnyEvent
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: TCP/UDP Streaming (RTMP/MMS)
 Pros:
⁃ ライブ配信ができる
⁃ コンテンツ保護ができる
⁃ マルチビットレート対応ができる
 Cons:
⁃ 専用クライアント・サーバーソフトが必要 = Flash & FMS
 スマートフォンの時代になり iOS で Flash が使えない = 致命傷
⁃ 今回 Kamaitachi を使わない理由の一つ
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Progressive Download
 いわゆる先読みダウンロード
 読み込んだところまでで seek 可能
 Pros:
⁃ HTML5 ブラウザーで再生可能
⁃ HTTPサーバーは特に対応しなくていい
 Cons:
⁃ 開始位置の指定はできない
⁃ ライブストリーミングはできない
⁃ コンテンツ保護はできない
⁃ マルチビットレート対応はできない
 厳密にはストリーミングではない
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Streaming (HLS/HDS)
 メディアファイルを10秒程度の断片と分けてプレイリストで管理する
 Apple: HLS (HTTP Live Streaming)
 Adobe: HDS (HTTP Dynamic Streaming)
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Streaming (HLS/HDS)
 HLS
⁃ Apple が提唱
⁃ IETF で標準化
• http://tools.ietf.org/html/draft-pantos-http-live-streaming-11
⁃ 対応クライアント
• iOS 3.0+
• Android Browser 3.0+
• Flash Player 11+
• QuickTime 10+
⁃ 対応サーバー
• 普通のHTTPサーバー
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Streaming (HLS/HDS)
 サーバーの設定
⁃ mime type の設定を加えるだけ
⁃ Apache だったら
 クライアント
⁃ video タグ
AddType application/x-mpegURL .m3u8
AddType video/MP2T .ts
…
<video width="1280" height="720" src=”playlist.m3u8" …
…
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Streaming (HLS/HDS)
 Pros:
⁃ 多くの HTML5 ブラウザーが対応している
⁃ スマートフォンでも動く
⁃ マルチビットレート対応ができる
⁃ ライブ配信ができる
⁃ HTTPサーバーは mime types の設定のみ
 Cons:
⁃ segmenter などでファイルを分割してプレイリストを用意する必要
がある
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Pseudo-Streaming
 HTTP 1.1 の Range Request と Partial Response を利用した疑似スト
リーミング
 ダウンロード開始位置を byte で指定 (Range Request)
 指定された位置からコンテンツを返す (Partial Response)
 これにより seek が可能
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Pseudo-Streaming
 Range Request
 Partial Response
GET /music.mp3 HTTP/1.1
Host: localhost
Range: bytes=500-999
…
HTTP/1.1 206 Partial Content
Accept-Range: bytes
Content-Length: 500
Content-Range: bytes 500-999/99999
…
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Pseudo-Streaming
 サーバーの設定
⁃ MP4 のストリーミングをする場合にはモジュール組み込みが必要
⁃ Apache: mod_h264_streaming
⁃ lighttpd: mod_h264_streaming
⁃ nginx: http_mp4_module
 クライアント
⁃ video タグ
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類: HTTP Pseudo-Streaming
 Pros:
⁃ HTML5 ブラウザーで再生可能
⁃ スマートフォンでも動く
⁃ 多くのHTTPサーバーはモジュール組み込みで対応できる
 Cons:
⁃ ライブストリーミングはできない
⁃ コンテンツ保護はできない
⁃ マルチビットレート対応はできない
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類
HTTP
TCP/UDP
Progressive Download Pseudo-Streaming HLS/HDS RMTP/MMS
ライブストリーミング × × ○ ○
動的ビットレート × × ○ ○
コンテンツ保護 × × △ ○
ファイルの設置 そのまま置ける そのまま置ける 断片に分割して置く そのまま置ける
シーク位置 最初から バイト単位 断片 + バイト単位 時間単位
クライアントソフト HTML5 ブラウザ Flash / WMP
サーバーソフト HTTP サーバー FMS / WMS
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
今回の要件
 ライブ配信: いらない
 コンテンツ保護: 自分のファイルだからいらない
 マルチビットレート制御: 自宅 or 会社なのでいらない
 コンテンツ: すでにリッピングしてるファイルを使いたい
 HTTP Pseudo-Streaming でよい
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ストリーミングの種類
HTTP
TCP/UDP
Progressive Download Pseudo-Streaming HLS/HDS RMTP/MMS
ライブストリーミング × × ○ ○
動的ビットレート × × ○ ○
コンテンツ保護 × × △ ○
ファイルの設置 そのまま置ける そのまま置ける 断片に分割して置く そのまま置ける
シーク位置 最初から バイト単位 断片 + バイト単位 時間単位
クライアントソフト HTML5 ブラウザ Flash / WMP
サーバーソフト HTTP サーバー FMS / WMS
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: Perl
 サーバーサイド
⁃ Partial Response: Plack::Middleware::Static::Range
⁃ by audrey
…
builder {
…
enable 'Plack::Middleware::Static::Range',
path => qr{^(?:/mp3/)},
root => '.';
…
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: Perl デモ
 Progressive Download
⁃ http://localhost:5000/pd/music.mp3
⁃ すぐ再生はされるけど seek できない
 HTTP Pseudo-Streaming
⁃ http://localhost:5000/hps/music.mp3
⁃ seek できる
 *.mp3 などの mime type が URL に含まれると、ブラウザが勝手にタグ
を描画してくれる
 Plack::Middleware::Static::Range では Accept-Range ヘッダを返し
てないので、一部ブラウザだと動かないかも (ブラウザ実装依存?)
 簡単ですね!
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: HTML5
 HTML5 クライアント
⁃ video/audio タグでガリガリ書くのしんどい
⁃ jPlayer http://jplayer.org/
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: HTML5
 jPlayer
⁃ メディアプレイヤー written by JavaScript
⁃ jQuery プラグイン
⁃ js だけではなく swf もついてくる
⁃ skin 対応
$(‘#jp').jPlayer({
ready: function(event){
$(this).jPlayer('setMedia', {
mp3: './mp3/music.mp3',
}).jPlayer('play’);
},
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: HTML5 デモ
 open demo.htm
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Perl + HTML5 での実装: その他必要なもの
 Web Application
⁃ 認証
⁃ ファイルブラウジング
⁃ プレイリスト管理
⁃ Amon2
 メディアクローラー
⁃ 指定パス以下の mp3 ファイルを検索してファイルパスとID3タグを
得してデーターベースに保存する
⁃ MP3::Info
 これから!!
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
まとめ
 最近の HTML5 ブラウザはマルチメディア対応が結構充実してるので特
定技術に依存しなくても良さそう
 オンデマンドなコンテンツ配信であれば HTTP Pseudo-Streaming でも
十分実用的
 個人で使うのであれば Perl でも問題ない
 余談
⁃ ビジネスで使う場合には DRM などが問題になりそうなので HLS +
AES
⁃ ライブストリーミングが必要な場合にはノータイムで HLS
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
ホビープログラミング
楽しいですよ!
偉くなったら仕事でコード書かせてもらえなくなるので今のうちですよ
Copyright (C) 2013 DeNA Co.,Ltd. All Rights Reserved.
Thank you!

Perl で作るメディアストリーミングサーバー

  • 1.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl で作るメディアストリーミングサーバー Hideo Kimura
  • 2.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. アジェンダ  自己紹介  ストリーミング技術の種類  Perl + HTML5 での実装  まとめ
  • 3.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. 自己紹介
  • 4.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. 自己紹介  木村秀夫(@hidek)  株式会社ディー・エヌ・エー ⁃ 技術系執行役員 ⁃ Mobage オープンプラットフォーム統括
  • 5.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ところで…  とある転職サイトのインタビューでこんなことを言ってい た…  「コードを書かないマネージャーはありえない」  今、仕事でコード書いてますか? 書いてますか? 書いてますか?  …すみません  …っていうか、仕事でコード書いたら怒られます><
  • 6.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. この人に
  • 7.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. 実際…  プレイングマネージャー難しい  局所最適 vs 全体最適  組織の規模が大きくなればなるほど薄く広く 見なければいけない  だけどコード書きたい  ジレンマ…
  • 8.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. なので…  家で細々と書いてます 「自分を支える技術」  で、今回のお題は…
  • 9.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. 今回のお題  会社で音楽聴きながら仕事したい  家にある音楽ファイル全部はスマートフォンに入りきらない  デスクトップもいいけどできればスマートフォンもデバイスとしたい  そうだ!ストリーミングサーバーを作ろう!  Perl で書く必要ないけど書きたいから書こう!  ここまでスピリチュアルな話、こっから趣味の話
  • 10.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミング技術の種類
  • 11.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングとは  マルチメディアコンテンツ(映像や音声)をダウンロードしながら再生す る技術  ストリーミングを支える技術 ⁃ 圧縮 / 転送 / 制御  圧縮プロトコル ⁃ MPEG-2 / AAC / Vorbis / WM(V|A)  転送/制御プロトコル ⁃ 独自プロトコル(RTMP/MMS) vs HTTP  今回のスコープは転送、制御プロトコルをどうするか
  • 12.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: TCP/UDP Streaming  専用プロトコルと専用ソフトを使うことによって実現する  Adobe: ⁃ RTMP(E/S) ⁃ Flash Player & Flash Media Server  Microsoft: ⁃ MMS ⁃ Windows Media Player & Windows Media Server  Perl 実装: Kamaitachi by typester ⁃ FMS の Perl 実装 ⁃ AnyEvent
  • 13.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: TCP/UDP Streaming (RTMP/MMS)  Pros: ⁃ ライブ配信ができる ⁃ コンテンツ保護ができる ⁃ マルチビットレート対応ができる  Cons: ⁃ 専用クライアント・サーバーソフトが必要 = Flash & FMS  スマートフォンの時代になり iOS で Flash が使えない = 致命傷 ⁃ 今回 Kamaitachi を使わない理由の一つ
  • 14.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Progressive Download  いわゆる先読みダウンロード  読み込んだところまでで seek 可能  Pros: ⁃ HTML5 ブラウザーで再生可能 ⁃ HTTPサーバーは特に対応しなくていい  Cons: ⁃ 開始位置の指定はできない ⁃ ライブストリーミングはできない ⁃ コンテンツ保護はできない ⁃ マルチビットレート対応はできない  厳密にはストリーミングではない
  • 15.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Streaming (HLS/HDS)  メディアファイルを10秒程度の断片と分けてプレイリストで管理する  Apple: HLS (HTTP Live Streaming)  Adobe: HDS (HTTP Dynamic Streaming)
  • 16.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Streaming (HLS/HDS)  HLS ⁃ Apple が提唱 ⁃ IETF で標準化 • http://tools.ietf.org/html/draft-pantos-http-live-streaming-11 ⁃ 対応クライアント • iOS 3.0+ • Android Browser 3.0+ • Flash Player 11+ • QuickTime 10+ ⁃ 対応サーバー • 普通のHTTPサーバー
  • 17.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Streaming (HLS/HDS)  サーバーの設定 ⁃ mime type の設定を加えるだけ ⁃ Apache だったら  クライアント ⁃ video タグ AddType application/x-mpegURL .m3u8 AddType video/MP2T .ts … <video width="1280" height="720" src=”playlist.m3u8" … …
  • 18.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Streaming (HLS/HDS)  Pros: ⁃ 多くの HTML5 ブラウザーが対応している ⁃ スマートフォンでも動く ⁃ マルチビットレート対応ができる ⁃ ライブ配信ができる ⁃ HTTPサーバーは mime types の設定のみ  Cons: ⁃ segmenter などでファイルを分割してプレイリストを用意する必要 がある
  • 19.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Pseudo-Streaming  HTTP 1.1 の Range Request と Partial Response を利用した疑似スト リーミング  ダウンロード開始位置を byte で指定 (Range Request)  指定された位置からコンテンツを返す (Partial Response)  これにより seek が可能
  • 20.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Pseudo-Streaming  Range Request  Partial Response GET /music.mp3 HTTP/1.1 Host: localhost Range: bytes=500-999 … HTTP/1.1 206 Partial Content Accept-Range: bytes Content-Length: 500 Content-Range: bytes 500-999/99999 …
  • 21.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Pseudo-Streaming  サーバーの設定 ⁃ MP4 のストリーミングをする場合にはモジュール組み込みが必要 ⁃ Apache: mod_h264_streaming ⁃ lighttpd: mod_h264_streaming ⁃ nginx: http_mp4_module  クライアント ⁃ video タグ
  • 22.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類: HTTP Pseudo-Streaming  Pros: ⁃ HTML5 ブラウザーで再生可能 ⁃ スマートフォンでも動く ⁃ 多くのHTTPサーバーはモジュール組み込みで対応できる  Cons: ⁃ ライブストリーミングはできない ⁃ コンテンツ保護はできない ⁃ マルチビットレート対応はできない
  • 23.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類 HTTP TCP/UDP Progressive Download Pseudo-Streaming HLS/HDS RMTP/MMS ライブストリーミング × × ○ ○ 動的ビットレート × × ○ ○ コンテンツ保護 × × △ ○ ファイルの設置 そのまま置ける そのまま置ける 断片に分割して置く そのまま置ける シーク位置 最初から バイト単位 断片 + バイト単位 時間単位 クライアントソフト HTML5 ブラウザ Flash / WMP サーバーソフト HTTP サーバー FMS / WMS
  • 24.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. 今回の要件  ライブ配信: いらない  コンテンツ保護: 自分のファイルだからいらない  マルチビットレート制御: 自宅 or 会社なのでいらない  コンテンツ: すでにリッピングしてるファイルを使いたい  HTTP Pseudo-Streaming でよい
  • 25.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ストリーミングの種類 HTTP TCP/UDP Progressive Download Pseudo-Streaming HLS/HDS RMTP/MMS ライブストリーミング × × ○ ○ 動的ビットレート × × ○ ○ コンテンツ保護 × × △ ○ ファイルの設置 そのまま置ける そのまま置ける 断片に分割して置く そのまま置ける シーク位置 最初から バイト単位 断片 + バイト単位 時間単位 クライアントソフト HTML5 ブラウザ Flash / WMP サーバーソフト HTTP サーバー FMS / WMS
  • 26.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装
  • 27.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: Perl  サーバーサイド ⁃ Partial Response: Plack::Middleware::Static::Range ⁃ by audrey … builder { … enable 'Plack::Middleware::Static::Range', path => qr{^(?:/mp3/)}, root => '.'; …
  • 28.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: Perl デモ  Progressive Download ⁃ http://localhost:5000/pd/music.mp3 ⁃ すぐ再生はされるけど seek できない  HTTP Pseudo-Streaming ⁃ http://localhost:5000/hps/music.mp3 ⁃ seek できる  *.mp3 などの mime type が URL に含まれると、ブラウザが勝手にタグ を描画してくれる  Plack::Middleware::Static::Range では Accept-Range ヘッダを返し てないので、一部ブラウザだと動かないかも (ブラウザ実装依存?)  簡単ですね!
  • 29.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: HTML5  HTML5 クライアント ⁃ video/audio タグでガリガリ書くのしんどい ⁃ jPlayer http://jplayer.org/
  • 30.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: HTML5  jPlayer ⁃ メディアプレイヤー written by JavaScript ⁃ jQuery プラグイン ⁃ js だけではなく swf もついてくる ⁃ skin 対応 $(‘#jp').jPlayer({ ready: function(event){ $(this).jPlayer('setMedia', { mp3: './mp3/music.mp3', }).jPlayer('play’); },
  • 31.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: HTML5 デモ  open demo.htm
  • 32.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Perl + HTML5 での実装: その他必要なもの  Web Application ⁃ 認証 ⁃ ファイルブラウジング ⁃ プレイリスト管理 ⁃ Amon2  メディアクローラー ⁃ 指定パス以下の mp3 ファイルを検索してファイルパスとID3タグを 得してデーターベースに保存する ⁃ MP3::Info  これから!!
  • 33.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. まとめ  最近の HTML5 ブラウザはマルチメディア対応が結構充実してるので特 定技術に依存しなくても良さそう  オンデマンドなコンテンツ配信であれば HTTP Pseudo-Streaming でも 十分実用的  個人で使うのであれば Perl でも問題ない  余談 ⁃ ビジネスで使う場合には DRM などが問題になりそうなので HLS + AES ⁃ ライブストリーミングが必要な場合にはノータイムで HLS
  • 34.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. ホビープログラミング 楽しいですよ! 偉くなったら仕事でコード書かせてもらえなくなるので今のうちですよ
  • 35.
    Copyright (C) 2013DeNA Co.,Ltd. All Rights Reserved. Thank you!