Amazon Web Services ブログ

BytePlus Effects と Amazon IVS を使ったリアルタイム AR 効果でユーザーエンゲージメントを向上させる方法

このブログ記事は Chen Xiaoyu(BytePlus社 MLソリューションディレクター)と Hao Chen(Customer Success Engineer on the Amazon IVS team) および Tian Shi(Senior Solutions Architect at AWS)の共著によるものです。

Sandvine’s Global Internet Phenomena Report によると、2022 年の全インターネットトラフィックの 65 %以上が動画コンテンツでした。この数字は 2021 年から 24 %増加しており、クリエーターたちがストリーミング動画を通じて視聴者にリーチするために利用可能なプラットフォームの増加に伴い、さらに増えていく傾向にあります。

広大で、多様性に富み、更に成長していく市場に対し、あなたのユーザー生成コンテンツ (UGC) プラットフォームを際立たせるのは至難の業でしょう。いくつかのプラットフォームが成功を収めているひとつの方法として、拡張現実 (AR) のような機能を加えるというものがあります。

BytePlus Effects は、AR エンゲージメントツールの広範囲にわたるライブラリを有する SDK であり、デベロッパーがどのようにこれらの機能を素早く組み込むことができるかという一例です。SDK はオフラインで提供されますので、全てのエフェクトはユーザーのデバイス上で、クラウドに個人データを送信することなく作成されます。 このアプローチにはいくつか長所があるものの、ユーザーとの信頼を確立するポジティブな体験を創りあげるには高性能化とユーザーデータのプライバシーが最重要課題です。

BytePlus Effectsはあなたのライブストリーミング UGC プラットフォームとインテグレートすることもできます。このブログ記事では、Amazon intaractive video service (Amazon IVS) へ配信する iOS アプリケーションをライブラリを使って生成する方法について紹介します。

必要なもの

まず、必要なものをセットアップしてください:

ストリーミングチャンネルを生成したら、Amazon IVSが提供する以下の情報を確認してください:

  1. インジェストサーバーのURL
  2. ストリームキー
  3. プレイバック URL

Amazon IVS チャンネルに関する完全ガイドについては、Getting Started with Amazon IVS ガイドを参照してください。

SDK のインストール

SDKを簡単にインストールするには、CocoaPods を介して SDK をインテグレートするのをお勧めします。Amazon IVS も BytePlus も両方とも CocoaPods に対応しています。詳しくは Amazon IVS Broadcast SDK (iOS) Istallation GuideBytePlus Effect SDK (iOS) Instration Guide をご覧ください。

インテグレートステップ

デフォルトとして、Amazon IVS iOS broadcast SDK は、ストリーミングのためにデバイスカメラ画像を制御し撮像するための API を提供します。BytePlus Effect SDK をインテグレートするために、デバイスカメラを制御し、BytePlus Effect SDK を使って画像を処理し、処理した画像を CustomImageSource を介して IVS ブロードキャスト SDK に転送してストリーミングするアプリケーションロジックを作ります。このブログ記事では、Amazon IVS iOS broadcast SDK と BytePlus Effect SDK に対応する Object-C code を使ったインストールステップを紹介します。

Diagram showing how the device camera image works with the BytePlus Effects SDK and the Amazon IVS Broadcast SDK

  1. ブロードキャストセッションをセットアップ
  2. CustomImageSource 設定をセットアップ
  3. 動画キャプチャーをセットアップ
  4. 本例では BytePlus Effect SDK に BEVideoCapture を介してカメラにアクセスさせますが、アプリケーションデベロッパーは他の入力ソースを選んで使用しても構いません。
  5. 撮像した画像を BytePlus Effect SDK を使って処理
  6. CustomImageSource に処理した画像バッファを送信
  7. 配信をスタート

配信セッションのセットアップ

詳細なSDKマニュアルについては、GitHub 上にある Amazon IVS Documentation pagesample application をご覧ください。

CustomImageSource を配信設定でセットアップ

CustomImageSource は Amazon IVS Broadcast SDK の拡張機能です。これによりアプリケーションデベロッパーはカスタム入力ソースから画像バッファを提出し、ストリーミングできます。

配信設定

CustomImageSource を配信セッションの入力ソースとして使用して、まず配信設定をセットアップする必要があります。本例では、プレセットした設定standardPortrait を使います。

// Create Broadcast Configuration
IVSBroadcastConfiguration *config = [[IVSPresets configurations] 
standardPortrait];

ミキサースロット設定

