1カ月で作ったWebアプリ「DJ7」

Imagawa Takaya氏(以下、Imagawa):まずはPWA Nightのみなさん、こんばんは。今日は私が2020年1月に作成した「DJ7」というWebアプリについてお話ししたいと思います。

まずは自己紹介いたします。私はImagawa Takayaと申します。TwitterとGitHubのIDは「imataka7」でやっています。そして、私は都内のIT企業で働く社会人です。デザイナーではありません。

あと質問も「マシュマロ」で受け付けていますので、よろしければ発表後やイベントが終わったあとは、こちらからお願いいたします。

次に、タイトルにもあるDJ7が何なのかについてお話ししたいと思います。DJ7はYouTubeを同期再生するためのサービスです。同期再生とは、複数人で同じ動画を同じタイミングで見ることを言います。

Qiitaに公開の記事を書いたところ、「いいね!」が700を超え、公開後3日間はトレンドで1位になれました。また、今回のPWA Nightも、こちらの記事が主催者の方の目にとまり、発表にお誘いいただきました。YouTubeを見ながら意見を交わしたりするのは楽しいので、ぜひこれはみなさんにも体験してもらいたいです。

次に、今回の発表でお話しすることと、お話ししないことについて説明したいと思います。

まず、今回主に話すのはDJ7の開発に関わることです。1カ月でどのようにDJ7を作り上げたのか、そのための工夫や私が考えたことについてお話したいと思います。一方で話さないのはUIやUXの細かい理論的なお話です。私はデザイナーではないのでちょっとそういった話はわからないので、申し訳ございませんがお話ができません。こちらの点を注意していただければと思います。

また、今回の発表のアジェンダはこちらのようになります。

満足できるサービスがないなら、自分で作ってしまおう

はじめに開発前夜と題して、私がDJ7を開発するに至ったきっかけについてお話ししたいと思います。

今までの同期再生サービスにはどのようなものがあったのか、それらの問題点について紹介したいと思います。今回はいくつかある中から次の3点に絞ってお話しします。

1つ目は「MusicBot」についてです。MusicBotとは、Discordで通話をしながらYouTubeの音声を流せるツールです。Discordを知らない方はSlackに音声通話の機能がついたものを想像していただければと思います。このMusicBotでは、こちらの画像のように、チャットをCLIのように使って曲を追加できます。

次に「CyTube」と「Vynchronize」について紹介したいと思います。こちらはMusicBotと違って、Web上でYouTubeを同期再生できるサービスです。とくにCyTubeは日本語版もあり、国内にも一定数のユーザーがいるサービスとなっています。

今挙げたサービスは、私に同期再生の楽しさを教えてくれた一方で、このような問題点もありました。

まず使い方が直感的ではないことです。例えばMusicBotでは、複数行にわたってコマンド渡せば複数の曲を追加できそうですが、これはできません。ほかにも、曲を追加したあとに再生待ちの順番を変えることも難しいです。

こちらは主にCyTubeとVynchronizeの話になりますが、機能が多いのはいいのですけど、逆にそのせいでどこに何の機能があるのかわからず、同期再生を始めるまでに時間がかかってしまうといったことがありました。またチャットの機能も、私にとっては必要性を感じないものでした。

このように私が満足できるものがないならば、自分で作ってしまおうと考えるようになりました。そこで次に、サービスを自分で作成するにあたって実現したいものをリストアップしました。

まず1つ目に、Web上で使用可能なものにすること。2つ目に、サービスのコンセプトでもあるYouTubeの同期再生ができるもの。ここには「音楽の同期再生」とありますが、なぜサービスの公開時には動画の視聴もできるようにしたのかについては、後ほどお話しします。

3つ目に、先ほど挙げた既存のサービスの問題点を解消すること。4つ目に、PWAに対応すること。5つ目に、1カ月で作成するという目標を決めました。ここでどうして1カ月なのかについてですが、これはユーザーがサービスを本当に欲しているかどうかは手をかけて作る前にわかると考えたからです。

あと最後に、今回の開発の大きなテーマとして「同期再生をより身近なものにする」ことを決めて、開発を始めました。

こちらが今回の開発のスケジュールになります。白枠の中は実際に期間中に私がした作業について箇条書きでまとめてあります。また、下側の帯は各週に主にどんなしていたかを大まかに書いたものです。

ユーザーの意見を聞く開発スタイルは、プロトタイプの作成がきっかけ

ここからが実際に開発していたときの話になります。まずは開発1週目です。この週は先ほどの図の1週目の作業をやっていました。

またこちらに「PoC」と書いてありますが、これはProof of Conceptのことで、私が描いたサービスのコンセプトに本当に価値があるかを確かめてみました。

