ビデオコーデック

OpenTokでサポートされているビデオコーデックについて

OpenTokプラットフォームは、WebRTCプロトコルおよびWebRTCでサポートされているリアルタイムビデオコーデックを活用しています。特に、OpenTokプラットフォームはVP8、VP9、H.264の各ビデオコーデックをサポートしています。

ストリームにはVP8コーデックが使用されます。セッションが属するプロジェクトで優先コーデックを設定していない限り、このコーデックはすべてのクライアントでサポートされています( プロジェクトの推奨ビデオコーデックを設定する.)

OpenTokがサポートする幅広いデバイスやブラウザのエコシステムにおいて、VP8、VP9、H.264といったリアルタイム動画コーデックのサポート状況はさまざまです。 すべてのビデオコーデックに対応しているエンドポイントもあれば、1つのビデオコーデックのみに対応しているエンドポイントもあります。開発中のApplicationsの種類や、エンドユーザーが使用するブラウザやデバイスの種類に応じて、推奨されるコーデックの選択は変わってきます。

ビデオコーデックとは何ですか?

ビデオコーデックは、エンコーダーとデコーダーの2つの部分で構成されています。ウェブカメラから入力されるデジタルビデオフレームを、ネットワーク経由で送信可能なバイナリデータのストリームにエンコード(圧縮)することができます。 また、バイナリデータのストリームを取り込み、それをデコード(展開)して、画面に表示可能な生の動画フレームのストリームに変換することもできます。 ビデオのエンコードおよびデコードを行う仕組みはコーデック規格によって定義されており、本ページでは、広く普及しているVP8とH.264の2つについて解説します。

VP8とH.264の比較

VP8リアルタイムビデオコーデックはソフトウェアコーデックです。低ビットレートでも良好に動作し、 WebRTCの文脈においては成熟したビデオコーデックと言えます。ソフトウェアコーデックであるため、 メモリとCPUの制限の範囲内で、アプリケーションが必要とするだけ何度でもインスタンス化できます。 VP8コーデックは、以下の機能をサポートしています。 OpenTok スケーラブル ビデオ この機能により、対応しているブラウザやデバイスを使用している大規模なセッションでも問題なく動作します。

H.264リアルタイムビデオコーデックは、デバイスに応じてハードウェア形式とソフトウェア形式の両方で利用可能です。WebRTCの文脈では比較的新しいコーデックですが、インターネット経由での映画や動画クリップのストリーミングにおいては長い歴史があります。 ハードウェアコーデックがサポートされている場合、デバイスのコアCPUが動画処理に費やす負荷が軽減され、結果としてCPU負荷が低減されます。ハードウェアインスタンスの数はデバイスによって異なりますが、iOSでのサポートが最も充実しています。 H.264はWebRTCにとっては新しいコーデックであり、デバイスごとに実装が異なる可能性があるため、画質にはばらつきが生じることがあります。 そのため、低ビットレートではVP8と比較してH.264のパフォーマンスが劣る可能性があります。また、H.264はOpenTokのスケーラブルビデオ機能をサポートしていないため、大規模なセッションにはあまり適していません。

VP9とVP8の比較

VP9リアルタイムコーデックは、比較的新しいコーデックです。ブラウザやハードウェア ベンダーの間で、その対応が拡大しつつあります。対応は広がりつつあるものの、他のコーデックほどの普及度にはまだ達していません。

VP9コーデックは、VP8と同様に、H.264よりも低いビットレートで良好に動作します。さらに、VP9は動画のエンコードに、VP8よりもさらに少ない 帯域幅しか必要としません。しかし、この圧縮効率の向上には 代償が伴います。すなわち、エンコードおよびデコードには、VP8よりも多くのCPUリソースが必要となるのです。

VP9コーデックは以下をサポートしています。 スケーラブルなビデオコーディングルーティングセッション.詳しくは ルーティング・セッション用のVP9スケーラブル・ビデオ・コーディング.

プロジェクトの推奨ビデオコーデックを設定する

プロジェクトの「プロジェクト」ページで、そのプロジェクトに使用する推奨ビデオコーデックを設定できます。 Video APIアカウント. 有効な選択肢はVP8、H264、 またはVP9ですが、セッションの種類によって適用可能かどうかは異なる場合があります。デフォルトでは、 すべてのプロジェクトで、優先ビデオコーデックとしてVP8が事前に設定されています。