CustomImageSource を入力ソースとして使うために、Broadcast SDK のミキサー機能を使って、カスタムミキサー設定を生成します。ミキサーとは、複数の入力ソース(スロット)を受け取り、インジェスト用のひとつの出力を生成する動画処理ユニットです。例示のために本例では使用するスロットはひとつです。

// Set up Mixer Slot Configuration
IVSMixerSlotConfiguration *customSlot = [IVSMixerSlotConfiguration new];
customSlot.size = config.video.size;
customSlot.position = CGPointMake(0.0, 0.0);
customSlot.preferredAudioInput = IVSDeviceTypeUserAudio;
customSlot.preferredVideoInput = IVSDeviceTypeUserImage;
NSError *customSlotError = nil;
NSString * const customSlotName = @"custom-slot";
[customSlot setName:customSlotName error:customSlotError];

// Set this slot to Broadcast configuration we have created above
config.mixer.slots = @[customSlot];

配信セッション

最後に上記の設定で配信セッションをセットアップします。

NSError *broadcastSessionError = nil;
// providing nil to the camera descriptor parameter to let application logic to take control of the camera device
IVSBroadcastSession *broadcastSession = [[IVSBroadcastSession alloc] initWithConfiguration:config descriptors:nil delegate:nil error:&broadcastSessionError];

// Attach custom audio input source
id customAudioSource = [broadcastSession createAudioSourceWithName:@"custom-audio"];
[broadcastSession attachDevice:customAudioSource toSlotWithName:customSlotName onComplete:nil]; // <connect to your onComplete callback function>
self.customAudioSource = customAudioSource;

// Attach custom image input source
id customImageSource = [broadcastSession createImageSourceWithName:@"custom-image"];
[broadcastSession attachDevice:customImageSource toSlotWithName:customSlotName onComplete:nil]; // <connect to your onComplete callback function>
self.customImageSource = customImageSource;

self.broadcastSession = broadcastSession;

動画キャプチャーのセットアップ

デモンストレーション目的では、BytePlus Effect SDKのAPI BEVideoCapture を使って、動画キャプチャーをセットアップします。

BytePlus Effect SDK の初期化

self.imageUtils = [[BEImageUtils alloc] init];
self.manager = [[BEEffectManager alloc] initWithResourceProvider:[BEEffectResourceHelper new] licenseProvider:[BELicenseHelper shareInstance]];
// SDK initialization
int ret = [self.manager initTask];

デバイスカメラで動画を撮影

BEVideoCapture *capture = [[BEVideoCapture alloc] init];
capture.outputFormat = kCVPixelFormatType_32BGRA;
// code that sets up initial configuration for BEVideoCapture removed for brevity
[capture startRunning];

BytePlus Effect SDK を使って撮像画像を処理

BEVideoCapture が提供する以下の videoCapture プロキシ方法では、撮影した CMSampleBufferRef をデバイスカメラから転送して処理します。

// BEVideoCapture delegate callback
- (void)videoCapture:(id<BEVideoSourceProtocol>)source didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer withRotation:(int)rotation {

// code that provides GLContext check removed for brevity

    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CMTime sampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
    double timeStamp = (double)sampleTime.value/sampleTime.timescale;
    
// code that provides lock on BytePlus Effect SDK for thread safety removed for brevity e.g. NSRecursiveLock
    [self processWithCVPixelBuffer:pixelBuffer rotation:rotation timeStamp:timeStamp];
}

BytePlus Effect SDK を使ってカメラからのバッファを処理

実際の画像処理は、次のprocessWithCVPixelBuffer機能で行われます。

出入力画像バッファのセットアップ

