プログラミングスクールで、「リアルバーチャルYoutuber」というWebサービスを作りました
- はじめに
- 作ったWebサービスの紹介
- 開発日誌
- Getting Realを読む
- エレベーターピッチを作る
- 技術検証
- ペーパープロトタイプを作る
- 技術選定とシステム構成図の作成
- 開発の進め方を考える
- $ rails new
- Herokuをセットアップ
- 独自ドメイン設定 + SSL化
- SendGridをセットアップ
- S3 + CloudFrontをセットアップ
- Googleアナリティクスをセットアップ
- Googleサーチコンソールをセットアップ
- ロゴ・ファビコンを作る
- サイトマップを自動作成
- metaタグを設定する
- Rubocopを設定する
- 便利Gemを導入する
- Railsを日本語化
- 利用規約・プライバシーポリシーを作る
- PageSpeed Insightsで表示速度を測定する
- @machida さんによるデザインレビューを受ける
- @komagata さんによるコードレビューを受ける
- さいごに
はじめに
(まだまだRails勉強中の身で、至らない点も多いと思います💦よろしくお願いします🙇)
FJORD BOOT CAMP(フィヨルドブートキャンプ) というプログラミングスクールの最終課題で、自作のWebサービスを作りました。
本記事はWebサービスの紹介と開発日誌のまとめです。
作ったWebサービスの紹介
「リアルバーチャルYoutuber」は、AIが生み出した実在しない人物の顔を、AIによる顔合成技術でユーザーの顔に合成することで、顔を匿名化するWebサービスです。
ユーザーは、ベースとなる動画をアップロードして、用意された実在しない人物の顔モデルを選ぶことで、その顔になることができます。
実写Youtubeをしたいけれど顔出しはしたくない、といった方達に使って頂けると嬉しいです。
Rails + Herokuで作られていて、開発期間は2週間ほどです。
利用は無料で、ソースコードはOSSとして公開しています。
サービス: https://realvtuber.shita1112.com
ソースコード: https://github.com/shita1112/realvtuber
プログラミングスクールで、『リアルバーチャルYoutuber』というWebサービスを開発しました。
— shita (@shita1112) September 11, 2019
AIが生み出した実在しない人物の顔をあなたの顔に合成することで、別の人間になれます。
解説記事: https://t.co/nPmbXtsnp3
サービス: https://t.co/u1MoL1kUAa pic.twitter.com/jHH2rIf8kF
開発日誌
以下、開発時にやったことのまとめです。
フィヨルドブートキャンプ生のような、初めてWebサービスを作る方達に読んでいただけると嬉しいです。
次回Webサービスを作る時用の備忘録も兼ねているので、リンク多めです。ご了承ください🙇
Getting Realを読む
まず最初にフィヨルドブートキャンプでサービス開発の教科書としておすすめされた Getting Real を読みました。(たしか翻訳もあったはずですが、なぜか検索しても見つかりませんでした💦すみません🙇)
Rails作者のDHHさんのいる会社「BaseCamp」の社長が書いた文章です。
サービス開発する際に大切なことがたくさん書かれています。
サービス開発で悩んだ際は、この本に立ち返りつつサービス開発を進めていきました。(とはいえサービス開発の哲学が凝縮された本なので、まだ消化しきれていないことが多いのですが・・・。)
今後も何度か読むことになりそうです。
エレベーターピッチを作る
エレベーターピッチとは、投資家さんとエレベータで30秒だけ一緒にいられる場合に、短い時間でサービスの本質を伝えるための文章です。
趣味の個人開発の場合でも、エレベーターピッチを作っておくとプロダクトの「解決する課題」や「ターゲット」等を自分の中で整理でき、「本当に必要な機能」と「必要ない機能」を実装前に知ることができます。
あと、それをメンターさんたちと共有できます。
エレベーターピッチのテンプレートはいくつかパターンがあるようですが、フィヨルドブートキャンプで使っているのはこんな感じです。
サービス名
というサービスは、
解決する問題
を解決したい
このサービスを使うターゲット
向けの、
サービスのカテゴリー
です。
ユーザーは このサービスでできること
ができ、
競合サービス
とは違って、
差別化要素
が備わっている事が特徴です。
自分の場合はいくつかぼんやりしたWebサービスのアイデアがあったのですが、自分で一人では考えをまとめられなかったので、一度エレベーターピッチにしてメンターである@komagataさんと@machidaさんのレビューを受けることにしました。
作ったエレベーターピッチは以下の4つです。
リアルバーチャルYoutuber
というサービスは、
Youtubeで実写動画を作る際に、顔を出さなければいけないという問題
を解決したい
Youtubeで実写動画を公開したいけど、顔出しはしたくない人
向けの、
動画の顔の匿名化ツール
です。
ユーザーはAIで生成された実在しない人物の顔を、AIによる顔転写技術を使ってユーザーの顔に転写することで、ユーザーの顔を実在しない人物の顔に置き換える
ことができ、
バーチャルYoutuber
とは違って、
実写に使えます。
Readme翻訳
というサービスは、
Gemを利用する時に、英語が苦手なためReadmeを読まないという問題
を解決したい
英語が苦手なRailsプログラマ(=自分)
向けの、
英語技術文書のリーディング支援ツール
です。
ユーザーはReadmeの隣に表示されるGoogle翻訳の結果を読み、日本語で大意を掴むことで、Readmeを読む負担を減らす
ことができ、
日本語に翻訳(chrome内蔵のGoogle翻訳機能)でReadmeを読む
場合とは違って、
Google翻訳を原文を読むための補助として利用します。
Tsukutte(ツクッテ)
というサービスは、
技術力UPとポートフォリオ強化のためにWebサービスを作りたいが、作りたいものがないという問題
を解決したい
Webエンジニア
向けの、
マッチングサービス
です。
依頼者は自分が作って欲しいWebサービスの内容をTsukutteに書き込み、開発者は書き込み内容から作りたいWebサービスを選んで開発する
ことができ、
クラウドソーシングでWebサービスの開発を依頼/開発する場合
とは違って、
無料なので依頼者/開発者ともに気楽に使えます。
Readch(リードック)
というサービスは、
英文のEPUBやPDFを読む際に、英文リーディング用のChrome拡張(Mouse Dictionary等)を使えないという問題
を解決したい
英語が苦手なRailsプログラマ(=自分)
向けの、
洋書の技術書のリーディング支援ツール
です。
ユーザーが英文のEPUB/PDFをサイトにアップロードすると、HTMLに変換されてレンダリングされるので、Chrome拡張を使って読む
ことができ、
EPUP/PDFをHTMLに変換するWebサービス
とは違って、
HTMLをダウンロードせずに、サイト上で読む
ことができます
フィヨルドブートキャンプからのアドバイスで、エレベーターピッチを作る際には以下の2点に気をつけました。
「自分の課題を解決するサービスにする」
自分の課題を解決するサービスだと、ターゲットが自分になり普段痛みを感じている具体的な課題から始めることが出来るので、課題の質を上げられます。
あと必ず自分は使うので、個人開発でありがちなユーザー数0という悲劇を避けられます。(このパターンは本当に多いそうです。)
「CGM(Consumer Generated Media)型ではなくツール型にする」
CGMだとそもそもユーザーやユーザー投稿が集まらないと始まらないので、避けたほうがいいそうです。
ツール型なら過疎っていてもとりあえず自分は使えるので安心です。
@machidaさんや@komagataさんに相談しつつ、最終的にはツール型でポートフォリオとして面白がってもらえそうな「リアルバーチャルYoutuber」を作ることに決めました。
参考
技術検証
フェイススワップ(ディープフェイク)というDeep Learningを用いた顔転写技術とこの生成技術で今回のプロダクトを作れそうと思いましたが、自然な出来になるのか心配だったので先に検証しました。
最初の試作動画はこんな感じです。
少し顔が崩れていますが、改良すればなんとかいけるかなーと判断して開発を始めました。
いくつか調整を重ねて、今はもう少し質が上がっています。
ペーパープロトタイプを作る
作るもののざっくりとしたUIを書くことで、必要な機能やUIの検討ができます。
自分はこんな感じで作りました。
ログイン前の画面4つ
ログイン後の画面4つ
ここでもメンターさん達にレビューしていただき、そもそもログインはいるのかー?等をつめていきました。
参考
技術選定とシステム構成図の作成
技術スタックはこんな感じです。
- バックエンド: Rails
- フロントエンド: Vue.js + Webpack(Webpacker) + Material Design for Bootstrap 4
- インフラ: Heroku + S3 + CloudFront + MySQL
バックエンドはちょうどRails6がリリースされたタイミングだったので、Rails6で作りました。
gemが対応できているか少し心配でしたが、特に問題なく開発できました。
フロントエンドはVue.jsの勉強をがっつりしたばかりだったので、経験を積むためにVue.jsを選びました。(でも結局JS側のコードはあんまり書きませんでした😹)
CSSフレームワークにはMaterial Design for Bootstrap 4を採用しました。
インフラはHerokuを採用しています。
CDNはHerokuのFastlyアドオンを使うと簡単にできるそうなのですが、価格面を考慮した結果CloudFrontを採用することにしました。
システム構成はこんな感じです。
動画作成でDeep Learningを使うので、GPUサーバーが必要です。
しかしAWSやGCPでGPUサーバーを使おうと思うと、GPU1つで数万円/月もかかってしまい、とても運用できません💦
たまたま自宅にGTX 1080 Tiが4枚あったので、自宅でGPUサーバーを組んで運用することにしました。
GPUサーバーにもコードを置いて、そこでJobワーカーを動かします。
あとこの図だとassetsをS3に置いていますが、 @komagata さんにassetsはS3に置かずにHerokuから配信すればいいよーとアドバイスいただいたので、今はHerokuからassetsを配信して前段にCloudFrontを置くように変更しています。
開発の進め方を考える
タスク管理にはGithubプロジェクトを利用していました。
しかし途中から面倒になってしまい、 Emacsのorgモード で管理するようになりました。
(orgモードはMarkdown相当の機能にTODO管理とかの便利機能を色々詰め込んだ感じのものです。)
ワークフローはOSSなのでちゃんとしたほうがいいのかなと思い GitHub Flow と呼ばれるものを使っていました。
しかしこちらも途中から面倒になってしまい、結局masterに直接commitするようになりました。
$ rails new
ここまでで開発の準備ができたので、ここから実際の開発を進めていきます。
$ rails new
でRailsアプリを作成します。この際に--skip-xxxx
オプションを使うと不要な機能を外してくれるので便利です。
$ rails new realvtuber --skip-test --skip-turbolinks --skip-active-storage --skip-action-cable --skip-action-text --skip-action-mailbox --webpack=vue --database=mysql
テストはRSpecを使い、ファイルアップローダーはActiveStrageの代わりにCarrierWaveを使うのでskipしました。
あとVue.jsやMySQLを使う場合はここで指定しておくと、自分で設定する手間を省けます。
Herokuをセットアップ
PaasにはHerokuを利用しました。
参考
独自ドメイン設定 + SSL化
Herokuアプリを作ると「サービス名.herokuapp.com」ドメインが割り当てられます。
これを利用してもいいのですが、せっかくなので独自ドメインを お名前.com で取得して設定します。
実はこのアプリを作る前に「Readme翻訳」というサービスを開発をするために独自ドメインを取得したのですが、結局諸事情で開発が中止になってしまいドメインだけが手元に残ってしまいました。
とても悲しかったので、その教訓から作ったWebサービスが誰からも使われなくてさみしい問題を解決する(しない)意識低い方法論 を参考にさせていただいて、サブドメインで運用することにしました。
Herokuで独自ドメインをSSL化するのは若干面倒でしたが、以下の記事等を参考にしてなんとかいけました。
参考
- Custom Domain Names for Apps | Heroku Dev Center
- Heroku SSL | Heroku Dev Center
- 初めてHerokuで独自ドメインを公開するあなたへ
- 独自ドメインをherokuに設定しSSL化もおこなう
ルートドメインを設定する場合にも、PointDNSというアドオンを使えば無料でいけます。
参考
SendGridをセットアップ
メール配信にはSendGridアドオンを利用します。
無料枠が大きいので、個人開発の場合は無料枠に収まることが多そうです。
参考
S3 + CloudFrontをセットアップ
Herokuにはファイルを置けないので、ファイル置き場としてS3を用意します。
あと配信速度を上げるためにCDNとしてCloudFrontも一緒に利用します。
S3の前段にCloudFrontを置くイメージです。
CloudFront + S3 によるCDN (Cache Distribution パターン) 構築手順 を参考に設定すればいけました。
特に難しい箇所もなく、基本的にはデフォルト設定でOKです。
assetsの配信でHerokuの前段にCloudFrontを置く場合は、Rails側の設定も必要になります。
特にWebフォントを使用するためにはCORS対応が必要になり、そこでハマりました。
以下のサイトが参考になります。
- CloudFront CDN with Rails on Heroku
- heroku+CloudFrontで静的ファイルを配信する(Webフォント対応)
- Heroku on Rails で asset_sync ではなく Cloudfront を利用する方法
Googleアナリティクスをセットアップ
アクセス解析を行うために、Googleアナリティクスを導入しておきます。
参考
Googleサーチコンソールをセットアップ
サイトの検索キーワード等を調べるために、Googleサーチコンソールの設定を行っておきます。
参考
ロゴ・ファビコンを作る
ロゴはWebで使えるデザインツールのCanvaで作りました。
こんな感じでフォントを最大サイズにして、フォントパワーに全てを託します。
あとは色を反転させたものをファビコンとして使います。
ファビコンはこちらのサイトで作れます。
参考
サイトマップを自動作成
サイトマップはGoogle等の検索エンジンにサイトの情報を伝えることで、インデックスを促します。
sitemap_generatorというgemを使い、リリース時にサイトマップを自動作成するようにしておきます。
参考
metaタグを設定する
SEO対策としてtitle等のmetaタグを設定できるようにします。
meta-tags というgemを利用しました。
必要な部分だけ各ページで上書きできるので、メンテしやすくてよかったです。
参考
Rubocopを設定する
Rubocopを使い、コーディング規約を強制します。
Rubocopのデフォルト設定は(Ruby Style Guide通りなのですが)ルールが厳しめで守るのが難しいので、少し緩くしたいです。
@onkさんがいい感じの設定をgemにまとめてくださっているので、そちらのonkcopというgemを利用します。
# Gemfile group :development do gem "onkcop", github: "shita1112/onkcop" # onkcopがrubocop最新版に対応していないようなので、一時的にforkを使う gem "rubocop" gem "rubocop-rails" gem "rubocop-rspec" end
$ bundle install
FrozenStringLiteralの設定を追加しておきます。
# .rubocop.yml inherit_gem: onkcop: - "config/rubocop.yml" - "config/rails.yml" - "config/rspec.yml" AllCops: TargetRubyVersion: 2.6 Exclude: - "bin/bundle" - "node_modules/**/*" Style/FrozenStringLiteralComment: Enabled: true
rubocopコマンドの--auto-correct
を使うとルールに合わせて機械的に変換してくれるので、使っておきます。
$ rubocop --auto-correct
参考
便利Gemを導入する
開発する際に便利なGemを先に導入しておきます。
bullet
N+1の検出ができます。
letter_opener
developmentモードで簡単に送信メールの確認できます。
letter_opener_web
letter_openerのwebインターフェースです。
xray-rails
どの部分がパーシャルか、画面上に表示してくれます。
pry-rails
binding.pry
でブレークポイント仕込めます。
pry-byebug
binding.pry
でステップ実行できます。
pry-doc
pry-alias
binding.pry
の代わりにbp
でいけます。
awesome_print
p
やpp
より出力が綺麗なap
が使えるようになります。
tapp
レシーバをputsしてくれるtapです。デバッグで利用します。
[1, 2, 3].tapp(&:size) 3 => [1, 2, 3]
rack-mini-profiler
簡易的なパフォーマンス測定として、ページ左上にレンダリング時間を表示してくれます。
newrelic_rpm
パフォーマンス測定できるNew Relicというサービスを利用できます。Herokuのアドオンとして基本機能は無料で使えます。
enum_help
Rails標準機能のenumにi18n機能を追加してくれます。
config
環境毎に定数管理できます。
gon
Rails側からJS側に変数を渡せます。
browser
ブラウザ/デバイスの種類を判定できます。スマホかどうか調べるのに利用します。
devise
認証。カスタマイズが難しく避けられがちですが、今回はビューの変更だけで済みそうだったので利用しました。
pundit
認可。リソース毎にファイルを作るので、cancancanより好みです。
active_decorator
デコレータ。自動的にデコレートしてくれるので、draperより好みです。関連先もデコレートしてくれるようになっていました。
carrierwave
ファイルアップローダー。たしかActiveStrageにはキャッシュとバリデーション機能がまだなかったはずなのでこちらを利用します。
Railsを日本語化
設定を変更して、タイムゾーンとlocaleを日本向けにします。
# config/application.rb + config.time_zone = "Tokyo" + + config.i18n.default_locale = :ja
利用規約・プライバシーポリシーを作る
フッターに置く利用規約とプライバシーポリシーを作成します。
何を書けばいいのか全くわからなかったのですが、フィヨルドブートキャンプの先輩方のサービスを参考にさせていただきました🙇
あと今読んでいる途中なのですが、【改訂新版】良いウェブサービスを支える 「利用規約」の作り方 が利用規約を置く意義等が丁寧に書かれていてとても参考になります。
PageSpeed Insightsで表示速度を測定する
Railsアプリが一通りできたらPageSpeed Insightsで表示速度を測定します。
PageSpeed Insightsはサイトの表示速度を測定した上で、遅い場合には改善策を提示してくれます。
測定してみるとリアルバーチャルYoutuberはパソコンが98点、モバイルが89点でした。
「合格した監査」を見てみると、画像を適切なサイズで配信できていることや、CSS/JSをminifyできていること等を確認できます。
「改善できる項目」を見てみると、「次世代フォーマットでの画像の配信」を改善すれば速くできることがわかります。
この場合はWebp対応ブラウザにWebpを配信すれば速くできそうです。
@machida さんによるデザインレビューを受ける
メンターでデザイナーの@machida さんにデザインレビューをしていただきました。
こちらがもともとのデザインです。
作成した動画をリストとして並べています。
次がレビューを元に修正したデザインです。
作成した動画をカードとして並べることで、前のデザインよりスッキリして見えます。
あとh1タグはただでかい文字が置かれているだけだったのですが、別ブロックを作ることで見やすくなりました。
他のページもかなり丁寧にレビューしてくださいました。
普段デザインのことはあまり考えていなかったので、デザインはとても苦労しました。
開発のかなりの時間をデザインに使ってた気がします。
なのでプロのデザイナーである@machidaさんにアドバイス頂けたのはとても助かりましたし、勉強になりました。
@komagata さんによるコードレビューを受ける
リリースを優先させてテストコードがおざなりなので、これからテスト書いてレビューしていただきます。
さいごに
謝辞
メンターとして相談にのってくださった@machidaさん、@komagataさん、毎週の進捗報告会に付き合ってくださった@matt59649858さん、@tararicoさん、@wai_doiさん、フィードバックをくださったフィヨルドブートキャンプの皆さん、唐突なお願いにも関わらず動画提供や戦略面でのアドバイスなど親身になって協力してくださったYoutuberの@fujishuuさん、@Layer_Qさん、皆さんのおかげでなんとか完成させることができました。本当にありがとうござました🙇
あとうちのお猫様には開発中も癒やされました。ありがとうございました😺
(完成祝にちゅーるあげました)
Railsのお仕事探しています🙇
これでプログラミングスクールが完了になるので、これからお仕事探しを本格的に始めます。
もしRailsプログラマ探してるよーという方がいましたら、自分の経歴をまとめたのでこちらを見ていただけると嬉しいです。
よろしくおねがいします🙇