• GiNZA v3.0の拡張固有表現抽出を試してみた 【自然言語処理】

    2020-01-27 20:30

    自動でキーワードの分類ができます。

    ---- SKA’s blomaga written on 2020/01/27 ----

    はいみなさんこんにちは。SKA’s blomagaへようこそ。この記事は次の動画のテキストバージョンになります。動画を見れる環境の方は動画をオススメします。また,今日のソースコードはGitHubにて公開しています。

    前置き

    1/15に日本語の自然言語処理ライブラリー「GiNZA」のversion 3がリリースされました。

    自然言語処理のタスクで「固有表現抽出」と呼ばれる,キーワードを引っ張ってくるみたいな課題があるのですが,GiNZAのバージョン2では「組織名・人名・地名・日付・時間・金額・割合・製品名」の8つの分類しかなかったのですが,バージョン3ではこんなに(参照:関根の拡張固有表現階層)分類が増えたそうです。

    ということで,今日はGiNZAのバージョン3の固有表現抽出機能をレビューしていきたいと思います。ちなみに,GiNZAはリリースされてからまだ1年も経ってないんですが,MITライセンスで商用利用も可能ですし,開発も活発なので,今後日本語の自然言語処理を応用したサービスも盛り上がっていくのではないかと期待しています。

    ---- SKA’s blomaga ----

    試してみた

    はいということで,文字を入力するとGiNZAを使って固有表現を抽出してくれるWebアプリを作ってみました。

    GiNZAはフロントに欧米で有名な「spaCy」という自然言語処理ライブラリーを使っているので,「displaCy」という,特に複雑なコードを書かなくてもいい感じに表示してくれる機能もあります。

    では例文として

    1月18日,19日にラブライブ!フェスがさいたまスーパーアリーナで行われた。μ's,Aqours,Saint snow,虹ヶ咲学園スクールアイドル同好会の4グループ,計29人が出演し,ラブライブ!9周年を祝った。μ'sがSnow halationを披露した後,Aqoursの伊波杏樹さんがあまりの感動に言葉を詰まらせ「ラブライブ!が大好きです」と言ったところは特に感動した。もう1度μ'sが見れてとても嬉しかった。

    というのを入れてみましょう(ラブライブ!フェスに関する個人的な感想です)。

    こんな感じに出ました。分類が怪しいところですが,まあいい感じにキーワードが拾えているのではないでしょうか。

    CaboChaからの移行

    ちなみに今までCaboCha使っててGiNZAに切り替えるのが面倒くさそうと思うかもしれませんが,ginzaというコマンドが付いていてCaboCha互換形式にもできるので,わりと簡単です。

    では試しにCaboCha向けに作った固有表現をハイライト表示するアプリをGiNZAに差し替えて動かしてみましょう。

    はい,呼び出しコマンドをcabochaからginzaに変えただけですが動きました。さっきと同じく細かい分類なのでGiNZAが使われているのが分かると思います。

    まとめ

    はいということで,GiNZA version 3の拡張固有表現抽出を試してみました。まだ例文1つでしか試してないので,どのくらいの精度なのか分かりませんが,ひとまず細かい分類で固有表現を抽出できることを確認しました。

    固有表現抽出はチャットボットやプライバシー保護,文書要約などに使われる要素技術ですが,細かい分類になったことで,それらがより精度や効率が上がると思います。

    ちなみに,この分類は見て分かる通り(参照:関根の拡張固有表現階層)階層構造になっているので,後処理は必要になりますが,従来バージョンの荒い分類として扱うことも可能です。

    ということで今日の動画(ブロマガ)は以上です。もし良かったらコメント等してみてください。ではまた!

    おまけ

    【おまけ画像:わーすた に関する自分なりの紹介文】

    はい おまけです。遅くなりましたが,2020年初動画でした。昨年末の動画やTwitterで言っていたとおり,今年はICT・AI・映像技術・ガジェットをテーマに動画制作やっていくのでよろしくお願いします。今日はその第1歩ということで,AI系のソフトの紹介をしてみました。自分の今までもそうですし,YouTube・ブロマガ全体としてもハードの紹介動画の方が多いなってことで,ソフトの紹介をしてみました。今後もAI関連や映像関連のソフトの紹介もたまにやっていきたいと思いますので,よろしくお願いします。ではまた!

    今日のリンク

    おまけの例文に関連して……

  • 広告
  • 動画生配信サーバーを作ってみた【前編】〈Debian 10,Nginx,FFmpeg,Red5〉

    2019-11-14 20:30

    動画生配信サーバー作るためにLinuxをセットアップします

    ---- SKA’s blomaga written on 2019/08/14 edited on 2019/11/14 ----

    はいみなさんこんにちは。SKA’s blomagaへようこそ。
    前回からえらく時間が空いてしまって申し訳ありません。当初予定していたnginx-rtmp-moduleを使った生配信では配信終了できない問題(XSplitで配信終了してもRTMPが閉じない問題)が起きたため,試行錯誤していたら時間が経ってしまいました(←だとしても1か月前には投稿できていた)。
    てことで今日はですね,「お盆休みの自由研究」と題した自宅鯖&Webアプリ開発日記の続きです。今回のテーマは「Debian 10をインストールしてNginxとFFmpegで動画・生配信サーバーをセットアップしよう前編」(次回は前回作ったプレイヤーで再生してみよう)って感じで,Linuxをセットアップしていきます。本当は最後までを1つの記事にする予定でしたが,目的は同じでもやることはかなり違うので分けました(前編の分は8月中に作業終わってました。さっさと投稿すればよかったですね)。

    概要

    • Debian 10(GNU/Linux)をインストールします
    • サーバー向けにセットアップをしていきます
    • Nginx(Webサーバー)を rtmp-module込みで ビルドします
    • FFmpeg(マルチメディアフレームワーク)をビルドします
    • Red5(RTMPサーバー)をインストールします
    • Nginxのセットアップをします(次回)
    • Red5のセットアップをします(次回)
    • 試験放送してみます(次回)

     前回の最後に書いたとおり,今回は詳しいやり方まで書きません。こうやったという流れと,詰みポイントをメインに書いていきます。対象はやや上級者向けになりますが,ご了承ください。

     とはいっても,Linux系一切触ったことない人だと↑が異世界語にしか見えないかもしれないのでほんとに軽く説明しておきます。

    • Debian:いわゆるLinux系と呼ばれるフリーのOS(ディストリビューション)です。
    • Nginx:フリーでオープンソースなWebサーバーアプリです。
    • ビルド:ソース(プログラミング言語)から機械語に翻訳し,コンピューターで実行できるようにすることです。
    • FFmpeg:コマンドラインで使える万能なマルチメディアの編集・変換ソフトです。
    • Red5:RTMP(Flashを使ってリアルタイムに映像やテキストをやりとりするプロトコル)のサーバーです。

     ちなみに,配信方式としては

    1. 当サーバーはRed5がRTMPを待ち受ける。
    2. 配信者はXSplit BroadcasterやOBS StudioからRTMPで当サーバーに配信する。
    3. Red5は動画を受信したらFFmpegを呼び出す。
    4. FFmpegはHLS(HTTP Live Streaming)方式に分割・変換し,Nginxの領域に配置する。
    5. NginxはHTTPを待ち受ける。
    6. 視聴者はブラウザーから当サーバーに動画を要求する。
    7. Nginxは動画を返す。



    という感じになります。
    それでは作業していきます。

    Debian 10のインストール

    ※ 普段使わないPCにインストールする前提で進めます。デュアルブート(普段使ってるWindowsやmacを残したままLinuxもインストール)にする場合,機種や操作によっては元のOSが消える可能性がありますので,ご注意ください。普段使うPCにインストールしたい場合,VirtualBoxやVMware等の仮想環境をオススメします。なお,2019年現在,Windows Subsystem for Linuxでは今回やることができませんので別の方法でお願いします(今後変わる可能性はあります)。

     今回は先月(2019年7月)にリリースされたばかりのDebian 10でサーバーを構築していきます。Ubuntuでも全く問題ありませんが,Ubuntuは標準のままある程度使えるようになっている代わりに,逆に標準で付いてくるソフトがカスタマイズされてて分かりづらいので,私はUbuntuのもとになっているDebianの方が好きです。あと,私はGUI信者なのでデスクトップ環境GNOMEを入れますが,コマンドラインの方が好きな方はコマンドラインでどうぞ。

    それでは準備はできましたか? 始めていきます。

     まず,Debianのサイトのダウンロードページ(https://www.debian.org/distrib/netinst)からインストールディスクをダウンロードします。インストールのCPUに合わせてamd64,arm64,……などを選んでください。PCで一般的なIntel系のCPUならamd64です。

     次に,ダウンロードしたインストールディスクをUSBメモリーやDVDに書き込みます。ISOイメージなのでDVDの場合特に問題ないと思います。USBメモリーに書き込む場合,Windowsの場合Win32DiskImagerがオススメです。macの人はWeb検索すれば出ると思うので頑張ってください。

     その次に,USBメモリーなりDVDなりからDebianインストーラーを起動(ブート)します。そこに関してはPCの機種によって違うので自分で調べてください。ちなみに私はMac miniに入れました。Macの場合は起動時にcommand+optionを押します。

     Debianインストーラーが起動できれば後は画面の指示に従っていけば,迷うことなくインストールできると思います。まあ,インストール先のディスクに関する部分はある程度知識がないと理解できないと思いますが,そこは申し訳ありませんが,他サイトで勉強してきてください(もちろん,自動でいい感じにやってくれるオプションもあります)。

     最後の方で,デスクトップ環境が選べます。私はGNOME 3にしましたが,お好みのデスクトップ環境を選んでください(もちろんデスクトップなしでコマンドラインオンリーでも構いません)。個人的にはGNOME 3が一番見やすいかなと思います(macに近いところも多いし)。

    ていう感じで,インストールできましたよね?

    Debianのセットアップ

     先程も言いましたが,Ubuntuは初期装備でもある程度使えますが,Debianはわりと初期装備少なめです。なので,必要なものや,趣味のものを入れてしまいましょう。

     まず,最初にDebianインストール時に作成したアカウントをsudoers(管理者権限コマンド実行可能アカウント)にします。
    ターミナルで「su -」と入力し,root(管理者アカウント)でログインします。そして「visudo」コマンドで作成したアカウントをsudo可能にしてください。「sudoの権限を設定するvisudoコマンド【Linuxコマンド集】 - エンジニアの入り口」とかを参考にすると良いです。

     それではいろいろとセットアップ・インストールしていきます。特筆しないものに関してはターミナルで「sudo apt install ほげほげ」と入力することでインストールできます。プロキシー環境の方は以下のプロキシー設定をした後にインストール時は「sudo -E apt install ほげほげ」とsudoコマンドに-Eと引数を付けてください(-Eは環境変数を読み込んでくれるオプションです)。
    また,最近のDebianではapt-getではなくapt推奨なので,ググる・ヤフるときは適宜置き換えてください。
    ちなみにaptでインストールできるかだったり名前だったりは「Debian -- Packages」を使うと便利です。
    私は以下のような感じで設定しました。先程の「ほげほげ」に下の( )内の名前を入れてください。

    • (プロキシー環境の場合)プロキシーの設定
      基本的には環境変数「https_proxy」と「http_proxy」だけ設定すれば良いと思いますが,うまく行かない場合は
      社内Proxyに阻まれていろいろ捗らない人のためのTips - Qiitaとかを参考にいろいろやってみてください。
    • Vim (vim)
      コマンドラインで使うテキストエディターです。
    • UFW (ufw)
      ファイアウォール(パケットフィルタリング)です。インストール後「sudo systemctl enable ufw」と「sudo systemctl restart ufw」と「sudo ufw enable」で有効化してください。今回使用する内向きのTCP 80,443,1935番ポートは開く設定にしてください。いつかufwの使い方記事も書きます。
    • Mozc (ibus-mozc)
      Google発オープンソースの日本語入力(漢字変換)です。
      JISキーボードを使っている場合「ibus-mozcのキーボードレイアウトが英語になるトラブルの対処法 - クロの思考ノート」を参考に設定してください。
    • 各種日本語フォント
      • M+ 1P (fonts-mplus)
      • Noto Sans CJK JP (fonts-noto-cjk)
      • IPAゴシック (fonts-ipafont)
      • モトヤシーダ (fonts-motoya-l-cedar)
      あたりから好きなフォントをインストールすればいいと思います。私はかの有名なフリーフォントM+ 1Pを標準にしました。標準フォントはGNOME環境の場合「GNOME Tweaks」で変更できます(日本語使う人は変更推奨)。Noto Sans CJKはGoogleとAdobeが作ったフリーとは思えないクオリティーのフォントで現在の純正Androidの標準フォント。IPAは名前のとおりセキュリティーや情報処理技術者試験でお世話になる某独立行政法人とタイプバンクさんのフォント。特に特徴はない。モトヤは漢検のフォントも担当している大阪の印刷会社で,モトヤシーダは地図マピオンやAndroid 4で採用されています。「永遠に伝えたい、美しく格調高いモトヤ書体。」 わりと好き。あ,すみません,箇条書きの中なのにフォントについて熱く語ってしまいました。
    • (GNOMEの場合) Dash to Dock
      GNOME 3のShell extensions(拡張機能)です。背景画像以外何もないデスクトップにドックを追加します。
      aptではなく,Firefoxに拡張機能GNOME Shell integrationを入れ,そこからインストールします。プロキシー環境の方は詰みます。
    • htop (htop)
      システムモニタリングツールです。
    • fancontrol (fancontrol)
      PCのファン制御をします。機種によってはファン制御をOSに任せるので,Linuxを入れてから負荷によらずファン速度が一定になる場合は自己責任で入れてみてください(失敗すると最悪オーバーヒートします)。使い方はこちら(Ubuntu PWMファン制御 その1 - 概要とインストール・設定ファイルを作成する - kledgeb)とかどうでしょうか(他人任せ)。
    • NTP (ntp)
      時刻サーバーと同期します。こちらもインストール後「sudo systemctl enable ntp」で有効化させましょう。ネットワーク管理の厳しい環境の方は設定ファイル「/etc/ntp.conf」を書き換えて適宜NTPサーバーの指定とかしましょう。
    • (Debianインストール時にやっていない場合)swap領域の作成
    • FileZilla (filezilla)
      GUIでSFTPが使えます。普通にサーバー専用機にする場合は入れなくていいです。
    • cURL (curl)
      何かで必要になったはずですが忘れました。まあ今後いろいろと必要な場面が出てくるので入れておいて損はないです。
    • rsync (rsync)
      ファイルを同期します。ユーザーのディレクトリーで編集したWebページをサーバーに配置する際に使います。
    • リモートデスクトップする場合,好きなVNCサーバーを入れてください(執筆時点でWayland対応のVNCサーバーが見つからなかったので難しいかもしれません)。← ここらの問題についてはまたいつか記事にしたいと思います。

     ここで一旦Q憩(好きなもの入れてね)。
    私は「ls=ls -l --color=auto」のエイリアスを~/.bash_rcに書いて,Audacity,GIMPといった定番ソフト,Blender,Shotcutも趣味で入れました(最後2つは絶対使わないと思う)。そして,GIMPで背景画像用に画像加工して,好きな背景画像をセットしました。

    Nginx とrtmp-module をビルドします

     まずは引き続きNginx とrtmp-module に必要なものをインストールしていきます。以下すべて「sudo apt install ほげほげ」というコマンドで入れていきます。下に( )がないものは そのまま入れてください。

    • Git (git)
    • GCC (gcc)
    • OpenSSL (openssl)
      ※ 入ってたのでおそらく入れる必要なし
    • libpcre3-dev
    • libssl-dev
    • zlib1g-dev
    • build-essential

     次に,Nginx とrtmp-module をダウンロードし,ビルドしていきます。
    またまた他人任せですが,「nginxでストリーミングサーバを立ててライブ配信する。 - Qiita」の「インストール・設定」の項目を参考に作業していくとNginxがインストールできます。

     その次に,Nginx公式サイトの「NGINX systemd service file | NGINX」を参考に,テキストエディターで「/lib/systemd/system/nginx.service」というファイルを作り,リンク先に書いてある内容をコピーして保存してください。
    いちおうGNOME環境の初心者向けに言うなら「sudo -E gedit /lib/systemd/system/nginx.service」というコマンドを打てばいいと思います。
    自分もはまってしまいましたが,「systemd」の中にさらに「system」があるので間違えないようにしましょう。

    FFmpegをビルドします

     基本的に公式Wikiの通りにコマンドを打てば今回の用途としては問題ありません。ただし,さきほど書いたように「apt-get」は「apt」に置き換えてください。いちおう全く英語が読めない人に向けて補足するなら,まずWikiのTipにも書いてありますが,「make」コマンドは引数-jを付けて「make -j4」のように置き換えてください(数値はCPUのコア数にするのがオススメ ←分からなければ数値なしでもおk)。次に各項目(モジュール)の「sudo apt」で始まる1行のものか「cd ~/」で始まる複数行のコマンドはどちらか片方を選択して実行してください。見れば分かると思いますが,1行の方はaptからインストールし,複数行の方はそれぞれのモジュールも自分でビルドします。

     Wikiのとおりに作業すると,ユーザー領域にビルドしたFFmpegが置かれるので,他のユーザーからも使えるようにシンボリックリンク(ショートカットのようなもの)を作ります。次のような感じでコマンドを打ちます。
    ※ 「現在のディレクトリー $ 入力コマンド」の形式で記載しています。

    $ cd ~/bin/
    ~/bin $ sudo ln -s ./ffmpeg /usr/local/bin/ffmpeg
    ~/bin $ sudo ln -s ./ffplay /usr/local/bin/ffplay
    ~/bin $ sudo ln -s ./ffprobe /usr/local/bin/ffprobe

    Red5をインストールします

     Red5はJavaで書かれているので,まずはJDKが必要となります。お好きなJDKをインストールしてください(Javaには詳しくないので割愛します ググるなり ヤフるなり ビンるなり Siriるなり Alexaるなり してください)。

     次にRed5をダウンロードします。ターミナル(端末アプリ)を起動し,次のような感じで行いました。

    ~ $ mkdir ./temp-red5
    ~ $ cd ./temp-red5/
    ~/temp-red5 $ wget https://github.com/Red5/red5-server/releases/download/vx.x.x/red5-server-x.x.x.tar.gz
      yyyy-mm-dd hh:mm:ss (1.35 MB/s) - ‘red5-server-x.x.x.tar.gz’ saved [49082226/49082226]
    ~/temp-red5 $ tar -zxf ./red5-server-x.x.x.tar.gz
    ~/temp-red5 $ sudo mv ./red5-server /usr/local/
    ~/temp-red5 $ cd /usr/local/red5-server/
    /usr/local/red5-server $ sudo chown root:root ./*
    /usr/local/red5-server $ sudo ./red5.sh
    • Red5のバージョン(red5-server-の後など)はx.x.xに置き換えています。適宜最新版のバージョンに置き換えてからコマンド実行してください。というか,GitHubのReleasesを見て,wgetの後のURIはコピペすればいいと思います。その後のファイル名もTabキー押してシェルの補完機能使えばいいと思います。
    • 日付・時刻等もyy (ryに置き換えています。
    • 所有者をrootに変えていますが,私もLinuxやサーバー周りの経験は浅いので,賛否等あればコメントくれるとありがたいです。

    動作確認

     まだ設定等はしていませんが,インストールが完了したということで,とりあえず動作確認してみましょう。

    1.Nginx

     次のようにコマンドを打って,Nginxを開始し,状態を確認します。

    ~ $ sudo systemctl restart nginx
    ~ $ sudo systemctl status nginx/

    結果が次のようにactive (running)と出れば問題ありません。

     nginx.service - The NGINX HTTP and reverse proxy server
    Loaded: loaded (/lib/systemd/system/nginx.service; disabled; vendor preset: enabled)
    Active: active (running) since xxxx

    まだちゃんと設定してないので動作確認が終わり次第「sudo systemctl stop nginx」でNginxを止めてください。

    2.FFmpeg

     ffmpegとコマンドを打って,次のような感じのメッセージが出れば問題ありません(↓は違うビルドの物なので細かいところは変わってくると思います)。

    ~ $ ffmpeg
    ffmpeg version x.x.x Copyright (c) 2000-2019 the FFmpeg developers
    built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
    configuration: --prefix=/usr/local/Cellar/ffmpeg/x.x.x --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
    libavutil 56. 22.100 / 56. 22.100
    libavcodec 58. 35.100 / 58. 35.100
    libavformat 58. 20.100 / 58. 20.100
    libavdevice 58. 5.100 / 58. 5.100
    libavfilter 7. 40.101 / 7. 40.101
    libavresample 4. 0. 0 / 4. 0. 0
    libswscale 5. 3.100 / 5. 3.100
    libswresample 3. 3.100 / 3. 3.100
    libpostproc 55. 3.100 / 55. 3.100
    Hyper fast Audio and Video encoder
    usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

    3.Red5

    ~ $ cd /usr/local/red5-server/
    /usr/local/red5-server $ sudo ./red5.sh

    とコマンドを打って,ここに書ききれないくらい大量に文字が出てくれば問題ないと思います(?) 

    Q&A

    Q1:ニコ生とかYouTube Liveでよくない?

    A1:大抵の人はニコニコやつべでいいと思います。ただ,今回はあくまで趣味なのでダメです。あとはネットワークが厳しくて,RTMPがブロックされてる環境だったり,ネット上に公開できないコンテンツを特定少数に見せたいとか,そういうときにも使えると思います。あとはニコ厨だったりして,どうやって映像が流れてくるんだろうかって知りたくなった人とかも,実際に自分で配信サービスを立ててみるっていうのは理解の助けになると思います。


    -------- SKA’s blomaga --------

     はいということで,前回のクライアント側とは逆にサーバー側をセットアップしていこう(前編)ということでしたが,どうだったでしょうか。次回はNginxの設定ファイルを書いたり,FFmpegを使ってコマンドラインで動画の変換をしてみたり,Javaでプログラミングしたりします。お楽しみに。ではまた!

    今日のリンク と 参考文献

    • お盆休みの自由研究その0「お盆休みの自由研究と題して自宅鯖&Webアプリ構築するお(2019)」:ar1798085
    • お盆休みの自由研究その1「hls.jsでお手軽 動画・生配信視聴プレイヤー作ってみた」:ar1798847
    • SKAのニコニコ動画
    • SKAのTwitter
    • 宣伝:最近の動画です。
    • 各種参考文献は本文中にあります。
  • hls.jsでお手軽 動画・生配信視聴プレイヤー作ってみた 【お盆休みの自由研究2019その1】

    2019-08-12 19:00

    この記事はわりと細かいことまで書いていて長いです。時間のない方や,もうすでに知ってるわって人は飛ばし飛ばし読んでください。対象レベルはWebや動画に関して最低限の知識はあるけど,実際に作ったことはあまりない人程度にしたつもりです。

    簡単お手軽 低遅延な動画・生配信視聴プレイヤーです。

    ---- SKA’s blomaga written on 2019/08/12 ----

    はいみなさんこんにちは。SKA’s blomagaへようこそ。
    てことで今日はですね,「お盆休みの自由研究」と題した自宅鯖&Webアプリ開発日記の1つ目です。今回のテーマ(概要)は「hls.jsを用いて(実用レベルまでは行かないけど)簡単お手軽に低遅延で安定したHLS形式の映像配信視聴プレイヤーを作ってみた」って感じです。

    背景技術

     昔からニコ動とかニコ生とかYouTubeとかやってる人は分かると思いますが,昔(5〜15年くらい前)はWebで動画を流すにはAdobe Flashを用いたHTTPプログレッシブダウンロード(先頭からダウンロードし,ダウンロード終わったところのみ再生可能)が主流でした。生配信は同じくAdobe Flashを用いてRTMP方式(専用サーバー必要)で行っていました。今みたいにブラウザー単体で動画を扱えませんでした。しかし,iPhoneの登場,iOSがFlashをサポートしなかったこと,Flashのセキュリティー問題,さらにHTML5でvideoタグが追加されたこと(ブラウザー単体で動画再生可能に),それでもAdaptive Bitrate(自動画質調整)の付けられないプログレッシブダウンロードを特定の条件でしか再生できないようにiOSがしたことから,現在の動画配信は一般的にHLS(HTTP Live Streaming)形式(ニコ動・AbemaTV等で採用)や,それをより一般化・標準化したMPEG-DASH形式(YouTube等で採用)が使われるようになりました。

     ※ 個人的に長いカタカナ用語は好きではないので,以下 一般的名称ではありませんが,「プログレッシブダウンロード」を「順次ダウンロード」と記載します。また,わかりやすさ重視で「クライアント」を「客」,「サーバー」を「窓口」に見立てている部分があります。

    技術詳細

     順次ダウンロードはPCやスマホの動画再生アプリでPCやスマホ本体の動画を再生するのと同じように動画を先頭から順番にダウンロードしていきます。もちろん1本の動画では1ファイルです。

     しかし,HLSでは図のように10秒程度(Apple推奨値)に動画ファイルを分割します。その動画の順番と時間をプレイリストファイル(拡張子:m3u8)に書いておき,そのプレイリストの通りにファイルを順番にダウンロードしていくことにより再生します。あ,ちなみにニコ動は6秒ごとに分割してますね(2019年8月現在)。

     この方式の利点はたくさんあります。

     まず,先読み時間の制御がしやすく,ムダな通信を避けることができる点。例えば,10分の動画を1分で見飽きたとします。順次ダウンロードではどんどんダウンロードしていくので,8分ぶんダウンロードしてしまうかもしれません。しかし,HLSでは次の3ファイルまでしか読み込まないというようにしておけば,1分30秒ぶんしかダウンロードしていないわけです。これによりサーバー負荷もモバイルの通信量も抑えることができます。(逆に動画をダウンロードして保存したいときは時間もかかるし結合が面倒)

     次に,アクセスログにより簡単にユーザーの視聴時間が分かる点。例えば,先程の例だと9ファイル読み込まれて3ファイルは先読みなので実際に再生したのは6ファイル分で,時間にすると60秒という具合です。おそらくYouTubeはこの仕組みで視聴時間を算出し,広告料の配分をしていると考えられます。

     さらに,通信速度により最適な画質に調整できる点。先程の図のように,プレイリストのプレイリストを作ることができます。そこには「このプレイリストを使うとこのくらいの画質」ということが書いてあります。客側(ブラウザーやアプリ)が「やっべw この通信速度だと先読み3ファイルも用意できねえわwww」と判断すればサーバーに低画質の動画ファイルを要求して,「なにこの回線! 先読み一瞬で終わるんだが。たっのしー!」と判断すれば高画質の動画ファイルを要求するって感じです。つまり,客側が判断するだけで,無能お役人(一般的なWebサーバー)でも,自動画質調整ができてしまいます。

     そして,動画(オンデマンド)だけではなく,生配信(ライブ)すら無能な役人(一般的なWebサーバー)で対応可能です(10秒ごとに新しい動画ファイルが追加されて,プレイリストが更新されて,そのあとすぐにが来るので役人目線だと「普段より忙しいな」って感じでしょうか)。ただし,もちろん動画・生配信ともに約10秒ごとに動画ファイルを分割する他サーバーやアプリの協力は必要です。

    という感じに,HLS(あるいはMPEG-DASH)は現代の動画配信においてかなりメリットがあると思います。

    もちろんそのままブラウザーで再生できるんでしょ?

    いいえ! というと語弊があるかもしれませんが,Microsoft Edge(2019年現在,Chromium系になる前)とSafariは優しさ設計でvideoタグでHLSのプレイリストを指定してやれば,そのまま再生できてしまいます。が,Mozilla FirefoxやGoogle Chromeは未対応です。

    てことで,やっと本題です。OSがWIndowsでもmacでもAndroidでもiOSでも,ブラウザーがChromeでもFirefoxでも問題なくHLS形式で再生できるプレイヤーを作りましょう。

    やり方

     と言っても,やり方はいくらでもあります。自分で1からJavaScriptで実装しても良いですし,jQueryとかで頑張っても良いですし,video.jsというHLSに対応したJavaScriptの動画プレイヤーのライブラリーもすでにあります。ですが,今回はHTML5のvideoタグで色々なブラウザーでHLSを扱うことができるようになるライブラリー「hls.js」を使います。

     実は私は以前video.jsを使っていたのですが,パフォーマンスに問題がありました。まれにコマ落ちが発生したり,生配信の遅延が大きかったりなどです。それで,WebVTTによる章分け(チャプター)機能や,字幕機能にも対応していて,UIまで用意されていて圧倒的手軽さで実用的なvideo.jsですが,使うのはやめて,別のライブラリーを探してました。

     そして,見つけたのがhls.jsです。hls.jsはvideo.jsみたいにUIを持たず,本当にvideoタグでHLS形式の動画を読み込ませるだけです(自動画質調整はしてくれますが)。ですが,HTML5に対応している一般的なブラウザーはブラウザー自体が動画用のUIを持っているので,それを使えばシークや一時停止などは可能になります。また,自分のUIを使いたいのであれば,それこそ1から書いたり,jQueryでも使えばいいだけなので,hls.jsで全く問題ないと判断しました。

    では実装していきましょう。雰囲気を出すためにBGM用に てってってー を貼っておきます。

    実装

    前準備

     まず,今回作るお試しサイトのディレクトリー(フォルダー)構造を作っていきます。今回は以下のような構造にしましたが,まあお好みで。

    test-video-site/
      ├ js/
      | ├ hls.js
      | └ set-video.js
      ├ videos/
      | ├ hls/
      | | ├ video1.m3u8
      | | ├ video1-00000.ts
      | | ├ video1-00001.ts
      | | ├ video1-00002.ts
      | | └  …… 
      | └ video1.html
      ├ index.html
      ├ icon.ico
      └ style.css

    hls.jsは特にダウンロードせずにCDNの利用をオススメしますが,CDNを利用したくない場合GitHubの https://github.com/video-dev/hls.js/ からダウンロードするなりクローンするなりして,上のとおりjsディレクトリーにでも入れてください。

    icon.icoとstyle.cssはテキトーに用意してください。アイコンはGIMPとかで作成できます。スタイルはお好みで。別に作らなくてもいいです。index.htmlはvideo1へのリンクが貼ってあるページという想定ですが,なんでもいいです。テキトーに用意してください。
    これ以外のファイルについてはこれから順番に用意していきます。

    ちなみに,自動画質調整に対応させるならvideosの下のhls以下を次のようにします(ここもお好みで)。

    hls/
    ├ hd/
    | ├ video1-hd.m3u8
    | ├ video1-hd-00000.ts
    | ├ video1-hd-00001.ts
    | ├ video1-hd-00002.ts
    | └  …… 
    ├ sd/
    | ├ video1-sd.m3u8
    | ├ video1-sd-00000.ts
    | ├ video1-sd-00001.ts
    | ├ video1-sd-00002.ts
    | └  …… 
    └ video1.m3u8

    動画の準備

     上の方で解説したとおり,HLS形式の動画は10秒程度に分割したファイルを用います。分割に使うソフトは何を使っても良いですが,私はFFmpegを用いています。
    ただし,FFmpeg自体はフリーですが,商用利用でエンコードされる場合MPEG-LAとのライセンス契約が必要かと思われますのでご注意ください。
    FFmpegは自分でビルドすることをオススメしますが,時間がかかるのと,分割だけの場合 配布版で全く問題ないので,そこもおまかせします。

     次に,シェルでFFmpegが入っているディレクトリーに移動します。
    Linuxの人は自力で頑張ってください(シェルやデスクトップ環境によって違うので)。
    macの方はFinderでFFmpegが入っているフォルダーに移動し,ターミナルを起動し,「cd 」(最後は半角スペース)と打ったのち,Finderの一番上(赤丸 黄色丸 緑丸と同じy座標)のフォルダーマークをターミナルにドラッグアンドドロップして,文字が入ったらreturnキーを押します。
    WindowsではエクスプローラーでFFmpegが入っているフォルダーを開き,Shiftキーを押しながら右クリックすると「PowerShellでここを開く」的なメニューがあるので(日本語版Windows使ってないので正しい名称は分かりません),それを押します。

    ※ 以下 元の動画が,映像コーデックが「H.264」,音声コーデックが「AAC」であるという前提で進めます。

     その次に,自動画質調整しない場合は

    ./ffmpeg -i "(動画のパス)" -c:v copy -c:a copy -segment_format mpegts -hls_time 9.0 -break_non_keyframes 0 -hls_list_size 99999 -hls_segment_filename "(test-video-siteまでのパス)/test-video-site/videos/hls/video1-%05d.ts" "(test-video-siteまでのパス)/test-video-site/videos/hls/video1.m3u8"

    と入力しreturn(Enter)キーを押します。
    ただし,Windowsの場合,「ffmpeg」を「ffmpeg.exe」に置き換え,「/」(スラッシュ)を「\」(バックスラッシュ)に置き換えてください。場合によってはバックスラッシュが円記号(¥)に見えることがありますが,それはWindowsのクソ仕様なので無視してください。

    このコマンドの意味は
    このディレクトリーの「ffmpeg」を次の引数をとって実行します。その引数は入力ファイルが(動画のパス)で,映像コーデックはコピーして(再エンコードしない),音声コーデックもコピーして,分割後の形式(コンテナ)はMPEG-2 TSで,分割時間は9.0秒ごとで,「キーフレーム(Iフレーム)で分割しない」をオフ(0)にして,プレイリストの最大数は99999で,分割後のファイルは「(test-video-siteまでのパス)/test-video-site/videos/hls/video1-%05d.ts」として保存して,プレイリストは「(test-video-siteまでのパス)/test-video-site/videos/hls/video1.m3u8」として保存します。
    って感じです。
    分割時間は再エンコードなしで,「break_non_keyfreames」を0にすると,記載した時間よりも多少長めで分割されるので10.0ではなく,9.0を指定しています。分割後ファイル名には「%○○d」といった感じに数字のフォーマットを指定できます。%05dは0埋めあり(001みたいに先頭に0を付ける)の5桁の整数となります。

    よく分からない方はこのままお使いください。詳しい方は自分好みにカスタマイズしてご利用ください。

    自動画質調整する場合は映像をリサイズして再エンコードして,別ファイルに保存すればおkです。コマンドは…… メモしてたファイルをコピーし忘れてて今手元にないので,数日後更新して記載しておきます。

    set-video.jsの作成

    ※ set-video.jsという名前じゃなくても大丈夫です。

    hls.jsの機能を利用して,videoタグでHLSを読み込ませるset-video.jsと名付けたJavaScriptプログラムを書いていきます。AtomでもVS CodeでもJetBrainsさんのでも何でも良いですが,テキストエディターを起動して,test-video-siteのディレクトリーを開いて,「js」ディレクトリーに「set-video.js」というファイルを作成します。
    書く中身は先程の hls.jsのGitHub を参考に(本家とは少し違います)次のように書けばおkです。

    function setVideo(path)
    {
    var video = document.getElementById("video");
    if(video.canPlayType("application/vnd.apple.mpegurl"))
    {
    video.src = path;
    return;
    }
    if(Hls.isSupported( ))
    {
    var hls = new Hls( );
    hls.loadSource(path);
    hls.attachMedia(video);
    }
    return;
    }

    説明するまでもないと思いますが,軽く説明しておくと,
    次のような「path」を引数にとる関数setVideoを定義します。videoという変数にHTMLで「video」というIDが付与された要素を格納して,もしブラウザーが直接HLSを再生できれば,videoのsrc属性をpathにします。もしブラウザーがMSEに対応していれば(hls.jsの動作条件),hlsという変数に(hls.jsで定義されている)Hlsクラスのインスタンスを格納し,pathを読み込み,videoに結びつけます。(ブラウザーがMSEにもHLSにも対応していない場合 何もしません)

    video1.htmlの作成

     では次に,実際に動画を表示するHTMLを書いていきます。同じくテキストエディターで「video1.html」を作成します。中身はこんな感じです。「(○○)」「(ほげほげ)」は好きな文字に置き換えてください。

    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="shortcut icon" type="image/vnd.microsoft.icon" href="../icon.ico" />
    <link rel="stylesheet" type="text/css" href="../style.css" />
    <!-- hls.jsをCDN経由で用いる場合 -->
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
    <!-- hls.jsをダウンロードして用いる場合 -->
    <!-- <script src="../js/hls.js"></script> -->
    <script src="../js/set-video.js"></script>
    <title>(ほげほげ)</title>
    </head>
    <body>
    <h1>
    (動画タイトル)
    </h1>
    <p>
    (動画説明)
    </p>
    <video id="video" controls preload="metadata" width="854" height="480">
    <p>
    ご利用のブラウザーは当サイトの動画に対応していません。申し訳ありませんが,別のブラウザーソフトをお試しください。
    </p>
    </video>
    <script>setVideo("./hls/video1.m3u8");</script>
    </body>
    </html>

    って感じで,簡易的な動画サイトみたいな感じになります。videoタグの中身については,setVideo関数内でvideoというIDのついた要素を取得するようにしていたため,id="video",hls.jsは動画制御用UIを持たないので,ブラウザー内蔵のUIを用いるためcontrols,私は自動再生絶対許さないマンなのでpreload="metadata"(メタデータのみ先読みする),width(幅)とheight(高さ)はお好みの値で(動画の解像度に合わせる必要ありません)って感じですね。もしかしたら(もしかしなくても),widthとheightはvideoタグ内よりもCSSで指定した方がいいかもしれませんね。
    ちなみに,viewportの設定で,スマホを縦画面にしても表示が小さくならないようにしています。

    Webサーバーへの配置

     では最後に,Webサーバーへ配置しましょう。ファイルをブラウザーで直接開く場合,hls.jsが正しく動作しないことがあります。なので,HTTPかHTTPSのサービスをしているサーバーのところへ配置しましょう。
    サーバーのセットアップは次回の予定なので,今回は省略します。

    基本的にWebサーバーのドキュメントルートのディレクトリーにtest-video-siteディレクトリーの中身をコピーして,権限を変更すればおkです。

    だいたいこんな感じで終わりです。さっき てってってー を流した方はここで止めてください。

    動作確認

     ブラウザーを起動して,アドレスバーにWebサーバー上の「index.html」か「video1.html」のURIを入力してみましょう。正しく再生できましたか? ちなみに私はこのプレイヤーでGOP&分割時間0.5秒の生配信を視聴したら遅延時間が2〜4秒程度でした(LAN内でFirefoxの場合。Chromeはもう1秒程度遅れる感じでした)。コマ落ちも今のところ確認できていません。インターネット(WAN)上ではまだ試していませんが,パフォーマンスは良さそうです。


    -------- SKA’s blomaga --------

    はい,というわけで,今回はhls.jsを用いてお手軽なHLS形式の動画・生配信視聴プレイヤーを作ってみたってことで,いろいろと説明しました。
    さすがに長々と詳しく書きすぎて,これ書くのに丸1日かけてしまって,進捗0なので,次回からは簡潔に書いていきます。対象がやや上級者向けになるかもしれませんが,ご了承ください。そもそも内容も難しくなるので,そこは割り切ってしまおうと思います。

    また,今回の記事は私がやったことをベースに書いていますが,実際に私がやったこととは多少変えて書いています。そのため,間違っている部分があるかもしれません。何か間違いに気づいたり,この通りにやったのに動かないとかあればコメントお願いします。

    次回は「LinuxとNginxとFFmpegで動画配信サーバーを作ってみた」です。お楽しみに。 ではまた!

    今日のリンク と 参考文献

    • お盆休みの自由研究その0「お盆休みの自由研究と題して自宅鯖&Webアプリ構築するお(2019)」:ar1798085
    • お盆休みの自由研究その2「LinuxとNginxとFFmpegで動画配信サーバーを作ってみた」:(まだ書いていません)
    • プリパラ5周年 一挙放送 lv321267111 ←作業しながら見てました