- (void)processWithCVPixelBuffer:(CVPixelBufferRef)pixelBuffer rotation:(int)rotation timeStamp:(double)timeStamp {

    BEPixelBufferInfo *pixelBufferInfo = [self.imageUtils getCVPixelBufferInfo:pixelBuffer];

    // The BytePlus Effect SDK requires BGRA format
    if (pixelBufferInfo.format != BE_BGRA) {
        pixelBuffer = [self.imageUtils transforCVPixelBufferToCVPixelBuffer:pixelBuffer outputFormat:BE_BGRA];
    }
    if (rotation != 0) {
        // The texture received by the BytePlus Effect SDK must be positive, so before calling the SDK, you need to rotate it first
        pixelBuffer = [self.imageUtils rotateCVPixelBuffer:pixelBuffer rotation:rotation];
    }
    
    // Set up input buffer
    id<BEGLTexture> texture = [self.imageUtils transforCVPixelBufferToTexture:pixelBuffer];
    // Set up output buffer
    id<BEGLTexture> outTexture = nil;
    outTexture = [self.imageUtils getOutputPixelBufferGLTextureWithWidth:texture.width height:texture.height format:BE_BGRA];

画像の処理

BytePlus Effect SDK 初期化で前にセットアップした BEEffectManager オブジェクトである self.manager を使います。

    // self.manager is the BEEffectManager during the BytePlus Effect SDK Initialization
    // For demonstration purposes we will fix the rotation of the image.
    int ret = [self.manager processTexture:texture.texture outputTexture:outTexture.texture width:texture.width height:texture.height rotate:BEF_AI_CLOCKWISE_ROTATE_0
timeStamp:timeStamp];
    if (ret != BEF_RESULT_SUC) {
        // Log successful image processing
    } else {
        // Log unsuccessful image processing
    }
    outTexture = texture;

処理した画像バッファを CustomImageSource に送信

処理済み画像バッファが準備出来たら、前のステップでセットアップした配信セッションの CustomImageSource に送信します。

if (self.broadcastSession != nil) {
        // obtain CVPixelBufferRef
        CVPixelBufferRef outputPixelBuffer = [(BEPixelBufferGLTexture *)outTexture pixelBuffer];

        CMVideoFormatDescriptionRef formatDescription;
        CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, outputPixelBuffer, &formatDescription);

        
        CMSampleTimingInfo timing = { kCMTimeInvalid, kCMTimeInvalid, kCMTimeInvalid };
        CMSampleBufferRef sampleBuffer;
    
        // Convert to CMSampleBufferRef
CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault,
                                              outputPixelBuffer,
                                              formatDescription,
                                              &timing,
                                              &sampleBuffer);


        // submitted CMSampleBufferRef to customImageSource
        [self.customImageSource onSampleBuffer:sampleBuffer];
    }    
// code that sets up preview window in the UI removed for brevity
}

動画配信を開始

if (self.broadcastSession != nil) {
    
        NSURL *myURL = [NSURL URLWithString:@"<INGEST_URL>"];
        NSString *myKey = @"<STREAM_KEY>";
        
        [self.broadcastSession startWithURL:myURL streamKey:myKey error:nil];
    }

インテグレーションの結果

Face shaping demo

フェイスシェイピングのデモ 左:ソースの iPhone アプリケーション、右: Amazon IVS チャンネルからの HLS 出力

Image filtering demo

画像フィルタリングのデモ 左:ソースの iPhone アプリケーション、右: Amazon IVS チャンネルからの HLS 出力

このインテグレーションはさらにカスタマイズすることができます。BytePlus Effect SDK は、BEImageCaptureBELocalVideoCapture などの様々な画像ソースの処理をするために汎用型のインテグレーションオプション を提供しています。

アプリケーションアーキテクチャ

Amazon IVS Broadcast SDKBytePlus Effect SDK の両方を iOS モバイルアプリケーションにインテグレートしました。BytePlus Effect SDK を使って、デバイスカメラからの動画を処理し、IVS Broadcast SDK に送信して、ストリーミングしました。Application architecture diagram

BytePlus について

ByteDance technologyから生まれたBytePlusは、クライアントが様々なインテリジェント技術ソリューションで成長の最大化をお手伝いします。スペシャリストの専門チームがお客様に協力して、より良い製品づくり、より良い体験、そしてビジネスの成長を実現するために、専門家集団がお客さまと手を携えてお手伝いします。

Xiaoyu Chen

Xiaoyu Chen

BytePlus AI ソリューションのディレクター。BytePlus エフェクト、AR、ビデオ エディター、オーディオ、メディア処理サービス、その他の製品ラインを含む AI to B 製品の海外商業化と製品化を担当。彼女は南洋理工大学を卒業し、学士号を取得し、シンガポール国立大学で大学院の学位を取得しました。国内外の AI/ML 製品およびプロジェクトで豊富な経験を持っています。彼女は、東南アジア、日本、韓国、および海外市場において、相互エンターテイメント、文化観光、銀行、保険会社向けの数多くの AI/ML プロジェクトを指揮してきました。

Hao Chen

Hao Chen

Haoは、Amazon IVS チームのカスタマーサクセスエンジニアです。AWS のお客様が Amazon IVS を使った革新的なライブストリーミングソリューションの構築をお手伝いします。

Tian Shi

Tian Shi

Tian Shi は、AWS のシニアソリューションアーキテクトです。彼の専門分野はデータ分析、機械学習、サーバーレスです。クラウドにおける信頼性と拡張性の高いソリューションの設計と構築を支援することに情熱を注いでいます。余暇には、水泳や読書を楽しんでいます。