そして、私は価値があるかを確かめるためにプロトタイプの作成を始めました。目的はプロトタイプを作って実際に知り合いに使ってもらうことで、サービスに価値があるのかどうかを確かめること、同期再生の概念を伝えることと決めました。

次に、作成するにあたって技術の選定をしました。先ほども言ったとおり1カ月で作成する目標があったので、開発を効率よく進められるようにできるだけ使い慣れたものを選びました。

1つ目に、先ほど実現したいことの中でも挙げた、PWAへの対応を選びました。メリットは、まずWebをアプリのような使用感にしてくれることです。また、審査もないことから公開までの時間を短縮でき、さらにはクロスプラットフォームに対応させるのも簡単なので、私としてはメリットしかないと考えています。

Webでやることは決まっていたので、フロントエンドのフレームワークには、使い慣れたVue.jsを選びました。Vue.jsはHTMLとTypeScriptとCSSを別々に書けて、ロジックの実装とデザインを効率よく進められるので気に入っています。またVue.jsのいいところは、公式ツールによってPWAへの対応がすごく簡単にできるという点もあります。

またバックエンドにはFirebaseを選びました。これは単に使い慣れていることもありましたが、今回やる同期再生とFirestoreのリアルタイムの通知機能の相性がよいと考えたからです。

そして、こちらが実際に開発1週目で作成したものになります。こちらを見ていただければわかると思いますが、デザインは一切しておらず、画面のスペースも有効活用されていないものになっています。

知り合いに使ってもらったところ、このレベルでもおもしろいと言ってもらえました。このことで私以外にもこのサービスを欲していることを知り、同期再生の需要の確信につながりました。

開発スタイルの話になりますが、このプロトタイプが、このあとの開発で知り合いに使ってもらって意見を聞きながら進めていくことのきっかけになりました。

サービスの趣旨から外れた機能は実装しない

次に2週目です。2週目にやっていたことはこちらになります。この週は「最低限必要な機能が何か?」について考えていました。

必要なものを考えるにあたって、1カ月で作ることを決めていたので、時間がなく欲しい機能をどれもこれも実装できない事実がありました。その上で何が必要かを考え、次の2つの方針に従って実装を進めていくことにしました。

1つは、サービスの趣旨からズレていない機能を実装すること。次に、自分の知り合いに使ってもらって、ないと不便だと感じた機能を実装することです。

またもう1つ、私が実装していく上で意識したものに、「ソフトウェアは1つのことをうまくやる」というものがあります。これはUNIXの哲学としてエンジニアのみなさんならば聞いたことがあるかもしれません。この言葉が具体的に示すものは、DJ7では、サービスの趣旨が同期再生であり、これから外れた機能は実装しないことになります。

例えば、今回意図的に実装しなかった機能の1つにチャットの機能があります。チャットというコミュニケーションのためのサービスは、すでに数え切れないぐらいあります。DJ7は最初からこういった既存のサービスと一緒に使ってもらうことを目的に開発していました。

以上のことを踏まえて実装した機能がこちらになります。見ていただければわかると思いますが、どれも一般的な機能ばかりで変わったものはないと思います。これが私の考えた、サービスの趣旨からズレない機能であり、実際に使っていく上で必要不可欠だった機能の一覧になります。

次に、私が実装を進めていく上でこだわった点についてお話ししたいと思います。まず1つは、分散システムにすること。今回バックエンドとして使用したFirestoreのできることは、主にデータの保持と更新の通知になります。なので、データの操作はユーザーがやる必要がありました。そこで今回はユーザーが主体的になってFirestoreのデータを更新していく仕組みにしました。

こういった実装をすることによって、中央にAPIサーバやDBを操作するためのサーバを立てることなく同期再生を実装できました。また、この分散システムによってサービスの構成を小さくできました。実際に今回の開発ではほとんどフロントエンドの開発しかしていません。

次にリアルタイム性を高めることです。これがどういったことかというと、DJ7ではできるだけ見ているものを一緒にすることになります。

実際にDJ7の行っていることの1つにシークバーの同期があります。ユーザーがシークバーを操作すると、その変更がほかのユーザーにも伝播するようになっています。ほかのサービスでは、同期できたとしても部屋のホストだけだったり、そもそもできないといったものもありました。もしかすると、すべてのユーザーが平等に行えるのはDJ7が初めてかもしれません。

また、時刻のズレを補正することもやっています。これがどういうことかというと、ふだんはほとんど意識することはないかもしれませんが、実はみなさんのPC内部の時計も少しズレていることがあります。DJ7では1秒2秒のズレをなくすために、サービス内で補正された時刻を使用しています。これによってできるだけ同じものが見られるようになっただけではなく、時計のズレによる不具合も減らせました。