abceed webの映画・ドラマ機能開発で使用した動画ライブラリの変遷

この記事は[Globeeアドベントカレンダー](https://qiita.com/advent-calendar/2023/globee)15日目の記事です。

[AI英語教材 abceed（エービーシード）](https://www.abceed.com/)のWeb版のフロントエンド開発をしている[蔵下](https://twitter.com/umi_kappa)です。2023年春にリリースされた映画・ドラマ機能で、動画プレイヤーの実装にOSSの動画ライブラリを使用しているのですが、最終的に採用した動画ライブラリにたどり着くまで、紆余曲折がありました。今回は、その変遷を紹介します。

# abceedの映画・ドラマ機能をざっくりご紹介

![abceed紹介ページのキャプチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55103/b783c012-806b-8a20-18e3-e57dd4d6df50.png)

みなさんは「映画を見て英語を勉強した」という体験談を聞いたことはありますか？ 映画はネイティブな英語に字幕がついていてストーリーも楽しめる、英語学習にはうってつけのコンテンツです。今まではそれをテレビや動画配信サイトのボタンでポチポチと操作するしかありませんでしたが、abceedでは映画での英語学習に特化した機能を提供することで、ユーザーの効率的な英語力向上を目指しています。

![英語・ドラマ機能の説明画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55103/c95d61bc-2059-af5e-7cec-0c669c0c1c10.png)

※記事「[映画で楽しく英語学習！abceedの映画機能おすすめ学習法](https://note.com/globee/n/ne81dc1b60ccb)」では、abceedの映画・ドラマ機能でより効果的に学習する方法を紹介しています。

# 動画プレイヤーの要件

映画・ドラマ機能を開発するにあたり、動画プレイヤーの実装には下記の要件がありました。

- DRMで著作権保護できること
- Google Chromeで再生できること
- スムーズにフレーズ送りできること

## DRMで著作権保護できること

映画会社から映画のライセンスを取得するには、DRMによる著作権保護が必須でした。

> DRMはDigital Rights Managementの略。デジタルコンテンツにおいてコンテンツホルダーが持つ著作権などの権利が不当に侵害されることを防ぐため、コンテンツの利用や複製を制限する仕組みの総称です。
> 
> 記事「[第70回　DRMとは？デジタルコンテンツを保護するその仕組みを解説](https://www.tdk.com/ja/tech-mag/knowledge/070)」より引用

DRMを導入することで、PCやスマートフォンでスクリーンショットを撮ろうとしても動画部分が黒塗りになり、複製を防止します。

![動画プレイヤーをキャプチャした様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55103/39740754-6003-d8be-bf96-4c0be2362fbf.png)

※実装した動画プレイヤーをキャプチャした様子

## Google Chromeで再生できること

ブラウザによってDRMの規格が異なるため、ブラウザごとにDRMの処理を実装しなくなてはなりません。abceed webでは、Google Chromeをサポートブラウザとしているため、Googleが開発している[Widevine](https://www.widevine.com/)で再生できる必要がありました。

下記がブラウザごとの規格です。

- Google Chrome
  -  [Widevine](https://www.widevine.com/)
- Microsoft Edge
  - [PlayReady](https://learn.microsoft.com/ja-jp/playready/)
- Safari
  - [FairPlay](https://developer.apple.com/streaming/fps/)

※Microsoft EdgeはGoogle Chromeと同じく[Chromium](https://www.chromium.org/chromium-projects/)になりましたが、DRMの規格は異なります

## スムーズにフレーズ送りできること

通常の動画プレイヤーでは、チャプターごとに再生位置を行き来しますが、abceedの映画・ドラマ機能では、気になったフレーズをストレスなく再生できるように、フレーズ（台詞）ごとに再生位置を行き来できる必要があります。そのため、読み込み前のフレーズも極力瞬時に再生できる動画ライブラリを採用しました。

# 要件を満たすために試した動画ライブラリ

映画・ドラマ機能の開発フェーズにごとに、下記の3つの動画ライブラリを試しました。結果、[Shaka Player](https://github.com/shaka-project/shaka-player)を採用しました。

1. [hls.js](https://github.com/video-dev/hls.js)
2. [Video.js](https://github.com/videojs/video.js)
3. [Shaka Player](https://github.com/shaka-project/shaka-player)

## 動画プレイヤープロトタイプ実装期: hls.js

Google ChromeでWidevineのDRMを対応するには、動画フォーマットを[MPEG-DASH](https://e-words.jp/w/MPEG-DASH.html)にする必要があるのですが、hls.jsの名の通り[HLS](https://e-words.jp/w/HLS.html)からスタートしました。なぜ初めからMPEG-DASHをサポートする動画ライブラリにしなかったかというと、すでにabceedの他の機能でHLSが使われていたため、その資産を活用しながら動画プレイヤーのプロトタイプを素早く実装し、映画での英語学習に適したUIは何なのか？を試すためでした。
映画会社の担当者にも「abceedで映画を使った英語学習はどういうものなのか？」を先手先手で伝えることができたため、その時持っている武器でプロトタイプを素早く出す！のは大切だと感じました。

## DRM実装期: Video.js

プロトタイプでUIの試行錯誤を繰り返し、映画・ドラマ機能でやりたいことが実現できそうだという結論に至り、本実装に入っていきました。UIのベースはプロトタイプで出来上がっていたため、hls.jsで仮実装していた動画のロジックをDRMとMPEG-DASHに対応しているVideo.jsに置き換えていきました。Video.jsはGitHubのStar数も多い人気の動画ライブラリですが、DRMについての情報になかなかたどり着けず（サンプル通りにやっても再生できない...などなど）、動画ライブラリの置き換えには想定以上に時間がかかりました。
Video.jsのコードも覗きながら少しずつ改善し続け、なんとかDRMで再生できるところまで実装できました。

が、ここで一つ問題が...
動画プレイヤーの要件にあった `スムーズにフレーズ送りできること` が満たせなかったのです。動画の途中から再生を開始して、その開始位置より前までフレーズを素早く戻し続けると動画が停止してしまう現象にぶち当たった。この現象の調査にも時間をかけたのですが、残念ながら解決できませんでした:sob:
英語学習の体験的に、この部分は妥協できない！と判断し、他の動画ライブラリを探すことにしました。

## ブラッシュアップ期: Shaka Player

DRMがサポートされている動画ライブラリを、OSSから有料のものまで調べました。その中から、OSSでDRMのサンプルも多いShaka Playerを試してみることにしました。Video.jsからShaka Playerへの置き換えは想定していたよりもサクッとできました。

いざ！高速フレーズ送り！おおおおぉお！
初期再生位置より前のフレーズに高速でフレーズを戻しても、瞬時に再生が再開されました。3つも動画ライブラリを渡り歩きましたが、なんとか納得のいく動画プレイヤーが出来上がりました！🎉

# まとめ

プロダクト開発において、使用するライブラリの選定は重要です。ときには想定していなかった事象にぶち当たり、路線を変更せざるを得ない場合もあります。そのときに頭を切り替えつつ、過去の資産・経験を活かす（ときには全て捨て去る）のは大切だなと感じました。

abceed webはiOS/Androidアプリに比べるとまだまだユーザー数は少ないですが、Web版ではディスプレイなどの大きい画面で映画が見られることもあり、多くのユーザーに使っていただいています。改善しなければならない箇所も多いですが、少しずつ着実に改善を進めています。

今後も、ユーザーにとって使い続けたいなと感じてもらえるプロダクト開発を続けていきます。