このトピックでは、macOS での画面共有の実装方法について説明します。
機能概要
画面共有は、ビデオ通話またはライブストリーミング中に、チャンネル内の他のユーザーに対してリアルタイムでご利用の画面の内容を共有する機能です。この機能により、即時の情報共有および視覚的なコミュニケーションが可能になります。
前提条件
画面共有を実装する前に、以下の前提条件を満たしていることを確認してください。
有効な Alibaba Cloud アカウント (root ユーザー) を保有し、ApsaraVideo Real-time Communication アプリケーションを作成済みである必要があります。詳細については、「アプリケーションの作成」をご参照ください。App ID および App Key は、コンソールから取得できます。
ApsaraVideo Real-time Communication (ARTC) SDK をプロジェクトに統合済みであり、基本的なリアルタイム音声・映像機能を実装済みである必要があります。SDK の統合に関する詳細については、「SDK のダウンロードと統合」をご参照ください。音声・映像機能の実装に関する詳細については、「音声・映像通話の実装」をご参照ください。
注意事項
ARTC バージョン 7.6 より前の場合、画面共有を開始する前に必ずチャンネルに参加する必要があります。チャンネルへの参加方法については、「音声・映像通話の実装」をご参照ください。
ARTC バージョン 7.6 以降では、チャンネルに参加しなくても画面共有を開始できます。この場合、
AliEngineScreenShareConfig.isPushStreamを FALSE に設定することを推奨します。チャンネルに参加後に、このパラメーターを TRUE に設定し、updateScreenShareConfigメソッドを呼び出してアップストリーミングを開始してください。
実装手順
1. 画面共有のエンコーディングパラメーターの構成
画面共有ビデオストリームのエンコーディングプロパティをカスタマイズするには、setScreenShareEncoderConfiguration メソッドを呼び出します。解像度、フレームレート、ビットレート、グループ・オブ・ピクチャーズ(GOP)、映像の回転などのパラメーターを構成できます。
このメソッドは、チャンネルに参加する前後いずれでも呼び出せます。セッションごとに画面ストリームのエンコーディングプロパティを一度だけ設定する場合は、チャンネル参加前に呼び出すことを推奨します。
必要に応じて、複数回呼び出して構成を更新できます。
関連する構成項目は以下のとおりです。
パラメーター名 | 説明 | デフォルト値 |
dimensions | ビデオの解像度。 | 0 × 0(キャプチャされた画面の解像度に自動一致)。最大値は 3840 × 2160。 |
frameRate | ビデオフレームレート。 | デフォルト値は 5。最大値は 30。 |
bitrate | ビデオエンコーディングビットレート(単位:Kbps)。 注:ビットレートは、解像度およびフレームレートに基づいて適切な範囲内に設定する必要があります。指定した値が有効範囲外の場合、SDK が自動的に有効な値に調整します。 | 512 |
keyFrameInterval | キーフレーム間隔(グループ・オブ・ピクチャーズ:GOP)。単位:ミリ秒(ms)。 | デフォルト値は 0(SDK が内部でキーフレーム間隔を制御)。 |
forceStrictKeyFrameInterval | エンコーダーが構成されたキーフレーム間隔を厳密に遵守するかどうかを指定します。 | デフォルト値は false。
|
rotationMode | ビデオストリームの回転角度。 | デフォルト値は AliEngineRotationMode_0。有効値は 0、90、180、270 です。 |
サンプルコード:
/*
config はユーザー定義の構成構造体
*/
AliRtcScreenShareEncoderConfiguration * encoderConfig = [[AliRtcScreenShareEncoderConfiguration alloc] init];
encoderConfig.dimensions = CGSizeMake( width_, height_);
encoderConfig.frameRate = frameRate_; // 5/10/15...
encoderConfig.bitrate = bitrate_; // 1200...
encoderConfig.rotation = AliRtcRotationMode_0; // 0/90/180/270
encoderConfig.keyFrameInterval = keyFrameInterval_; // 1/2/3 seconds
if (keyFrameInterval_ > 0) {
encoderConfig.forceStrictKeyFrameInterval = TRUE;
}
encoderConfig.forceStrictKeyFrameInterval = forceStrictKeyFrameInterval_;
[self.mainEngine setScreenShareEncoderConfiguration: encoderConfig];2. 画面共有のプレビューの設定
ローカルの画面共有フィードをプレビューするには、setLocalViewConfig メソッドを呼び出して、画面共有ストリーム(AliEngineVideoTrackScreen)の表示ビューを構成します。
AliVideoCanvas *canvas = [[AliVideoCanvas alloc]init];
canvas.mirrorMode = _mirrorButton.state == NSControlStateValueOn ? AliRtcRenderMirrorModeAllEnabled:AliRtcRenderMirrorModeAllDisabled;
canvas.view = renderView;
int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen];3. (リモート)画面共有の表示
リモートユーザーの画面共有フィードを表示するには、setRemoteViewConfig メソッドを onRemoteTrackAvailableNotify コールバック内で呼び出し、表示ビューを構成します。
- (void)onRemoteTrackAvailableNotify:(NSString *)uid audioTrack:(AliRtcAudioTrack)audioTrack videoTrack:(AliRtcVideoTrack)videoTrack {
/* メインスレッド上で UI コンポーネントを処理 */
dispatch_async(dispatch_get_main_queue(), ^{
AliVideoCanvas *canvas = [[AliVideoCanvas alloc]init];
if ( videoTrack == AliRtcVideoTrackScreen ) {
canvas.view = self._screenshareView;
int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen];
} else {
/* このユーザーに対応するビューを検索 */
canvas.view = self.findView(uid);
int rv = [self.mainEngine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackScreen];
}
});
}4. 共有可能なデスクトップの一覧取得
共有可能なウィンドウおよびデスクトップの一覧を取得するには、getScreenShareSourceInfoWithType メソッドを呼び出します。
システムから権限付与のプロンプトが表示されます。ユーザーが権限を拒否した場合、その後のすべての共有試行は失敗します。
_screenInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareDesktop];
/* リストに追加 */
if (_screenInfoArray) {
for (AliRtcScreenSourceInfo *info in _screenInfoArray) {
// 名前 + ID
NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
[_screenListBox addItemWithObjectValue:showString];
}
}
5. 画面共有の開始
画面共有を開始するには、startScreenShareWithDesktopId メソッドを呼び出します。
注:config.isPushStream の構成が必要です。
AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];
/* リージョン単位の共有の場合 */
if ( shareRegion ) {
config.isShareByRegion = TRUE ;
AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
region.originX = regionRect.origin.x;
region.originY = regionRect.origin.y;
region.width = regionRect.size.width;
region.height = regionRect.size.height;
config.shareRegion = region;
} else {
config.isShareByRegion = FALSE;
}
/* 即時にストリームをプッシュする場合は true、それ以外の場合は false を設定。
後続で updateScreenShareConfig を呼び出して変更可能 */
if ( pushStream ) {
config.isPushStream = TRUE ;
} else {
config.isPushStream = FALSE ;
}
/* _screenListBox からデスクトップ ID を取得 */
int idValue = [[_screenInfoArray[_screenListBox.indexOfSelectedItem] sourceId] intValue] ;
int r = [self.engine startScreenShareWithDesktopId:idValue config:config];
NSLog(@"startScreenShareWithDesktopId:%d",r);
if ( r != 0 ) {
// エラー処理
}
6. (任意)構成の更新
画面共有構成を更新するには、updateScreenShareConfig メソッドを呼び出します。
AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];
/* リージョン単位の共有の場合 */
if ( share_region ) {
config.isShareByRegion = TRUE ;
AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
region.originX = regionRect.origin.x;
region.originY = regionRect.origin.y;
region.width = regionRect.size.width;
region.height = regionRect.size.height;
config.shareRegion = region;
} else {
config.isShareByRegion = FALSE;
}
/* 即時にストリームをプッシュする場合は true、それ以外の場合は false を設定。
後続で updateScreenShareConfig を呼び出して変更可能 */
if ( pushStream ) {
config.isPushStream = TRUE ;
} else {
config.isPushStream = FALSE ;
}
[self.engine updateScreenShareConfig:mScreenConfig];7. 画面共有の停止
[self.engine stopScreenShare];マルチウィンドウ共有
プレビュー表示ビューの構成、プレビュー表示、およびアップストリーミングのロジックは、デスクトップ共有と同一です。サンプルコードは本セクションでは繰り返しません。
1. 共有可能なすべてのウィンドウの表示
ビジネス要件に応じて、startScreenShareWithWindowId メソッドを呼び出して特定のウィンドウを共有できます。
_windowInfoArray = [self.engine getScreenShareSourceInfoWithType:AliRtcScreenShareWindow];
/* リストボックスに表示 */
if (_windowInfoArray) {
for (AliRtcScreenSourceInfo *info in _windowInfoArray) {
// 名前 + ID
NSString *showString = [NSString stringWithFormat:@"%@+%@",info.sourceName,info.sourceId];
[_windowsListBox addItemWithObjectValue:showString];
}
}
2. 特定のウィンドウの共有
AliRtcScreenShareConfig *config = [[AliRtcScreenShareConfig alloc]init];
/* リージョン単位の共有の場合 */
if ( shareRegion ) {
config.isShareByRegion = TRUE ;
AliRtcScreenShareRegion *region = [[AliRtcScreenShareRegion alloc]init];
region.originX = regionRect.origin.x;
region.originY = regionRect.origin.y;
region.width = regionRect.size.width;
region.height = regionRect.size.height;
config.shareRegion = region;
} else {
config.isShareByRegion = FALSE;
}
/* 即時にストリームをプッシュする場合は true、それ以外の場合は false を設定。
後続で updateScreenShareConfig を呼び出してプッシュストリームフラグを変更可能 */
if ( pushStream ) {
config.isPushStream = TRUE ;
} else {
config.isPushStream = FALSE ;
}
/* _windowsListBox からウィンドウ ID を取得 */
int idValue = [[_windowInfoArray[_windowsListBox.indexOfSelectedItem] sourceId] intValue] ;
int r = [self.engine startScreenShareWithWindowId:idValue config:config];
NSLog(@"startScreenShareWithWindowId:%d",r);
if ( r != 0 ) {
// エラー処理
}
3. ウィンドウまたはデスクトップ共有の停止
共有を停止するには、stopScreenShare メソッドを呼び出します。
[self.mainEngine stopScreenShare];