【動画配信】HTML5ブラウザのサポート状況チェック MSE編


# はじめに

動画配信サービスを提供していると、カスタマーの問い合わせに悩まされることが多々あります。
手元の環境では再現しない、ログを確認しても大多数は問題なく再生できているように見えるが、特定のカスタマーの環境では再生がうまくいっていないということがしばしばあります。

HTML5ブラウザでのサービス提供の場合、環境依存の問題が多く存在するため、とにかくカスタマーの再生環境の情報を集めることが原因特定に役に立ちます。

本記事では、今回はMSE (Media Source Extensions)部分のサポート状況チェックについてまとめます。

# MSEのコーデックのサポート状況をチェックする

MediaSource.isTypeSupportedを使えば、MSEが映像・音声のコーデックをサポートしているかをtrue/falseで確認できます。
 
```js
if (MediaSource.isTypeSupported(type)){
  // OK
}else{
  // NG
}
```
MDN web docs | MediaSource.isTypeSupported()
https://developer.mozilla.org/docs/Web/API/MediaSource/isTypeSupported

記法としてはこんな感じです。
> {MIME Type}; codecs="{コーデック1, コーデック2, ... , コーデックn}"

例えばH264の映像とAACの音声が1トラックごとのファイルにMUXされてるMP4であれば、こんな感じになります。（プロファイルの話等は省きます。）

```js
if (MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')){
  // OK
}else{
  // NG
}
```

# MPEG-DASH×MP4

Azureメディアサービスが生成するMPEG-DASH×MP4を例に挙げます。
要素AdaptationSetやPresentationの属性に存在するmimeTypeとcodecsを参照すれば、自分たちが提供しているコンテンツの情報を確認できます。

```xml:MPDファイルの例
<?xml version="1.0" encoding="utf-8"?>
<MPD>
    <Period>
        <AdaptationSet id="1" contentType="video" mimeType="video/mp4" codecs="avc1.640028" maxWidth="1920" maxHeight="1080" startWithSAP="1">
            <SegmentTemplate timescale="10000000" media="QualityLevels($Bandwidth$)/Fragments(video=$Time$,format=mpd-time-csf)" initialization="QualityLevels($Bandwidth$)/Fragments(video=i,format=mpd-time-csf)">
                <SegmentTimeline>
                    <S d="20020000" r="100"/>
                    <S d="2002000"/>
                </SegmentTimeline>
            </SegmentTemplate>
            <Representation id="1_V_video_1" bandwidth="1200000" codecs="avc1.4D401F" width="800" height="450"/>
            <Representation id="1_V_video_3" bandwidth="8000000" width="1920" height="1080"/>
        </AdaptationSet>
        <AdaptationSet id="2" contentType="audio" mimeType="audio/mp4" codecs="mp4a.40.2">
            <Label>audioname</Label>
            <SegmentTemplate timescale="10000000" media="QualityLevels($Bandwidth$)/Fragments(audioname=$Time$,format=mpd-time-csf)" initialization="QualityLevels($Bandwidth$)/Fragments(audioname=i,format=mpd-time-csf)">
                <SegmentTimeline>
                    <S d="20201360"/>
                    <S d="20201361"/>
                    (中略)
                    <S d="6269388"/>
                </SegmentTimeline>
            </SegmentTemplate>
            <Representation id="5_A_audioname_1" bandwidth="128000" audioSamplingRate="44100"/>
        </AdaptationSet>
    </Period>
</MPD>
```

例えば、MPDがこんな感じの場合[^1]、以下3件をチェックすれば、このコンテンツの再生がブラウザに搭載のMSEでサポートしているかを確認できます。

* 'video/mp4; codecs="avc1.640028"'
* 'video/mp4; codecs="avc1.4D401F"'
* 'audio/mp4; codecs="mp4a.40.2"'


# HLS×MPEG2-TS

MPEG2-TSの場合、MP4と若干事情が異なるようです。HLSのプレイリストを見ても、コーデックは分かるものの、MIME Typeをどうすればよいか、パッと分かりませんでした。


* 'video/mp2t; codecs="avc1.640028"'
* 'video/mp2t; codecs="avc1.4D401F"'
* 'audio/mp2t; codecs="mp4a.40.2"'

TSだと"mp2t"を指定すれば良さそうなので、MP4の場合を参考にMicrosoft Edgeでこんな値を試してみると、音声だけfalseが返ってきます。

色々調べてみるとMPEG2-TSの場合、音声であってもvideo/mp2tで指定しなければいけないようです。

* 'video/mp2t; codecs="avc1.640028"'
* 'video/mp2t; codecs="avc1.4D401F"'
* 'video/mp2t; codecs="mp4a.40.2"'

こんな風に指定すれば、Microsoft Edgeで音声もtrueが返ってくるようになりました。

# 残課題

手元で前述のMPEG2-TSのサポート状況をChromeやFirefoxで確認すると、falseが返ってきます。
私の場合、ChromeやFirefoxはMPEG-DASHの確認ができれば十分なので問題ないのですが、MPEG2-TSってサポートされていないんでしたっけ？
Chrome, Firefoxに関してはもう少し検討が必要です。

また、記事投稿時点でSafari上での動作確認が取れておりません。

[^1]: MPDの例は説明に関係のない要素・属性を削っています。