既存のプロジェクトについては、以下のページにアクセスしてください。 ダッシュボード、プロジェクトを選択し、[ プロジェクト設定, 推奨されるビデオコーデック セクションに移動し、通知の末尾にあるリンクをクリックしてください。

Codec change step 1
In order to change the preferred codec, click the link marked as 'here'.

新しい設定が反映されるまでお待ちください。

Codec change step 2
Preferred Video Codec notification after applying changes.

ルーティングセッション (OpenTok Media Router を使用する セッションの場合)、パブリッシャーは OpenTok Media Router と 使用するコーデックについてネゴシエーションを行い、デバイスが対応している場合は、ユーザーが選択したコーデックを優先します。

リレーセッション, ここで クライアント同士が直接ストリームを送信し合う場合、OpenTok Media Routerは ネゴシエーションに関与しません。各パブリッシング・サブスクライビングのペアは、共通のビデオ コーデックを見つけようと試み、両方のデバイスでサポートされている場合は、ユーザーが選択したコーデックを優先します。

ネゴシエーションの結果、このペアで使用されるビデオコーデックは、プロジェクトで設定された優先 コーデックとは異なる場合があります。

SDKを通じて優先ビデオコーデックを設定する

すべてのモード、ネゴシエーションの挙動、および検証について網羅した包括的なガイドについては、 パブリッシャー優先 Video Codec API を案内する。

Publisher Preferred Video Codec API を使用すると、セッション・ネゴシエーショ ン時のビデオ・コーデックの優先順位を細かく制御できます。 をきめ細かく制御できます。この API を使用すると、次のことが可能になります:

  • ネゴシエーションに影響するコーデックのカスタム優先リストを指定する。
  • 自動モードで優先順位付けをSDKに委ねる。
  • 何も設定していない場合は、プロジェクト設定のデフォルトに頼ってください。

注: このAPIでは、ネゴシエーションの対象となるコーデックに制限を設けていません。プリファレンスリストを設定した場合でも、必要に応じて他のコーデックが使用される可能性がありますが、それらの優先度は低くなります。

ウェブSDK


export type VideoCodec = 'vp8' | 'vp9' | 'h264';
export type PreferredVideoCodecs = 'automatic' | [VideoCodec, ...VideoCodec[]];

// Default (omitted)
OT.initPublisher('div', {});

// Automatic mode
OT.initPublisher('div', {
  preferredVideoCodecs: 'automatic'
});

// Manual priority order
OT.initPublisher('div', {
  preferredVideoCodecs: ['vp9', 'vp8']
});

// Invalid usage (empty list)
OT.initPublisher('div', {
  preferredVideoCodecs: []
}, function (err) {
  if (err) {
    console.error(err.name);    // 'OT_INVALID_PARAMETER'
    console.error(err.message); // 'preferredVideoCodecs must be "automatic" or a non-empty array of valid codec strings'
  }
});

iOS SDK


// Manual mode
OTVideoCodecPreference *pref = [OTVideoCodecPreference manualWithCodecs:@[
    @(OTVideoCodecTypeVP9),
    @(OTVideoCodecTypeH264),
    @(OTVideoCodecTypeVP8)
]];
OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.videoCodecPreference = pref;

// Automatic mode
OTVideoCodecPreference *pref = [OTVideoCodecPreference automatic];
OTPublisherKitSettings *settings = [[OTPublisherKitSettings alloc] init];
settings.videoCodecPreference = pref;

アンドロイドSDK


// Manual mode
PublisherKit.PreferredVideoCodecs preferredVideoCodecs =
    PublisherKit.PreferredVideoCodecs.manual(
        new ArrayList<PublisherKit.PreferredVideoCodecs.Codec>(
            List.of(PublisherKit.PreferredVideoCodecs.Codec.VP9,
                    PublisherKit.PreferredVideoCodecs.Codec.H264)));

Publisher publisher = new Publisher.Builder(MainActivity.this)
    .preferredVideoCodecs(preferredVideoCodecs)
    .build();

// Automatic mode
PublisherKit.PreferredVideoCodecs preferredVideoCodecs =
    PublisherKit.PreferredVideoCodecs.automatic();

Publisher publisher = new Publisher.Builder(MainActivity.this)
    .preferredVideoCodecs(preferredVideoCodecs)
    .build();

Windows SDK


// Manual mode
var pref = new PreferredVideoCodecs(new List<PreferredVideoCodecs.Codec> {
    PreferredVideoCodecs.Codec.VP9,
    PreferredVideoCodecs.Codec.H264,
    PreferredVideoCodecs.Codec.VP8
});
builder.PreferredVideoCodecs = pref;

// Automatic mode
builder.PreferredVideoCodecs = PreferredVideoCodecs.Automatic();

// Default (uses project settings)
builder.PreferredVideoCodecs = null;

// Invalid (throws)
try {
    builder.PreferredVideoCodecs = new PreferredVideoCodecs(new List<PreferredVideoCodecs.Codec>());
} catch (ArgumentException ex) {
    // "Must specify at least one codec"
}

LinuxおよびmacOS SDK


// Manual mode: specify an ordered priority list of codecs
otc_publisher_settings* publisher_settings = otc_publisher_settings_new();

otc_video_codec_type codecs[] = {
    OTC_VIDEO_CODEC_VP9,
    OTC_VIDEO_CODEC_H264,
    OTC_VIDEO_CODEC_VP8
};

otc_status status = otc_publisher_settings_set_preferred_video_codecs(
    publisher_settings,
    codecs,
    sizeof(codecs) / sizeof(codecs[0])
);

otc_publisher_callbacks publisher_callbacks = {0};
struct otc_publisher* publisher =
    otc_publisher_new_with_settings(&publisher_callbacks, publisher_settings);

// Done with settings object
otc_publisher_settings_delete(publisher_settings);

// Automatic mode: let the SDK choose priority automatically
otc_publisher_settings* publisher_settings = otc_publisher_settings_new();

otc_status status = otc_publisher_settings_set_preferred_video_codecs_automatic(
    publisher_settings
);

otc_publisher_callbacks publisher_callbacks = {0};
struct otc_publisher* publisher =
    otc_publisher_new_with_settings(&publisher_callbacks, publisher_settings);

// Done with settings object
otc_publisher_settings_delete(publisher_settings);

リアクト・ネイティブSDK

手動モード:コーデックの優先順位を指定します:

class App extends Component {
  constructor(props) {
    super(props);

    this.publisherProperties = {
      preferredVideoCodecs: ['vp9', 'vp8']
    };

    this.publisherEventHandlers = {
      streamCreated: event => {
        console.log('Publisher stream created!', event);
      },
      streamDestroyed: event => {
        console.log('Publisher stream destroyed!', event);
      }
    };
  }

  render() {
    return (
      <OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
        <OTPublisher
          properties={this.publisherProperties}
          eventHandlers={this.publisherEventHandlers}
          style={{ height: 100, width: 100 }}
        />
      </OTSession>
    );
  }
}

自動モード:SDKが自動的に優先順位を選択します:

class App extends Component {
  constructor(props) {
    super(props);

    this.publisherProperties = {
      preferredVideoCodecs: 'automatic'
    };

    this.publisherEventHandlers = {
      streamCreated: event => {
        console.log('Publisher stream created!', event);
      },
      streamDestroyed: event => {
        console.log('Publisher stream destroyed!', event);
      }
    };
  }

  render() {
    return (
      <OTSession apiKey="your-api-key" sessionId="your-session-id" token="your-session-token">
        <OTPublisher
          properties={this.publisherProperties}
          eventHandlers={this.publisherEventHandlers}
          style={{ height: 100, width: 100 }}
        />
      </OTSession>
    );
  }
}

ネゴシエーション段階の結果によっては、最終的に使用されるビデオコーデックが、 希望するコーデックとは異なる場合があることを理解しておくことが重要です。

OpenTokのコーデック対応状況

以下の表は、OpenTokがサポートするエンドポイントのリアルタイム動画コーデック機能の一覧です。なお、ほぼすべてのデバイスがストリーミング動画用のH.264デコーダーに対応していますが、以下の表では、デバイスのリアルタイム動画コーデック(エンコードおよびデコード)機能に焦点を当てています。

デスクトップブラウザ VP8 H.264 VP9
クローム はい はい はい
ファイアフォックス はい はい はい
サファリ はい 1 はい はい 2
エッジ はい はい はい
1 VP8は、macOS 10.14.4に同梱されているSafari 12.1以降で利用可能であり、macOS 10.13.6および10.12.6でも利用可能です。
2 VP9はSafari 15以降で利用可能ですが、ハードウェアデコード機能を備えたデバイス(M3搭載のMacBook Proなど)でのみサポートされています。
モバイルブラウザ VP8 H.264 VP9
アンドロイドのクローム はい 第1部 はい
アンドロイド版ファイアフォックス はい はい はい
モバイル・サファリ はい 2 はい はい 3
iOSのChrome/Firefox はい はい はい 4
WebViewアンドロイド はい 第5部(その5) はい
iOSのWebView はい 6 はい はい 7
1 Android版Chromeでは、QualcommおよびExynosチップセットを搭載した端末においてのみH.264に対応しており、Chrome 65以降が必要です。
2 VP8は、iOS 12.2以降のSafariで利用可能です。
3 VP9はSafari 15以降で利用可能ですが、ハードウェアデコード機能を備えたデバイス(iPhone 15 Proなど)でのみサポートされています。
4 VP9はiOS 17以降で利用可能ですが、ハードウェアデコード機能を備えたデバイス(iPhone 15 Proなど)でのみサポートされています。
5 WebView(Android版)は、QualcommおよびExynosチップセットを搭載した端末においてのみH.264に対応しており、Chrome 65以降が必要です。
6 VP8は、iOS 12.2以降で利用可能です。
7 VP9はiOS 15以降で利用可能ですが、ハードウェアデコード機能を備えたデバイス(iPhone 15 Proなど)でのみサポートされています。
ネイティブSDK VP8 H.264 VP9 **
iOS SDK (2.12+) はい はい はい
Android SDK (2.13+) はい ほとんどの機器に対応 はい
Windows SDK (2.13+) はい はい はい
Linux SDK はい いいえ はい
macOS SDK はい はい *** はい
* ハードウェアH.264は、HiSiliconおよびMediaTekチップセットのサブセットに加え、QualcommおよびExynosチップセットを搭載したデバイスでサポートされています。ソフトウェアH.264へのフォールバックは、Android M以降でサポートされます。
** VP9に対応するには、OpenTokネイティブクライアントSDK(Android、iOS、macOS、Linux、Windows用)のバージョン2.27以降が必要です。
*** H264に対応するには、macOS用OpenTok Client SDKのバージョン2.29以降が必要です。

OpenTokエンドポイント全体におけるコーデック機能のサポート

コーデック/エンドポイント クローム アンドロイド・クローム ファイアフォックス サファリ エッジ WebViewアンドロイド iOSのWebView iOS SDK アンドロイドSDK Windows SDK macOS SDK Linux SDK
VP8
H.264 75% (*) 75% (*) 99% (*)
VP9 (**) (**)
VP8スケーラブル・ビデオ
H.264スケーラブル・ビデオ
VP9スケーラブル・ビデオ (***) (***) (***) (***) (***) (***) (***) (***) (***) (***) (***) (***)

* 当該コーデックに対応しているAndroid端末の割合 ** VP9は、Safari 15以降(デスクトップ版およびiOS版)およびiOS 15以降のWebViewでサポートされていますが、M3搭載MacBookやiPhone 15 Proなど、ハードウェアエンコーディングに対応した端末でのみ利用可能です。 *** 詳細については、以下を参照してください。 本書. FirefoxではVP9に対応していますが、スケーラブルビデオには対応していません。ハードウェアおよびソフトウェアによるスケーラブルビデオのサポートは、すべてのデバイスで利用可能なわけではありません。

クライアントのコーデックサポートの検出

すべてのAndroidデバイスがH.264コーデックに対応しているわけではなく、また、旧バージョンのSafariでは VP8に対応していません。OpenTok.jsおよび OpenTok Android SDKには、クライアントが利用可能なコーデックを確認するためのメソッドが含まれています。

ブラウザでサポートされているコーデックの検出(OpenTok.js)

OT.getSupportedCodecs() このメソッドは Promise を返します。成功した場合、この Promise は、2 つのプロパティを持つオブジェクトで解決されます。 videoDecoders:デコードに対応しているビデオコーデックの配列、および videoEncoders:エンコードに対応しているビデオコーデックの配列。

次の例では、ビデオストリームのエンコードとデコードでサポートされているコーデックのリストを取得します:

(async () => {
  try {
    const supportedCodecs = await OT.getSupportedCodecs();
    if (supportedCodecs.videoEncoders.indexOf('H264') < 0 && supportedCodecs.videoDecoders.indexOf('H264') < 0) {
      // They do not support encoding or decoding H264 let's tell them to use a different browser
    }
  } catch(err) {
    console.log(err);
  }
})();

Android SDKを使用した対応コーデックの検出

MediaUtils.SupportedCodecs.getSupportedCodecs(コンテキスト) を返します MediaUtils.SupportedCodecs 2つのプロパティを持つオブジェクト: videoDecoders:サポートされているビデオコーデックのArrayList(以下で定義される MediaUtils.VideoCodecType (クラス)をデコード用として、また videoEncoders を、 サポートされているビデオコーデック(MediaUtils.VideoCodecType クラスで定義される)の ArrayList として、 エンコード用に使用します。

次の例では、ビデオストリームのエンコードとデコードでサポートされているコーデックのリストを取得します:

MediaUtils.SupportedCodecs supportedCodecs =
    MediaUtils.SupportedCodecs.getSupportedCodecs(context);
if (supportedCodecs.videoEncoders.indexOf(MediaUtils.VideoCodecType.VIDEO_CODEC_H264) < 0
    && supportedCodecs.videoDecoders.indexOf(MediaUtils.VideoCodecType.VIDEO_CODEC_H264) < 0)
{
    // The device does not support encoding or decoding H264.
}

お好みのリアルタイム・ビデオ・コーデックを選択する際に考慮すべき問題点

相互運用性

相互運用性に関する主な問題は、Androidデバイス、旧バージョンの Safari、およびLinuxに関連しています。VP8は、Android Chromeおよび OpenTok Android SDKの両方において、すべてのAndroidデバイスで動作しますが、AndroidにおけるH.264コーデックのサポートは全機種に及んでいません。 旧バージョンのSafariではVP8コーデックがサポートされていません。また、Linux SDKでは H.264がサポートされていません。

セッションサイズ

H.264、VP8、およびVP9は、小規模なセッション(例えば、参加者1~3名)のエンドポイントでは問題なく動作します。ただし、H.264にはScalable Videoのサポートがないため、大規模なセッションではこのコーデックの使用をお勧めしません。

ビデオ品質

ほぼすべてのエンドポイントで同じVP8ビデオコーデックが実装されているため、画質はおおむね同じです。VP8は低ビットレートでも良好に動作します。さらに、VP8ではOpenTok Scalable Videoを利用できます。Scalable Videoは、参加者が多いセッションにおいて、映像品質を大幅に向上させます。

H.264の画質は、デバイスごとに実装が異なるため、デバイスによって異なります。また、デバイスで動作しているオペレーティングシステムのバージョンによっても、画質に違いが見られることがあります。低ビットレートでのH.264の画質は、一般的にVP8ほど良くありません。

iOSデバイスはH.264ハードウェア・アクセラレーションをよくサポートしているので、H.264はiOSデバイスでうまく機能する。これにより、CPU負荷が軽減され、バッテリー寿命が向上します。

VP9は、同じビットレートで動作させた場合、VP8よりも優れた画質を実現します。ただし、画質の向上に伴い、VP8よりもCPUへの負荷が高くなる可能性があります。

シナリオ例

以下は、いくつかのシナリオ例で使用する推奨ビデオコーデックです:

  • 参加者が2~3人のOpenTokセッションで、旧バージョンの Safariとの相互運用性が不可欠な場合は、H.264ビデオコーデックを使用してください。

  • iOSデバイスだけが使用されている、2人または3人の参加者がいるOpenTokセッションでは、ハードウェアアクセラレーションを活用するためにH.264ビデオコーデックを使用してください。

  • ウェビナーや大規模な教室でのセッションでは、OpenTokのスケーラブルビデオ機能を活用するために、VP8コーデックを使用してください。

  • すべてのAndroidデバイスへの対応が不可欠なOpenTokセッションでは、VP8コーデックを使用してください。

  • 参加者が2人のOpenTokセッションでは、VP9ビデオコーデックの使用をご検討ください。

既知の問題

VP9とSIPの相互接続

VP9は、以下の要素を含むセッションではサポートされていません。 シップ 参加者。プロジェクトの優先ビデオコーデックとしてVP9が設定されている場合、SIP参加者はビデオを受信できなくなりますが、ビデオの送信は引き続き可能です。SIP相互接続を使用するセッションでは、代わりにVP8またはH.264を使用してください。

WebRTC参加者は、プロジェクトで設定された優先ビデオコーデックに関係なく、SIP参加者が公開したビデオをVP8形式で受信します。