すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo VOD:高度な機能

最終更新日:Mar 13, 2026

このトピックでは、ApsaraVideo Player SDK for iOS の高度な機能の使用方法について説明します。すべての機能の完全な説明については、「API リファレンス」をご参照ください。

重要

デモを試すには、ダウンロードして、「デモの実行」の手順に従ってプロジェクトをコンパイルおよび実行してください。

専門スキルの確認

説明

一部のプレーヤー機能は Professional Edition ライセンスを必要とします。詳細については、「機能」をご参照ください。ライセンスの取得については、「ライセンスの取得」をご参照ください。

アプリケーションの起動時、またはプレーヤーの API 操作を呼び出す前にリスナーを設定します。

void premiumVeryfyCallback(AVPPremiumBizType biztype, bool isValid, NSString* errorMsg) {
    NSLog(@"onPremiumLicenseVerifyCallback: %d, isValid: %d, errorMsg: %@", biztype, isValid, errorMsg);
}

[AliPrivateService setOnPremiumLicenseVerifyCallback:premiumVeryfyCallback];

ここで、AVPPremiumBizType はプロフェッショナル機能の列挙型です。関連する機能を使用すると、プレーヤーはその機能を検証し、このコールバックを通じて検証結果を返します。isValidfalse の場合、errorMsg には具体的な理由が含まれます。

再生

リスト再生

ApsaraVideo Player SDK for iOS は、フル機能のリスト再生機能を提供します。SDK はプリロードなどのメカニズムを用いて、短尺動画の初回フレーム表示までの時間(TTTF)を最小限に抑えます。

操作手順

  1. プレーヤーを作成します。

    AliListPlayer インスタンスを作成します。

    self.listPlayer = [[AliListPlayer alloc] init];
    [self.listPlayer setTraceID:@"xxxxxx"];  // TraceID はデバイスまたはユーザーを一意に識別するための識別子(例:IMEI や IDFA)です。

  2. 任意: リスナーを設定します。

    リスト再生を作成する際、リスナーの設定は任意です。ただし、設定しない場合、再生失敗や再生進捗などのイベント通知をプレーヤーから受信できなくなります。そのため、設定することを推奨します。

    プレーヤーは複数のリスナーの設定をサポートしています。特に重要な onPlayerEvent および onError を設定することを推奨します。

    /**
     @brief エラー コールバック。
     @param player プレーヤーのポインター。
     @param errorModel プレーヤーエラーの説明。AliVcPlayerErrorModel を参照してください。
     */
    - (void)onError:(AliPlayer*)player errorModel:(AVPErrorModel *)errorModel {
        // エラーメッセージを表示し、再生を停止します。
    }
    /**
     @brief プレーヤーイベント コールバック。
     @param player プレーヤーのポインター。
     @param eventType プレーヤーイベントの種類。AVPEventType を参照してください。
     */
    -(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
        switch (eventType) {
            case AVPEventPrepareDone: {
                // プレーヤーの準備が完了しました。
            }
                break;
            case AVPEventAutoPlayStart:
                // 自動再生が開始されました。
                break;
            case AVPEventFirstRenderedStart:
                // 初回フレームのレンダリングが開始されました。
                break;
            case AVPEventCompletion:
                // 再生が完了しました。
                break;
            case AVPEventLoadingStart:
                // バッファリングが開始されました。
                break;
            case AVPEventLoadingEnd:
                // バッファリングが完了しました。
                break;
            case AVPEventSeekEnd:
                // シークが完了しました。
                break;
            case AVPEventLoopingStart:
                // ループ再生が開始されました。
                break;
            default:
                break;
        }
    }
    /**
     @brief 現在の再生位置のコールバック。
     @param player プレーヤーのポインター。
     @param position 現在の再生位置。
     */
    - (void)onCurrentPositionUpdate:(AliPlayer*)player position:(int64_t)position {
        // 進行状況バーを更新します。
    }
    /**
     @brief 動画のバッファ済み位置のコールバック。
     @param player プレーヤーのポインター。
     @param position 現在のバッファ済み位置。
     */
    - (void)onBufferedPositionUpdate:(AliPlayer*)player position:(int64_t)position {
        // バッファの進行状況を更新します。
    }
    /**
     @brief トラック情報のコールバック。
     @param player プレーヤーのポインター。
     @param info トラックストリーム情報の配列。AVPTrackInfo を参照してください。
     */
    - (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info {
        // マルチビットレートストリームに関する情報を取得します。
    }
    /**
     @brief 字幕表示のコールバック。
     @param player プレーヤーのポインター。
     @param trackIndex 字幕ストリームのインデックス。
     @param subtitleID 字幕 ID。
     @param subtitle 表示する字幕文字列。
     */
    - (void)onSubtitleShow:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID subtitle:(NSString *)subtitle {
        // 字幕を表示します。
    }
    /**
     @brief 字幕非表示のコールバック。
     @param player プレーヤーのポインター。
     @param trackIndex 字幕ストリームのインデックス。
     @param subtitleID 字幕 ID。
     */
    - (void)onSubtitleHide:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID {
        // 字幕を非表示にします。
    }
    /**
     @brief スナップショット取得のコールバック。
     @param player プレーヤーのポインター。
     @param image 画像。
     */
    - (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image {
        // スナップショットをプレビューおよび保存します。
    }
    /**
     @brief トラック切り替え完了のコールバック。
     @param player プレーヤーのポインター。
     @param info 新しいトラックの情報。AVPTrackInfo を参照してください。
     */
    - (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
        // ビットレート切り替え結果の通知。
    }
    //...
  3. プリロード数を設定します。

    適切なプリロード数を設定することで、起動速度を効果的に向上させることができます。

    self.listPlayer.preloadCount = 2;
  4. 再生ソースを追加または削除します。

    リスト再生は VidSts および UrlSource の 2 種類のソースタイプをサポートします。Url は再生 URL、Vid はオンデマンド動画の音声/動画 ID(VideoId)です。

    • UrlSource:ApsaraVideo VOD またはサードパーティサービスからの再生 URL。

      ApsaraVideo VOD のメディアアセットの再生 URL は、GetPlayInfo 操作を呼び出すことで取得できます。再生 URL の取得には、ApsaraVideo VOD のサーバー側 SDK を統合することを推奨します。これにより、URL 署名処理が自動で行われるため、手順が簡素化されます。例については、「OpenAPI Explorer」をご参照ください。

    • Vid:音声または動画ファイルの ID。この ID はコンソール(パス:メディア ライブラリ > 音声/動画)またはファイルのアップロード後にサーバー側 API を呼び出すこと(「メディア情報の検索」)で取得できます。

    // VidSts ソースを追加します。
    [self.listPlayer addVidSource:videoId uid:UUIDString];
    // UrlSource を追加します。
    [self.listPlayer addUrlSource:URL uid:UUIDString];
    // ソースを削除します。
    [self.listPlayer removeSource:UUIDString];
    説明
    • UID は動画を一意に識別するための識別子です。同一の動画であるかどうかを区別するために使用されます。UID が一致する場合は、同一の動画と見なされます。動画の再生順序が乱れる場合は、異なる動画に同じ UID が設定されていないか確認してください。UID には形式上の制約はなく、任意の文字列を指定できます。

  5. 表示ビューを設定します。

    ソースに動画コンテンツが含まれる場合、プレーヤー内に表示用のビューを設定します。

    self.listPlayer.playerView = self.simplePlayScrollView.playView;
  6. 動画ソースを再生します。

    1 つ以上の動画ソースを追加した後、moveTo を呼び出すと、特定の動画ソースに対して自動再生が有効になります。以下の例をご参照ください:

    // UrlSource 再生に使用する API。
    - (BOOL) moveTo:(NSString*)uid;
    // VidSts 再生に使用する API。一時的な STS 認証情報および一時的な AccessKey ペアを渡す必要があります。事前に取得してください。「RAM ロールの作成および STS 一時認証の実行」をご参照ください。
    - (BOOL) moveTo:(NSString*)uid accId:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
  7. 前の動画または次の動画を再生します。

    moveTo を呼び出して動画ソースの再生を開始した後、moveToPrev または moveToNext を呼び出すと、moveTo の呼び出しを基準として、前の動画または次の動画を再生できます。以下の例をご参照ください:

    説明

    同じ ビュー を使用して moveTo または moveToNext を呼び出してビデオソースを切り替えると、画面がちらついたり一時的に黒くなったりすることがあります。これを防ぐには、listPlayer を初期化する際に PlayerConfigclearShowWhenStop フィールドを false に設定し、変更を適用するために setConfig を呼び出します。

    UrlSource 再生ソース

    // 次の動画に移動します。
    - (BOOL) moveToNext;
    // 前の動画に移動します。
    - (BOOL) moveToPre;

    VidSts 再生ソース

    // 次の動画に移動します。
    - (BOOL) moveToNext:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
    // 前の動画に移動します。
    - (BOOL) moveToPre:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
説明

強化されたリスト再生体験を実現するには、当社のショートフォームドラマソリューションをご利用ください。詳細については、「ミニドラマ クライアント開発」をご参照ください。

alpha チャンネル付き動画の再生

概要

ApsaraVideo Player SDK は、アニメーションギフトなどのダイナミックエフェクトを実現するための alpha チャンネルのレンダリングをサポートしています。ライブストリーミング中には、メインコンテンツを遮ることなくアニメーションギフトを再生できるため、ユーザー体験が向上します。

使用制限

alpha チャンネルのレンダリングは、オールインワン SDK V6.8.0 以降、または ApsaraVideo Player SDK V6.9.0 以降でサポートされています。

メリット

ギフトエフェクトに透過性のある MP4 動画を使用すると、アニメーション品質の向上、ファイルサイズの縮小、互換性の向上、開発効率の向上が実現できます。これにより、ギフトエフェクトをユーザーにより効果的に表示でき、ユーザー体験が向上します。

  1. アニメーション品質の向上:MP4 動画は、他のフォーマットと比較して、オリジナルのアニメーションのディテールや色をより正確に保持します。

  2. ファイルサイズの縮小:MP4 動画ファイルは、APNG や IXD などの他のフォーマットと比較して、より効率的に圧縮されます。これにより、読み込み時間が短縮され、ネットワーク帯域幅の消費も低減されます。

  3. 互換性の向上:MP4 フォーマットは、さまざまなデバイスおよびブラウザで広くサポートされています。

  4. ギフトエフェクトに MP4 動画を使用することで、開発効率が向上します。この技術的ソリューションはシンプルであり、開発者は複雑な解析およびレンダリングロジックの調査・実装から解放され、他の機能に集中できます。

サンプルコード

alphaRenderMode プロパティを使用して、動画素材内の alpha チャンネルの位置(上、下、左、右)を設定します。デフォルト値は None です。

説明
  • 動画アセット内の alpha チャンネルの位置は、alphaRenderMode の設定と一致している必要があります。

  • ビューのサイズは、素材の解像度に比例している必要があります。

/**
 @brief Alpha レンダリングモード。右、左、上、下の alpha をサポートします。デフォルト値は none です。
 @see AVPAlphaRenderMode
 */
/****
 @brief レンダリングモードを設定します。右、左、上、下の alpha をサポートします。デフォルト値は none です。
 @see AVPAlphaRenderMode
 */
@property(nonatomic) AVPAlphaRenderMode alphaRenderMode;
//--------------ビューの使用-------------
// プレーヤーのビューには、透明な背景色を設定します。
@property (weak, nonatomic) IBOutlet UIView *mediaPlayerView;
[self.aliplayerview setBackgroundColor:UIColor.clearColor];

//-----------AliPlayer の使用-----------
// alpha モードを設定します。
[self.player setAlphaRenderMode:AVP_RENDERMODE_ALPHA_AT_LEFT];
// alpha モードに対応する素材を設定します。
AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:@"https://alivc-player.oss-cn-shanghai.aliyuncs.com/video/%E4%B8%9A%E5%8A%A1%E9%9C%80%E6%B1%82%E6%A0%B7%E6%9C%AC/alpha%E9%80%9A%E9%81%93/alpha_left.mp4"];
[self.player setUrlSource:source];

// 任意:再生完了後に画面をクリアして、視覚的なアーティファクトを防止します。
#pragma mark -- AVPDelegate
- (void)onPlayerEvent:(AliPlayer *)player eventType:(AVPEventType)eventType {
    switch (eventType) {
        case AVPEventCompletion:
        {
            [player clearScreen];
        }
            break;
        //...
    }
}

[self.player setAutoPlay: YES];
[self.player prepare];

Metal レンダリング

ApsaraVideo Player SDK for iOS は、Metal フレームワークを用いた動画レンダリングをサポートしています。

説明

現在、Metal レンダリングでは、背景色の設定、スケーリングモード、ピクチャーインピクチャー(PiP)のみがサポートされています。

構成

/**
 @brief 動画レンダリングタイプ。0 はデフォルトレンダリング、1 は混合レンダリングを意味します。デフォルトは 0 です。
 */
/****
 @brief 動画レンダリングタイプ。0 はデフォルトレンダリング、1 は混合レンダリングを意味します。
 */
@property(nonatomic, assign) int videoRenderType;

使用例

AVPConfig *config = [self.player getConfig];
// Metal レンダリングを有効化します。
config.videoRenderType = 1;
[self.player setConfig:config];
[self.player prepare];

外部字幕

説明

詳細なコード例については、「API-Example プロジェクト」の ExternalSubtitle モジュールをご参照ください。このプロジェクトは Objective-C をベースとしており、ApsaraVideo Player SDK for iOS のコア SDK 統合を実証しています。

ApsaraVideo Player SDK for iOS は、SRT、SSA、ASS、VTT 形式の外部字幕の追加および切り替えをサポートしています。

例:

  1. 字幕表示用のビューを作成します。

    異なるフォーマットごとに異なるビューを作成します。

    // カスタム subTitleLabel を初期化します。
    UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:frame];
    // カスタム subTitleLabel をカスタム superView に追加します。superView はカスタムインターフェイス内に存在する親ビューです。
    [superView addSubview:subTitleLabel];
  2. 字幕関連のリスナーを設定します。

    // 外部字幕が追加されたときのコールバック。
    - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL {}
    // 字幕ヘッダー情報のコールバック。
    - (void)onSubtitleHeader:(AliPlayer *)player trackIndex:(int)trackIndex Header:(NSString *)header{}
    // 字幕表示のコールバック。
    - (void)onSubtitleShow:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID subtitle:(NSString *)subtitle {
     subTitleLabel.text =subtitle;
     subTitleLabel.tag =subtitleID;
    }
    // 字幕非表示のコールバック。
    - (void)onSubtitleHide:(AliPlayer*)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID{
      [subTitleLabel removeFromSuperview];
    }
  3. 字幕トラックを追加します。

    [self.player addExtSubtitle:URL];
  4. 字幕トラックを切り替えます。

    [self.player selectExtSubtitle:trackIndexenable:YES];

外部字幕(レンダリングコンポーネントによるカスタムレンダリング)

WebVTT 外部字幕の完全サポートは、AliVttSubtitleView および AliVttRenderImpl を使用して実装されており、フォントサイズ、色、特定のフォントの柔軟なカスタマイズが可能です。

説明

ユースケース:

  • WebVTT 字幕スタイル(フォント、色、サイズなど)のカスタマイズ。

  • ApsaraVideo Player SDK 7.11.0 を統合し、AliVttSubtitleView を使用する。

  • アラビア語、中国語、日本語、韓国語などの多言語字幕を、自動フォントマッチングでサポートする。

重要

前提条件:

  • .ttf 形式のフォントファイルを Xcode プロジェクトに追加します。

  • 字幕リスナーを追加し、WebVTT コンテンツを取得できるようにします。

  • loadFontFromBundle メソッドがフォントを正常に読み込んでいること。

字幕スタイルのカスタマイズ手順

  1. カスタムレンダリング実装クラス(AliVttRenderImpl)を作成します。

    // CustomFontVttRenderImpl.h
    @interface CustomFontVttRenderImpl : AliVttRenderImpl
    @end
    
    // CustomFontVttRenderImpl.m
    @implementation CustomFontVttRenderImpl
    
    // 任意:フォント生成ロジックをオーバーライド
    - (UIFont *)customizeFont:(UIFont *)originalFont
             contentAttribute:(VttContentAttribute *)contentAttribute
                  contentText:(NSString *)text {
        
        // 例:コンテンツに基づいて自動的にフォントを選択
        if ([self containsArabicCharacters:text]) {
            return [UIFont fontWithName:@"NotoSansArabic-Regular" size:originalFont.pointSize];
        }
        if ([self containsCJKCharacters:text]) {
            return [UIFont fontWithName:@"NotoSansCJKsc-Regular" size:originalFont.pointSize];
        }
        
        return originalFont;
    }
    
    // 任意:色の変更を強制
    - (void)applyColorStyle:(NSMutableDictionary *)attrs
           contentAttribute:(VttContentAttribute *)contentAttribute {
        // 赤色を強制
        attrs[NSForegroundColorAttributeName] = [UIColor redColor];
    }
    
    // 任意:フォントサイズを拡大
    - (void)applyFontStyle:(NSMutableDictionary *)attrs
          contentAttribute:(VttContentAttribute *)contentAttribute
                   context:(RenderContext *)context {
        
        CGFloat originalSize = contentAttribute.fontSizePx / context.contentsScale;
        CGFloat newSize = originalSize * 2.0; // サイズを 2 倍に
    
        UIFont *font = [self generateFontWithName:contentAttribute.fontName
                                        fontSize:newSize
                                          isBold:contentAttribute.mBold
                                        isItalic:contentAttribute.mItalic];
        
        attrs[NSFontAttributeName] = font;
    }
    
    // ヘルパーメソッド:アラビア文字の検出
    - (BOOL)containsArabicCharacters:(NSString *)text {
        for (NSUInteger i = 0; i < text.length; i++) {
            unichar c = [text characterAtIndex:i];
            if ((c >= 0x0600 && c <= 0x06FF) || (c >= 0x0750 && c <= 0x077F)) {
                return YES;
            }
        }
        return NO;
    }
    
    // ヘルパーメソッド:CJK 文字の検出
    - (BOOL)containsCJKCharacters:(NSString *)text {
        for (NSUInteger i = 0; i < text.length; i++) {
            unichar c = [text characterAtIndex:i];
            if ((c >= 0x4E00 && c <= 0x9FFF) ||   // 中国語
                (c >= 0x3040 && c <= 0x309F) ||   // 日本語ひらがな
                (c >= 0xAC00 && c <= 0xD7AF)) {   // 韓国語
                return YES;
            }
        }
        return NO;
    }
    
    @end
  2. (任意)カスタムフォントを動的に読み込みます。

    - (void)loadCustomFontFromBundle:(NSString *)fontName {
        NSString *path = [[NSBundle mainBundle] pathForResource:fontName ofType:@"ttf"];
        if (path) {
            NSData *fontData = [NSData dataWithContentsOfFile:path];
            CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)fontData);
            CGFontRef fontRef = CGFontCreateWithDataProvider(provider);
            
            if (CTFontManagerRegisterGraphicsFont(fontRef, NULL)) {
                NSLog(@"フォント登録に成功しました: %@", fontName);
            } else {
                NSLog(@"フォント登録に失敗しました: %@", fontName);
            }
            
            CGFontRelease(fontRef);
            CGDataProviderRelease(provider);
        }
    }
  3. 字幕ビューを初期化し、カスタムレンダラーをバインドします。

    // 字幕ビューを作成します
    AliVttSubtitleView *subtitleView = [[AliVttSubtitleView alloc] init];
    
    // カスタムレンダラー ファクトリを設定します
    [subtitleView setRenderImplFactory:^AliVttRenderImpl*() {
        CustomFontVttRenderImpl *impl = [[CustomFontVttRenderImpl alloc] init];
        
        // 任意:フォントを事前に読み込みます
        [impl loadCustomFontFromBundle:@"LongCang-Regular"];
        
        return impl;
    }];
    
    // プレーヤーに関連付けます
    [player setExternalSubtitleView:subtitleView];
  4. プレーヤーの字幕コールバックを処理します。

    AVPDelegate で以下のメソッドを実装します:

    // 字幕ヘッダー(スタイルおよび領域定義を含む)
    - (void)onSubtitleHeader:(AliPlayer *)player trackIndex:(int)trackIndex Header:(NSString *)header {
        [self.subtitleView setVttHeader:player trackIndex:trackIndex Header:header];
    }
    
    // 字幕の表示
    - (void)onSubtitleShow:(AliPlayer *)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID subtitle:(NSString *)subtitle {
        [self.subtitleView show:player trackIndex:trackIndex subtitleID:subtitleID subtitle:subtitle];
    }
    
    // 字幕の非表示
    - (void)onSubtitleHide:(AliPlayer *)player trackIndex:(int)trackIndex subtitleID:(long)subtitleID {
        [self.subtitleView hide:player trackIndex:trackIndex subtitleID:subtitleID];
    }
    
    // 字幕の追加(トラックを有効化するために使用)
    - (void)onSubtitleExtAdded:(AliPlayer *)player trackIndex:(int)trackIndex URL:(NSString *)URL {
        [player selectExtSubtitle:trackIndex enable:YES];
    }

音声のみの再生

動画再生を無効にして音声トラックのみを再生します。prepare を呼び出す前にこの設定を行います。

AVPConfig *config = [self.player getConfig];
config.disableVideo = YES;
[self.player setConfig:config];

ソフトウェアデコーディングとハードウェアデコーディングの切り替え

iOS プレーヤー SDK は、H.264 および H.265 のハードウェアデコーディング機能を提供しており、enableHardwareDecoder というトグル機能を備えています。このトグル機能はデフォルトで有効になっており、ハードウェアデコーディングの初期化に失敗した場合、SDK は自動的にソフトウェアデコーディングに切り替わり、通常の動画再生を保証します。以下の例をご参照ください:

// ハードウェアデコーディングを有効化します。デフォルトで有効です。
self.player.enableHardwareDecoder = YES;

プレーヤーがハードウェアデコーディングからソフトウェアデコーディングに自動的に切り替わった場合、onPlayerEvent コールバックを通じて通知が送られます。以下の例をご参照ください:

-(void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString)eventWithString description:(NSString *)description {
    if (eventWithString == EVENT_SWITCH_TO_SOFTWARE_DECODER) {
        // ソフトウェアデコーディングに切り替わりました。
    }
}

H.265 アダプティブ再生

現在のデバイスモデルがクラウドベースの H.265 ブラックリストに含まれている場合、または H.265 ハードウェアデコーディングの初期化に失敗した場合、アダプティブフォールバックがトリガーされます。H.264 バックアップストリームが設定されている場合は、そのストリームが再生されます。設定されていない場合は、プレーヤーは H.265 ソフトウェアデコーディングにフォールバックします。

説明
  • この機能は、クラウドネイティブのアダプティブデコーディング付加価値サービス(VAS)を有効化した場合にのみ有効になります。ライセンス認証の申請には、Yida フォームの提出が必要です。

  • クラウドネイティブのアダプティブデコーディング付加価値サービスには、ハードウェアデコーディング互換性データの動的配信および H.265 から H.264 ストリームへのアダプティブフォールバックが含まれます。

  • この付加価値サービスが有効でない場合でも、ハードウェアデコーディングの初期化に失敗した場合、SDK は自動的にソフトウェアデコーディングに切り替わります。

バックアップストリームの構成例:

// アプリケーション層で元の URL とバックアップ URL のマップを管理します。
NSString* getBackupUrlCallback(AVPBizScene scene, AVPCodecType codecType, NSString* oriurl){
    NSMutableDictionary *globalMap = [AliPlayerViewController getGlobalBackupUrlMap];
    NSString *backupUrl = globalMap[oriurl];
    return backupUrl; 
}

[AliPlayerGlobalSettings setAdaptiveDecoderGetBackupURLCallback:getBackupUrlCallback];

ネットワーク状態に応じた動画解像度の切り替え

説明

iOS Player SDK は、アダプティブビットレート HLS および DASH 動画ストリームをサポートしています。prepare メソッドの実行が正常に完了した後、getMediaInfo を呼び出して各ビットレートストリームの情報を取得できます。このメソッドは TrackInfo オブジェクトを返します。以下の例をご参照ください:

AVPMediaInfo *info = [self.player getMediaInfo];
NSArray<AVPTrackInfo*>* tracks = info.tracks;

再生中に、プレーヤーの selectTrack メソッドを呼び出して再生中のストリームを切り替えることができます。SELECT_AVPTRACK_TYPE_VIDEO_AUTO を指定すると、アダプティブビットレートストリーミングが有効になります。以下の例をご参照ください:

// 特定のビットレートに切り替えます。
[self.player selectTrack:track.trackIndex];
// アダプティブビットレート切り替えを有効化します。
[self.player selectTrack:SELECT_AVPTRACK_TYPE_VIDEO_AUTO];

切り替えの結果は、onTrackChanged コールバックで返されます。以下の例をご参照ください:

- (void)onTrackChanged:(AliPlayer*)player info:(AVPTrackInfo*)info {
    if (info.trackType == AVPTRACK_TYPE_VIDEO) {
        // レンディションが変更されました。
    }
    // その他
}

任意: プレーヤーの selectTrack メソッドを呼び出して再生ストリームをアダプティブビットレートストリーミングに切り替える前に、構成を通じてアダプティブビットレート(ABR)切り替えにおける解像度の上限を設定できます。これにより、予期せぬ高ビットレートへの自動切り替えを防止できます。例:(プレーヤーが prepare メソッドを呼び出す前、またはリストプレーヤーが moveTo メソッドを呼び出す前に、以下のコードを呼び出すことを推奨します。これにより、構成が有効になります。)

AVPConfig *config = [self.player getConfig];
config.maxAllowedAbrVideoPixelNumber = 921600;// ABR の最大許容ピクセル数を 1280×720 に設定します。プレーヤーは、この値以下のピクセル数を持つ解像度のみに切り替えます。
[self.player setConfig:config];

スナップショットの取得

iOS Player SDK は、snapShot メソッドを提供しており、現在の動画のスクリーンショットを取得できます。このメソッドは生データをキャプチャし、bitmap として返します。コールバックメソッドは onCaptureScreen です。以下の例をご参照ください:

// スナップショットコールバック。
- (void)onCaptureScreen:(AliPlayer *)player image:(UIImage *)image {
    // スナップショットを処理します。
}
// 現在のフレームのスナップショットを取得します。
[self.player snapShot];
説明

スナップショットには UI は含まれません。

プレビュー

ApsaraVideo VOD の構成と組み合わせることで、プレビュー機能を実装できます。これは VidSts および VidAuth(推奨)再生の両方でサポートされています。構成手順については、「動画のプレビュー」をご参照ください。

プレビュー機能を設定した後は、setPreviewTime メソッドを使用して、VidPlayerConfigGen インターフェイスでプレビューの持続時間を設定します。次の例では、VidSts 再生メソッドを使用しています。

AVPVidStsSource *source = [[AVPVidStsSource alloc] init];
....
VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
[vp setPreviewTime:20];// 20 秒間のプレビュー
source.playConfig = [vp generatePlayerConfig];// 再生ソースに設定
...

プレビュー期間が設定されている場合、サーバーはその期間のコンテンツのみを返します。

説明

VidPlayerConfigGen は、さまざまなサーバー側リクエストパラメーターの設定をサポートしています。「リクエストパラメーターの説明」をご参照ください。

Referer の設定

iOS Player SDK は Referer の設定をサポートしています。コンソールの Referer ブラックリストおよびホワイトリストと併用することで、アクセス権限を制御できます。リクエストの Referer は、AVPConfig メソッドを使用して設定できます。以下の例は iOS Player SDK の構成です:

// まず構成を取得します。
AVPConfig *config = [self.player getConfig];
// Referer を設定します。
config.referer = referer;
....// その他の設定
// プレーヤーに構成を設定します。
[self.player setConfig:config];

User-Agent の設定

iOS プレーヤー SDK は、AVPConfig を使用して User-Agent(UA)ヘッダーを設定できます。このヘッダーを設定すると、プレーヤーは HTTP リクエストに UA ヘッダーを含めるようになります。以下の例をご参照ください:

// まず構成を取得します。
AVPConfig *config = [self.player getConfig];
// User-Agent を設定します。
config.userAgent = userAgent;
....// その他の設定
// プレーヤーに構成を設定します。
[self.player setConfig:config];

ネットワーク再試行回数およびタイムアウトの構成

iOS プレーヤー SDK のネットワークタイムアウト期間および再試行回数は、AVPConfig メソッドを使用して設定できます。以下の例をご参照ください:

// 現在の構成を取得します。
AVPConfig *config = [self.player getConfig];
// ネットワークタイムアウト期間を指定します。単位:ミリ秒。
config.networkTimeout = 5000;
// ネットワークタイムアウト時の最大再試行回数を指定します。再試行間隔は networkTimeout パラメーターの値です。値が 0 の場合、再試行は実行されません。アプリケーションが再試行ポリシーを決定します。デフォルト値は 2 です。
config.networkRetryCount = 2;
....// その他の設定を構成します。
// プレーヤーに設定を構成します。
[self.player setConfig:config];
説明
  • networkRetryCount が 0 より大きい場合、ネットワーク障害が発生したときにプレーヤーは networkRetryCount 回再試行し、再試行間隔は networkTimeout となります。

  • すべての再試行後にロード状態が継続する場合、onError イベントが AVPErrorModel.codeERROR_LOADING_TIMEOUT に設定してトリガーされます。

  • networkRetryCount0 に設定した場合、ネットワーク再試行のタイムアウト時にプレーヤーは onPlayerEvent コールバックを eventWithStringEVENT_PLAYER_NETWORK_RETRY に設定してトリガーします。その後、プレーヤーの reload メソッドを呼び出してネットワークを再読み込みしたり、その他の操作を実行したりできます。

キャッシュおよびレイテンシ制御の構成

プレーヤーにおいて、キャッシュ制御は非常に重要です。適切な構成を行うことで、起動速度の向上およびコマ落ちの低減を効果的に実現できます。iOS プレーヤー SDK は、AVPConfig を通じてキャッシュおよびレイテンシを構成するための制御インターフェイスを提供しています。以下の例をご参照ください:

// 構成を取得します。
AVPConfig *config = [self.player getConfig];
// 最大レイテンシを指定します。注:このパラメーターはライブストリーミングでのみ有効です。レイテンシが高い場合、プレーヤー SDK はフレームを同期して、レイテンシを指定された制限内に保ちます。
config.maxDelayTime = 5000;
// 最大バッファ持続時間を指定します。単位:ミリ秒。このパラメーターは、プレーヤーが一度にバッファリングできるデータの最大持続時間を指定します。
config.maxBufferDuration = 50000;
// ピークバッファ持続時間を指定します。単位:ミリ秒。ネットワーク状態が不良の場合にプレーヤーがデータをロードする際、バッファ済みデータの持続時間がこの値に達すると、ロードを停止します。
config.highBufferDuration = 3000;
// 起動バッファ持続時間を指定します。単位:ミリ秒。値が小さいほど、起動時のロード時間が短縮されますが、再生開始直後にプレーヤーがロード状態になる可能性があります。
config.startBufferDuration = 500;
// その他の設定を構成します。
// 構成をプレーヤーに適用します。
[self.player setConfig:config];
重要
  • バッファ持続時間は、startBufferDuration ≤ highBufferDuration ≤ maxBufferDuration を満たす必要があります。

  • 最大バッファ持続時間(maxBufferDuration)が 5 分を超える場合、過剰なメモリ使用を防ぐために、システムはデフォルトで 5 分の持続時間を使用します。

HTTP ヘッダーの設定

AVPConfig メソッドを使用して、プレーヤーのリクエストに HTTP ヘッダー パラメーターを追加できます。例:

// 構成を取得します。
AVPConfig *config = [self.player getConfig];
// ヘッダーを定義します。
NSMutableArray *httpHeaders = [[NSMutableArray alloc] init];
// 例:HTTPDNS を使用する場合、Host を設定します。
[httpHeaders addObject:@"Host:example.com"];
// ヘッダーを設定します。
config.httpHeaders = httpHeaders;
....// その他の設定を構成します。
// プレーヤーに設定を構成します。
[self.player setConfig:config];

ピクチャーインピクチャー(PiP)

説明

詳細なコード例については、「API-Example プロジェクト」の PictureInPicture モジュールをご参照ください。このプロジェクトは Objective-C をベースとしており、ApsaraVideo Player SDK for iOS のコア SDK 統合を実証しています。

説明
  • PiP には iOS 15 以降および ApsaraVideo Player SDK for iOS 5.4.9.0 以降が必要です。

  • ApsaraVideo Player SDK for iOS のバージョンが 5.5.2.0 より前の場合、PiP 機能は PiP の有効化/無効化およびアプリケーションがバックグラウンドにある際の PiP ウィンドウ表示のみを提供します。5.5.2.0 以降では、SDK は外部から PiP デリゲートを設定できるようになり、よりパーソナライズされた PiP 機能開発が可能になります。

  • PiP を使用するには、デバイスの設定(設定 > 一般 > ピクチャーインピクチャー)で PiP が有効になっていることを確認してください。

PiP の有効化

PiP(ピクチャーインピクチャー)機能を有効化すると、アプリケーションがバックグラウンドに移動しても、動画は小さなウィンドウで再生を継続します。アプリケーションをフォアグラウンドに戻すと、動画は元の再生形式で再生を再開します。PiP 機能は setPictureInPictureEnable トグルで制御され、プレーヤーが AVPEventPrepareDone 状態のときに有効化する必要があります。以下の例をご参照ください:

- (void)onPlayerEvent:(AliPlayer *)player eventType:(AVPEventType)eventType {
    switch (eventType) {
        case AVPEventPrepareDone:
        {
            [self.player setPictureInPictureEnable:YES];
        }
            break;
        default:
            break;
    }
}
説明

stop を呼び出して再生を停止する場合、まず setPictureInPictureEnable を呼び出して PiP を無効化し、その後 stop を呼び出します。

PiP デリゲートの設定

このセクションでは、ピクチャーインピクチャー(PiP)ウィンドウとプレーヤーウィンドウ間のインタラクションに関する一般的なコード例を提供します。これらの例には、PiP の一時停止、再生、早送り、早戻し、リプレイボタンの表示ロジックが含まれます。デリゲートメソッドの詳細については、「Player SDK デモ」、特に AliyunPlayer.framework フォルダ内の AliPlayerPictureInPictureDelegate.h ヘッダーファイルをご参照ください。

  1. PiP デリゲートを設定します。

    /**
    * @brief PiP デリゲートを設定します。
    */
    -(void) setPictureinPictureDelegate:(id<AliPlayerPictureInPictureDelegate>)delegate;
    
    
    // PiP デリゲートを設定します。
    [self.player setPictureinPictureDelegate:self];
  2. 変数を追加し、デリゲートインターフェイスを実装します。

    1. プレーヤーおよび PiP の状態を管理するグローバル変数を追加します。

      #import "YourUIViewController.h"
      #import <AliyunPlayer/AliyunPlayer.h>
      
      @interface YourUIViewController () <AVPDelegate, AliPlayerPictureInPictureDelegate>
      // プレーヤーインスタンス。
      @property (nonatomic, strong) AliPlayer *player;
      // プレーヤービューのコンテナ。
      @property (nonatomic, strong) UIView *playerView;
      // PiP が現在一時停止中かどうかを監視する。
      @property (nonatomic, assign) BOOL isPipPaused;
      // プレーヤーの現在の再生ステータスを監視する。再生イベントステータス変更リスナーの newStatus コールバックを通じて設定します。
      @property (nonatomic, assign) AVPStatus currentPlayerStatus;
      // PiP コントローラーを設定します。PiP が開始しようとするコールバックメソッド内でアクティブに設定する必要があります。ページが破棄される直前に nil に設定することを推奨します。
      @property (nonatomic, weak) AVPictureInPictureController *pipController;
      // プレーヤーの現在の再生進捗を監視する。現在の動画再生位置のコールバックの position パラメーターの値を currentPosition に設定します。
      @property (nonatomic, assign) int64_t currentPosition;
      
      @end
      説明

      pipController には weak または assign 修飾子を使用する必要があります。assign 修飾子を使用する場合、正しい変数を null に設定することを確認してください。

    2. onPlayerStatusChanged イベントを監視する際に、PiP コントローラーのステータスを更新します。

      - (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus {
          self.currentPlayerStatus = newStatus;
      
        if (_pipController) {
           [self.pipController invalidatePlaybackState];
         }
      }
    3. 再生イベントコールバックを監視する際に、以下のメソッドを呼び出して PiP コントローラーのステータスを更新します。

      - (void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
          if (eventType == AVPEventCompletion) {
            if (_pipController) {
             self.isPipPaused = YES; // 再生終了後、PiP ステータスを一時停止に変更します。
             [self.pipController invalidatePlaybackState];
          }
        } else if (eventType == AVPEventSeekEnd) {
          // シークが完了しました。
            if (_pipController) {
             [self.pipController invalidatePlaybackState];
          }
        }
      }
    4. リスナーを設定します。

      • PiP が開始しようとするコールバックを監視します。

        /**
         @brief ピクチャーインピクチャーが開始しようとしています。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         */
        - (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
            if (!_pipController) {
             self.pipController = pictureInPictureController;
          }
            self.isPipPaused = !(self.currentPlayerStatus == AVPStatusStarted);
          [pictureInPictureController invalidatePlaybackState];
        }
      • PiP が停止しようとしているコールバックを監視します。

        /**
         @brief ピクチャーインピクチャーが停止しようとしています。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         */
        - (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
            self.isPipPaused = NO;
          [pictureInPictureController invalidatePlaybackState];
        }
      • PiP が停止する前にユーザーインターフェースを復元するようデリゲートに指示するコールバックを監視します。

        /**
         @brief ピクチャーインピクチャーが停止する前にユーザーインターフェースを復元するようデリゲートに指示します。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         @param completionHandler システムがプレーヤーのユーザーインターフェースの復元を完了できるよう、YES を渡して呼び出します。
         */
        - (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
            if (_pipController) {
              _pipController = nil;
          }
          completionHandler(YES);
        }
      • PiP の現在の再生可能な時間範囲を設定するコールバックを監視します。

        /**
         @brief ピクチャーインピクチャー コントローラーに現在の再生可能な時間範囲を通知します。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         @return 現在の再生可能な時間範囲。
         */
         - (CMTimeRange)pictureInPictureControllerTimeRangeForPlayback:(nonnull AVPictureInPictureController *)pictureInPictureController layerTime:(CMTime)layerTime{
            Float64 current64 = CMTimeGetSeconds(layerTime);
        
            Float64 start;
            Float64 end;
        
            if (currentPosition <= self.player.duration) {
                double curPostion = self.currentPosition / 1000.0;
                double duration = self.player.duration / 1000.0;
                double interval = duration - curPostion;
                start = current64 - curPostion;
                end = current64 + interval;
                CMTime t1 = CMTimeMakeWithSeconds(start, layerTime.timescale);
                CMTime t2 = CMTimeMakeWithSeconds(end, layerTime.timescale);
                return CMTimeRangeFromTimeToTime(t1, t2);
            } else {
                return CMTimeRangeMake(kCMTimeNegativeInfinity, kCMTimePositiveInfinity);
            }
        }
      • PiP(ピクチャーインピクチャー)が一時停止中か再生中かを監視するコールバックです。

        /**
         @brief 一時停止または再生状態をユーザーインターフェースに反映します。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         @return 一時停止または再生中。
         */
        - (BOOL)pictureInPictureControllerIsPlaybackPaused:(nonnull AVPictureInPictureController *)pictureInPictureController{
            return self.isPipPaused;
        }
        説明

        このコールバックは PiP が開始する前にトリガーされます。この時点でこのコールバックの戻り値が false であることを確認してください。そうしないと、PiP を有効化できません。

      • ユーザーが早送りまたは早戻しをクリックした際に、再生進捗をプレーヤーに同期させるコールバックを監視します。

        /**
         @brief 早送りまたは早戻しボタンがクリックされました。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         @param skipInterval 早送りまたは早戻しの時間間隔。
         @param completionHandler シーク操作が完了したことを示すために呼び出す必要があるクロージャ。
         */
         - (void)pictureInPictureController:(nonnull AVPictureInPictureController *)pictureInPictureController skipByInterval:(CMTime)skipInterval completionHandler:(nonnull void (^)(void))completionHandler {
            int64_t skipTime = skipInterval.value / skipInterval.timescale;
            int64_t skipPosition = self.currentPosition + skipTime * 1000;
            if (skipPosition < 0) {
                skipPosition = 0;
            } else if (skipPosition > self.player.duration) {
                skipPosition = self.player.duration;
            }
            [self.player seekToTime:skipPosition seekMode:AVP_SEEKMODE_INACCURATE];
            [pictureInPictureController invalidatePlaybackState];
        }
      • PiP 内の一時停止または再生ボタンがクリックされた際に、必要な操作を実行するコールバックを監視します。

        /**
         @brief PiP 内の一時停止ボタンがクリックされました。
         @param pictureInPictureController ピクチャーインピクチャー コントローラー。
         @param playing 再生中かどうか。
         */
        - (void)pictureInPictureController:(nonnull AVPictureInPictureController *)pictureInPictureController setPlaying:(BOOL)playing {
            if (!playing){
              [self.player pause];
              self.isPipPaused = YES;
            } else {
              // 推奨:PiP 再生が完了し、再再生する必要がある場合、以下の if 文内のコードを追加実行できます。
              if (self.currentPlayerStatus == AVPStatusCompletion) {
                 [self.player seekToTime:0 seekMode:AVP_SEEKMODE_ACCURATE];
              }
        
              [self.player start];
              self.isPipPaused = NO;
          }
          [pictureInPictureController invalidatePlaybackState];
        }

アプリ内 PiP

デフォルトでは、アプリがバックグラウンドに移動すると PiP が有効化されます。アプリ内 PiP を実装するには、手動でその有効化を制御できます。まず、PiP が開始されているかどうかを判断します。

/**
 @brief PiP が開始されているかどうか。
 @param pictureInPictureController PiP コントローラー。
 @param isEnable PiP が開始されているかどうか。
 */
/****
 @brief PiP が有効かどうか。
 @param pictureInPictureController PiP コントローラー。
 @param isEnable 有効かどうか。
 */
- (void)pictureInPictureControllerIsPictureInPictureEnable:(nullable AVPictureInPictureController *)pictureInPictureController isEnable:(BOOL)isEnable;

PiP が有効化されている場合、自動有効化を無効化して手動で制御します。

- (void) pictureInPictureControllerIsPictureInPictureEnable:(nullable AVPictureInPictureController *) pictureInPictureController isEnable:(BOOL) isEnable
{
    if (isEnable && pictureInPictureController) {
        _pipController = pictureInPictureController;
        // PiP の自動開始を無効化
        if (@available(iOS 15.0, *)) {
            _pipController.canStartPictureInPictureAutomaticallyFromInline = false;
        }
    } else {
        _pipController = NULL;
    }
}

- (void) switchPip:(bool) enable {
    if (_pipController == nil) {
        return;
    }
    if (enable) {
        // PiP を開始
        [_pipController startPictureInPicture];
    } else {
        // PiP を終了
        [_pipController stopPictureInPicture];
    }
}

ライブ RTS フォールバック

説明

詳細なコード例については、「API-Example プロジェクト」の RtsLiveStream モジュールをご参照ください。このプロジェクトは Objective-C をベースとしており、ApsaraVideo Player SDK for iOS のコア SDK 統合を実証しています。

詳細については、「RTS ライブ再生」をご参照ください。

左右のサウンドチャンネルの切り替え

iOS プレーヤー SDK では、outputAudioChannel プロパティを使用して出力音声チャンネルを設定できます。入力ソースがステレオの場合、以下の方法を使用して左または右の音声チャンネルに切り替えることができます。入力ソースがモノラルの場合、この設定は影響しません。

説明

出力音声チャンネルの設定は、音声レンダリングおよび PCM データコールバックの両方に影響します。

// AVPOutputAudioChannel 列挙値を設定してチャンネルを切り替えます。
// AVP_AUDIO_CHANNEL_NONE:チャンネルを指定しません。入力ソースの音声チャンネルで再生します。これがデフォルト値です。
// AVP_AUDIO_CHANNEL_LEFT:左の音声チャンネルに切り替えて再生します。
// AVP_AUDIO_CHANNEL_RIGHT:右の音声チャンネルに切り替えて再生します。
self.player.outputAudioChannel = AVP_AUDIO_CHANNEL_NONE;

動画の背景色の設定

iOS Player SDK を使用して、レンダリング用の背景色を設定できます。API およびその使用方法は以下のとおりです:

API の例

/**
 @brief 動画の背景色を設定します。
 @param color 色
 */
/****
 @brief 動画の背景色を設定します。
 @param color 色
 */
-(void) setVideoBackgroundColor:(UIColor *)color;

使用方法

// パラメーターは 8 桁の 16 進数値です。8 桁は A(アルファ/透過度)、R(赤)、G(緑)、B(青)の順にペアでグループ化されます。
// 例:0x0000ff00 は緑を表します。
[self.player setVideoBackgroundColor:0x0000ff00]

VidAuth の再生ドメインの指定

VidAuth メソッドを使用すると、再生ドメインなどのパラメーターを指定できます。サポートされているフィールドの一覧については、「GetPlayInfo」をご参照ください。インターフェイスおよび使用手順は以下のとおりです:

API の例

/**
 @brief vid+playauth メソッドを使用して再生します。https://www.alibabacloud.com/help/zh/vod/user-guide/use-playback-credentials-to-play-videos を参照してください。
 @param source AVPVidAuthSource の入力タイプ。
 @see AVPVidAuthSource
 */
- (void)setAuthSource:(AVPVidAuthSource*)source;

使用方法

VidPlayerConfigGenerator インターフェイスを通じて playDomain フィールドを追加します。

VidPlayerConfigGenerator* gen = [[VidPlayerConfigGenerator alloc]init];
// playDomain フィールドを追加します。追加可能なフィールドについては、
// https://www.alibabacloud.com/help/zh/vod/developer-reference/api-vod-2017-03-21-getplayinfo を参照してください。
[gen addVidPlayerConfigByStringValue:@"playDomain" value: @"com.xxx.xxx"];
[source setPlayConfig:[gen generatePlayerConfig]];
[self.player setAuthSource:source]:

バックグラウンドデコーディング

バージョン 6.12.0 以降から、SDK はバックグラウンドデコーディングをサポートしています。有効化すると、アプリケーションがバックグラウンドにある場合でも、プレーヤーは動画ストリームのデコードおよび再生を継続できます。

// 値が 1 の場合、バックグラウンドデコーディングが有効化されます。値が 0 の場合、バックグラウンドデコーディングが無効化されます。デフォルト値は 0 です。
[self.player setOption:ALLOW_DECODE_BACKGROUND valueInt:1];

H.266 デコーディングプラグイン

H.266(Versatile Video Coding:VVC)は、同等の品質で大幅に低いビットレートを実現する次世代動画符号化規格です。H.266 デコーディング機能は、オンデマンド統合用に個別のプラグインとして提供されています。

前提条件

  1. Player またはオールインワン SDK V7.6.0 以降を使用します。

  2. Professional Edition ライセンスの権限付与が完了しました。詳細については、「Player SDK ライセンスの取得」をご参照ください。

  3. H.266 デコーディングプラグイン付きの ApsaraVideo Player は、ApsaraVideo トランスコーディング によってエンコードされた H.266 動画のみをサポートします。

プラグインの統合

Player SDK

CocoaPods(推奨)

依存関係を Podfile に追加します。

説明

iOS SDK の最新バージョンについては、「ApsaraVideo Player SDK for iOS のリリースノート」をご参照ください。

// x.x.x は ApsaraVideo Player SDK のバージョン番号と同じにする必要があります。
pod 'AliPlayerSDK_iOS_VVC_CODEC_PLUGIN', 'x.x.x'

ローカル統合

最新の iOS ApsaraVideo Player SDK をダウンロードします。vvcCodecPlugin.framwork を Frameworks、Libraries、Embedded Content に追加します。Embed を Embed & Sign に設定します。Framework Search Paths を構成します。詳細については、「ローカル統合」をご参照ください。

オールインワン SDK

CocoaPods(推奨)

依存関係を Podfile に追加します。

// x.x.x は統合する SDK のバージョン番号と同じにする必要があります。
pod 'AliVCSDK_Standard/AliPlayerSDK_iOS_VVC_CODEC', 'x.x.x'

ローカル統合

ダウンロードして、最新の iOS オールインワンパッケージを取得します。展開して、plugins/vvcCodecPlugin.framework をフレームワーク、ライブラリ、および埋め込みコンテンツに追加します。[埋め込み] を [埋め込みと署名] に設定します。フレームワーク検索パスを設定します。詳細については、「ローカル統合」をご参照ください。

プラグインの有効化

説明

v7.7.0 以降では、プラグインはデフォルトで有効化されており、手動での有効化は不要です。

[AliPlayerGlobalSettings enableCodecPlugin:@"vvc" valid:true];

関連するエラーコード

H.266 プラグインに関連するエラーコードについては、「さまざまなプラットフォームのプレーヤーに関する一般的な FAQ」をご参照ください。

再生ソースの自動更新

自動更新を有効化すると、認証の期限切れによる再生中断を防止できます。ソースの有効期限が切れた場合、プレーヤーは新しい URL を取得するためのリスナーをトリガーし、継続的かつスムーズな再生を保証します。

前提条件

  1. Player またはオールインワン SDK V7.9.0 以降を使用します。

  2. VidAuth ソース を使用するか、URL 署名 を構成します。

VidAuth ソース

API の例

/**
 @brief VidAuth ソースの有効期限切れ通知のコールバックを設定します。

 プレーヤーが現在の VidAuth ソースの有効期限が切れたことを検出した場合、このコールバックがトリガーされます。VidAuth ソースの有効期限切れには、PlayAuth の有効期限切れおよび再生 URL の有効期限切れが含まれます。
 このコールバック内で VidAuth ソースを更新し、`callback` を介して新しい VidAuth ソースオブジェクトを送信することで、安定的かつスムーズな動画再生を保証できます。

 @param callback VidAuth ソースの有効期限切れ時にトリガーされるコールバックブロック。
 このコールバックを使用して、プレーヤーに有効な `VidAuth` オブジェクトを返すことができます。
 */
/****
 @brief VidAuth ソースの有効期限切れ通知のコールバックを設定します。

 このメソッドは、プレーヤーが現在の VidAuth ソースの有効期限が切れたことを検出した場合にトリガーされます。
 このコールバック内で VidAuth ソースを更新し、`callback` を介して更新された VidAuth ソースを返すことで、
 中断のないスムーズな動画再生を保証できます。

 @param callback VidAuth ソースの有効期限切れ時にトリガーされるコールバックブロック。
 このコールバックを使用して、プレーヤーに有効な `VidAuth` オブジェクトを返すことができます。
 */
-(void)setOnVidAuthExpiredCallback:(void (^)(id expiredSource, id<AVPSourceRefreshCallback> callback))callback;

関数構成

関数構成

/**
 @protocol AVPSourceRefreshCallback
 @brief プレーヤーの再生ソースの更新結果を処理するためのプロトコルで、開発者が実装する必要があります。

 このプロトコルは、リソースの有効期限切れや更新が必要な場合など、プレーヤーが再生ソースの更新を要求した際に開発者に通知します。
 このプロトコルのメソッドは、更新結果(成功または失敗)を提供するために開発者に呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソースなど、更新ロジックを必要とするシナリオに適用されます。
 */
 /****
 @brief プレーヤーの再生ソースの更新結果を処理するためのプロトコルで、開発者が実装する必要があります。

 このプロトコルは、リソースの有効期限切れや更新が必要な場合など、プレーヤーが再生ソースの更新を要求した際に開発者に通知します。
 このプロトコルのメソッドは、更新結果(成功または失敗)を提供するために開発者に呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソースなど、更新ロジックを必要とするシナリオに適用されます。
 */
@protocol AVPSourceRefreshCallback <NSObject>

/**
 @brief 更新操作が成功した場合にプレーヤーから呼び出されます。
 @param newSource 更新された情報を含む新しい再生ソースオブジェクト。

 このメソッドは、更新操作が正常に完了したことを示します。開発者は、更新された `newSource` をプレーヤーに返す必要があります。
 これにより、プレーヤーは最新のリソースを読み込むことができます。
 */
 /****
 @brief 更新操作が成功した場合にプレーヤーから呼び出されます。
 
 @param newSource 更新された情報を含む新しい再生ソースオブジェクト。

 このメソッドは、更新操作が正常に完了したことを示します。開発者は、更新された `newSource` をプレーヤーに返す必要があります。
 これにより、プレーヤーは最新のリソースを読み込むことができます。
 */
- (void)onSuccess:(id)newSource;

/**
 @brief 更新操作が失敗した場合にプレーヤーから呼び出されます。
 @param errorMsg 失敗の理由を説明する文字列。

 このメソッドは、更新操作が失敗したことを示します。開発者は `errorMsg` を使用して失敗の詳細を取得し、
 後続の処理を適切に行うことができます。
 */
 /****
 @brief 更新操作が失敗した場合にプレーヤーから呼び出されます。
 
 @param errorMsg 失敗の理由を説明する文字列。

 このメソッドは、更新操作が失敗したことを示します。開発者は `errorMsg` を使用して失敗の詳細を取得し、
 後続の処理を適切に行うことができます。
 */
- (void)onError:(NSString *)errorMsg;

@end

使用方法

GetVideoPlayAuth 操作を呼び出すことで、動画の再生認証情報を取得できます。認証情報を取得し、自己署名を回避するには、ApsaraVideo VOD サーバー側 SDK を統合することを推奨します。詳細については、「OpenAPI Explorer」をご参照ください。

[self.player setOnVidAuthExpiredCallback:^(id expiredSource, id<AVPSourceRefreshCallback> callback) {
    // AVPVidAuthSource を取得します
    if ([expiredSource isKindOfClass:[AVPVidAuthSource class]]) {

        // ------------------- ユーザー実装開始 -------------------
        // アプリサーバーから新しい PlayAuth を取得する独自の関数を呼び出します。
        // clinetGetPlayAuthFunction はサンプル関数名です。独自の実装に置き換えてください。
        [self clinetGetPlayAuthFunction:vid success:^(NSString* newPlayAuth){
            // 1. 新しい認証情報の取得が成功した場合のコールバック
            [vidAuth setPlayAuth:newPlayAuth];
            // 2. SDK コールバックを介してプレーヤーに更新されたオブジェクトを返します
            [callback onSuccess:vidAuth];
        } failure:^(NSString* errorMsg) {
            // 認証情報の取得に失敗した場合のコールバック。
            // errorMsg には詳細なエラー情報が含まれます。
            [callback onError:errorMsg];
        }];
        // ------------------- ユーザー実装終了 -------------------
    }
}];

URL ソース

API の例

/**
 @brief URL ソースの有効期限切れ通知のコールバックを設定します。

 プレーヤーが現在の URL ソースの有効期限が切れたことを検出した場合、このコールバックがトリガーされます。
 このコールバック内で URL ソースを更新し、`callback` を介して新しい URL ソースを返すことで、中断のない動画再生を保証できます。

 @note URL 署名の構成については、Alibaba Cloud のドキュメントを参照してください:
 https://www.alibabacloud.com/help/zh/vod/user-guide/configure-url-signing?spm=a2c4g.11186623.0.0.560c4140fGh8MW
 
 @param callback URL ソースの有効期限切れ時にトリガーされるコールバックブロック。
 このコールバックを使用して、プレーヤーに有効な `URLSource` オブジェクトを返すことができます。
 */
 /****
 @brief URL ソースの有効期限切れ通知のコールバックを設定します。

 このメソッドは、プレーヤーが現在の URL ソースの有効期限が切れたことを検出した場合にトリガーされます。
 このコールバック内で URL ソースを更新し、`callback` を介して更新された URL ソースを返すことで、
 中断のない動画再生を保証できます。

 @param callback URL ソースの有効期限切れ時にトリガーされるコールバックブロック。
 このコールバックを使用して、プレーヤーに有効な `URLSource` オブジェクトを返すことができます。
 */
-(void)setOnURLSourceExpiredCallback:(void (^)(id expiredSource, id<AVPSourceRefreshCallback> callback))callback;

関数構成

関数構成

/**
 @protocol AVPSourceRefreshCallback
 @brief プレーヤーの再生ソースの更新結果を処理するためのプロトコルで、開発者が実装する必要があります。

 このプロトコルは、リソースの有効期限切れや更新が必要な場合など、プレーヤーが再生ソースの更新を要求した際に開発者に通知します。
 このプロトコルのメソッドは、更新結果(成功または失敗)を提供するために開発者に呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソースなど、更新ロジックを必要とするシナリオに適用されます。
 */
 /****
 @brief プレーヤーの再生ソースの更新結果を処理するためのプロトコルで、開発者が実装する必要があります。

 このプロトコルは、リソースの有効期限切れや更新が必要な場合など、プレーヤーが再生ソースの更新を要求した際に開発者に通知します。
 このプロトコルのメソッドは、更新結果(成功または失敗)を提供するために開発者に呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソースなど、更新ロジックを必要とするシナリオに適用されます。
 */
@protocol AVPSourceRefreshCallback <NSObject>

/**
 @brief 更新操作が成功した場合にプレーヤーから呼び出されます。
 @param newSource 更新された情報を含む新しい再生ソースオブジェクト。

 このメソッドは、更新操作が正常に完了したことを示します。開発者は、更新された `newSource` をプレーヤーに返す必要があります。
 これにより、プレーヤーは最新のリソースを読み込むことができます。
 */
 /****
 @brief 更新操作が成功した場合にプレーヤーから呼び出されます。
 
 @param newSource 更新された情報を含む新しい再生ソースオブジェクト。

 このメソッドは、更新操作が正常に完了したことを示します。開発者は、更新された `newSource` をプレーヤーに返す必要があります。
 これにより、プレーヤーは最新のリソースを読み込むことができます。
 */
- (void)onSuccess:(id)newSource;

/**
 @brief 更新操作が失敗した場合にプレーヤーから呼び出されます。
 @param errorMsg 失敗の理由を説明する文字列。

 このメソッドは、更新操作が失敗したことを示します。開発者は `errorMsg` を使用して失敗の詳細を取得し、
 後続の処理を適切に行うことができます。
 */
 /****
 @brief 更新操作が失敗した場合にプレーヤーから呼び出されます。
 
 @param errorMsg 失敗の理由を説明する文字列。

 このメソッドは、更新操作が失敗したことを示します。開発者は `errorMsg` を使用して失敗の詳細を取得し、
 後続の処理を適切に行うことができます。
 */
- (void)onError:(NSString *)errorMsg;

@end

使用方法

[self.player setOnURLSourceExpiredCallback:^(id expiredSource, id<AVPSourceRefreshCallback> callback) {
    // AVPUrlSource を取得します
    if ([expiredSource isKindOfClass:[AVPUrlSource class]]) {
        AVPUrlSource *expiredUrlSource = (AVPUrlSource *)expiredSource;
        NSString *expiredUrl = [expiredUrlSource.playerUrl absoluteString];

        // auth_key が含まれているかどうかを確認します
        if (![expiredUrl containsString:@"auth_key="]) {
            return;
        }

        // 1. 有効期限切れの URL から元の URL を抽出します
        NSRange authKeyQuestionRange = [expiredUrl rangeOfString:@"?auth_key="];
        NSRange authKeyAmpersandRange = [expiredUrl rangeOfString:@"&auth_key="];

        NSInteger authKeyIndex = NSNotFound;
        if (authKeyQuestionRange.location != NSNotFound) {
            authKeyIndex = authKeyQuestionRange.location;
        } else if (authKeyAmpersandRange.location != NSNotFound) {
            authKeyIndex = authKeyAmpersandRange.location;
        }

        NSString *originalUrl = nil;
        if (authKeyIndex != NSNotFound) {
            originalUrl = [expiredUrl substringToIndex:authKeyIndex];
        } else {
            // auth_key が見つからない場合、URL 全体を元の URL と見なします
            originalUrl = expiredUrl;
        }

        // 2. 新しい認証パラメーター(authKey および有効期限)を準備します
        // クラスメンバー authKey が有効な場合、authKey を使用します
        NSString *key = (self.authKey.length > 0) ? self.authKey : @"";
        if (!NOT_EMPTY(key)) {
            [callback onError:@"REFRESH_ERROR:key fail"];
            return;
        }       
        
        // クラスメンバー validTime が有効な場合、validTime を使用します。それ以外の場合はデフォルト値を使用します
        NSTimeInterval validTime = (self.validTime > 0) ? self.validTime : 3600; // デフォルトは 3600 秒
        NSTimeInterval newExpireTime = [[NSDate date] timeIntervalSince1970] + validTime;

         // 3. CdnAuthUtil を使用して新しい認証済み URL を生成します(方法 A)
        NSString *newAuthUrl = [CdnAuthUtil aAuthWithUri:originalUrl key:key exp:newExpireTime];
        AVPUrlSource *resultSource = [[AVPUrlSource alloc] urlWithString:newAuthUrl];

        // 4. コールバック処理
        if (newAuthUrl) {
            [callback onSuccess:resultSource];
        } else {
            [callback onError:@"REFRESH_ERROR:refresh fail"];
        }
    }
}];

ユーティリティ関数

たとえば、署名方法 A を使用します。

ユーティリティ関数

#import "CdnAuthUtil.h"
#import <CommonCrypto/CommonDigest.h>

@implementation CdnAuthUtil

#pragma mark - Auth Method A
+ (NSString *)aAuthWithUri:(NSString *)uri key:(NSString *)key exp:(NSTimeInterval)exp {
    NSDictionary *components = [self matchUri:uri];
    if (!components) return nil;

    NSString *scheme = components[@"scheme"];
    NSString *host = components[@"host"];
    NSString *path = components[@"path"];
    NSString *args = components[@"args"];

    NSString *rand = @"0";
    NSString *uid = @"0";

    NSString *sstring = [NSString stringWithFormat:@"%@-%lld-%@-%@-%@", path, (long long)exp, rand, uid, key];
    NSString *hashvalue = [self md5sum:sstring];
    NSString *authKey = [NSString stringWithFormat:@"%lld-%@-%@-%@", (long long)exp, rand, uid, hashvalue];

    if (args.length > 0) {
        return [NSString stringWithFormat:@"%@%@%@%@&auth_key=%@", scheme, host, path, args, authKey];
    } else {
        return [NSString stringWithFormat:@"%@%@%@%@?auth_key=%@", scheme, host, path, args, authKey];
    }
}

#pragma mark - Private Helper: MD5
+ (NSString *)md5sum:(NSString *)src {
    const char *cStr = [src UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (unsigned int)strlen(cStr), result);

    NSMutableString *hexString = [NSMutableString string];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [hexString appendFormat:@"%02x", result[i]];
    }
    return hexString.copy;
}

#pragma mark - Private Helper: Regex Match
+ (NSDictionary *)matchUri:(NSString *)uri {
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(https?://)?([^/?]+)(/[^?]*)?(\\?.*)?$"
                                  options:0
                                  error:&error];
    if (error) {
        NSLog(@"Regex error: %@", error.localizedDescription);
        return nil;
    }

    NSTextCheckingResult *match = [regex firstMatchInString:uri
                                   options:0
                                   range:NSMakeRange(0, uri.length)];
    if (!match) return nil;

    __block NSString *scheme = nil, *host = nil, *path = nil, *args = nil;

    void (^setStringFromRange)(NSInteger, NSString**) = ^(NSInteger idx, NSString **outStr) {
        NSRange range = [match rangeAtIndex:idx];
        if (range.location != NSNotFound && range.length > 0) {
            *outStr = [uri substringWithRange:range];
        } else {
            *outStr = nil;
        }
    };

    setStringFromRange(1, &scheme);
    setStringFromRange(2, &host);
    setStringFromRange(3, &path);
    setStringFromRange(4, &args);

    // デフォルト値の処理
    if (!scheme) scheme = @"http://";
    if (!path) path = @"/";

    return @{
        @"scheme": scheme,
        @"host": host,
        @"path": path,
        @"args": args ?: @""
        };
}
@end

パフォーマンス

再生シナリオの設定

再生シナリオを設定すると、バッファ設定および機能トグルを含む最適なパラメーターが自動的に構成され、setConfig インターフェイスを通じて行ったカスタム設定(カスタム設定が優先されます)は維持されます。

説明
  • 再生シナリオを設定した後、getConfig インターフェイスを使用してパラメーター構成を確認できます。

API の例

/**
 @brief プレーヤーのシナリオを設定します。
 @param scene プレーヤーのシナリオ。
 @see AVPScenario
 */
/****
 @brief プレーヤーのシーンを設定します。
 @param scene プレーヤーのシーン。
 @see AVPScene
 */
-(void) setPlayerScene:(AVPScene)scene;

再生シナリオ

typedef enum _AVPScene {
    /**
     * シナリオ:なし
     */
    /****
     * シナリオなし
     */
    SceneNone,
    /**
     * 長尺動画シナリオ:30 分を超える動画に適用
     */
    /****
     * 長尺動画シナリオ:30 分を超える動画に適用
     */
    SceneLong,
    /**
     * 中尺動画シナリオ:5~30 分の動画に適用
     */
    /****
     * 中尺動画シナリオ:5~30 分の動画に適用
     */
    SceneMedium,
    /**
     * 短尺動画シナリオ:5 分以内の動画に適用
     */
    /****
     * 短尺動画シナリオ:0 秒~5 分の動画に適用
     */
    SceneShort,
    /**
     * ライブストリーミングシナリオ
     */
    /****
     * ライブストリーミングシナリオ
     */
    SceneLive,
    /**
     * 超低遅延ライブストリーミングシナリオ
     */
    /****
     * RTS ライブストリーミングシナリオ
     */
    SceneRTSLive
} AVPScene;

使用方法

// 短尺動画シナリオを設定します
[self.player setPlayerScene:SceneShort];

// 中尺動画シナリオを設定します
[self.player setPlayerScene:SceneMedium]; 

// 長尺動画シナリオを設定します
[self.player setPlayerScene:SceneLong];  

// ライブストリーミングシナリオを設定します
[self.player setPlayerScene:SceneLive];   

プリレンダリング

ApsaraVideo Player SDK for iOS は、再生開始前に初回フレームを迅速にレンダリングする機能をサポートしており、起動速度を向上させます。

説明
  1. この機能はデフォルトで無効化されています。

  2. ViewPrepare を呼び出す前に設定する必要があります。これにより、View 上でフレームのレンダリングが準備されます。

  3. 有効化すると、準備完了および初回フレームレンダリングのイベント順序が変更されます。無効化時は、準備完了が先に発生し、その後に初回フレームレンダリングが発生します。有効化時は、デコードおよびレンダリングの速度に応じて、初回フレームレンダリングが準備完了よりも先に発生する場合があります。ただし、再生には影響しません。

例:

[self.player setOption:ALLOW_PRE_RENDER valueInt:1];

ローカルキャッシュ

説明

詳細なコード例については、「API-Example プロジェクト」の PreloadUrl モジュールをご参照ください。このプロジェクトは Objective-C をベースとしており、ApsaraVideo Player SDK for iOS のコア SDK 統合を実証しています。

ApsaraVideo Player SDK for iOS は、起動速度およびシーク速度の向上、繰り返し再生時のコマ落ちの低減、および帯域幅の節約のためにローカルキャッシュを提供しています。

ローカルキャッシュの有効化

ローカルキャッシュ機能はデフォルトで無効化されています。この機能を使用するには、手動で有効化する必要があります。AliPlayerGlobalSettings を使用して enableLocalCache でこの機能を制御できます。以下の例をご参照ください:

/**
 * ローカルキャッシュを有効化します。有効化すると、ローカルファイルにキャッシュされます。
 * @param enable: ローカルキャッシュ機能のスイッチ。true:有効、false:無効。デフォルトは無効です。
 * @param maxBufferMemoryKB: V5.4.7.1 以降で非推奨。効果はありません。
 * @param localCacheDir: 必須です。ローカルキャッシュファイルのディレクトリ。絶対パスを指定する必要があります。
 */
[AliPlayerGlobalSettings enableLocalCache:true maxBufferMemoryKB:1024 localCacheDir:@""];

/**
 @brief ローカルキャッシュファイルの自動クリア設定。
 @param expireMin: V5.4.7.1 以降で非推奨。効果はありません。
 @param maxCapacityMB: 最大キャッシュ容量(MB)。デフォルトは 20 GB です。クリーンアップ時、合計キャッシュ容量がこのサイズを超える場合、キャッシュアイテムの最終キャッシュ時刻に基づいて古いキャッシュファイルが順次削除され、容量が最大キャッシュ容量以下になるまで続けられます。
 @param freeStorageMB: 最小空きディスク領域(MB)。デフォルトは 0 です。クリーンアップ時、最大キャッシュ容量と同様に、現在のディスク空き領域がこの値より小さい場合、キャッシュファイルが同様のルールで順次削除され、空き領域がこの値以上になるか、すべてのキャッシュがクリアされるまで続けられます。
 */
[AliPlayerGlobalSettings setCacheFileClearConfig:0 maxCapacityMB:0 freeStorageMB:0];

/**
 * 読み込まれた URL のハッシュ値を取得するためのコールバック。URL の一意の ID として使用されます。各 URL が異なることを保証する必要があります。
 */

// この関数を自分で実装し、setCacheUrlHashCallback にその関数ポインターを渡す必要があります。
static NSString *CaheUrlHashHandle(NSString *url) {
    return @"xxx";
}

[AliPlayerGlobalSettings setCacheUrlHashCallback:&CaheUrlHashHandle];
説明
  • 動画ファイルの再生 URL に認証パラメーターが含まれている場合、動画ファイルのローカルキャッシュおよび再生中に認証パラメーターの値が変化します。setCacheUrlHashCallback 操作を呼び出して、認証パラメーターを削除した後に MD5 ハッシュ値を計算できます。たとえば、http://****.mp4?aaa は認証パラメーターを含む動画ファイルの再生 URL です。この場合、動画ファイルがロードされる際に、URL http://****.mp4 が MD5 ハッシュ値の計算に使用されます。ただし、暗号化された M3U8 動画のキー URL から認証パラメーターを削除した後に MD5 ハッシュ値を計算すると、同じキー URL で異なる動画がヒットするため、再生が失敗します。解決策: setCacheUrlHashCallback コールバック内で、再生 URL http(s)://xxxxx.m3u8?aaaa からのみ認証パラメーターを削除し、キー URL http(s)://yyyyy?bbbb からは削除しないでください。进阶功能-本地缓存.png

  • サーバーが HTTP および HTTPS の両方のプロトコルをサポートしているが、同じメディアファイルを指している場合、MD5 値の計算前にリクエストヘッダーを除外または統一する必要があります。たとえば:

    • 動画再生 URL が https://****.mp4 および http://****.mp4 の場合、MD5 値の計算には ****.mp4 を使用します。

    • 動画再生 URL が https://****.mp4 の場合、MD5 値の計算前に http://****.mp4 に統一します。

  • Player SDK 5.5.4.0 以降では、動画再生 URL に認証パラメーターが含まれており、再生プロトコルが HLS の場合、AVPConfig.enableStrictAuthMode フィールドを設定して、異なる認証モードを選択できます(以前のバージョンではデフォルト値は false です。7.13.0 以降ではデフォルト値は true です。):

    • 非 Strict 認証(false):認証がキャッシュされます。以前に一部のメディアがキャッシュされていた場合、プレーヤーはキャッシュされた認証を使用して未キャッシュの部分を要求します。URL 認証の有効期間が短い場合、または一時停止後に長時間経過して再生を再開する場合、認証が期限切れになる可能性があります。再開時の期限切れ認証を処理するには、「再生ソースの自動更新」機能と組み合わせることを推奨します。

    • Strict 認証(true):認証はキャッシュされません。すべての起動時に認証が実行されるため、ネットワーク接続がないと起動に失敗します。

単一の URL に対するローカルキャッシュの有効化または無効化

単一の URL に対してローカルキャッシュ機能を無効化したい場合、player config で設定できます。以下の例をご参照ください:

// まず構成を取得します。
AVPConfig *config = [self.player getConfig];
// 再生 URL に対するローカルキャッシュの有効化。デフォルトは true です。AliPlayerGlobalSettings でローカルキャッシュが有効化されており、ここでも有効化(true に設定)されている場合、この URL のローカルキャッシュが有効になります。ここでは false に設定した場合、この URL のローカルキャッシュは無効化されます。
config.enableLocalCache = false;
....// その他の設定

// プレーヤーに構成を設定します。
[self.player setConfig:config];

デフォルトのキャッシュパスの使用

キャッシュにデフォルトのパスを使用したい場合、AliPlayerGlobalSettings を以下のように構成できます。

[AliPlayerGlobalSettings enableLocalCache:true];

プリロード

ApsaraVideo Player SDK for iOS は、ローカルキャッシュのアップグレード版であるプリロード機能を提供しています。これにより、再生開始前に動画の一部をキャッシュにダウンロードすることで、起動速度が向上します。

プリロードの制限:

  • MP4、MP3、FLV、HLS などの単一メディアファイルをサポートします。

説明

デフォルトでは、SDK は現在再生中の動画に干渉しないようにプリロードのネットワークリクエストをスケジュールします。プリロードリクエストは、バッファされたコンテンツが特定のしきい値に達した後にのみ送信されます。これを無効化してリクエストをリアルタイムで管理するには、以下を使用します:

[AliPlayerGlobalSettings enableNetworkBalance:false];
  1. ローカルキャッシュ」で説明されているように、ローカルキャッシュを有効化します。

  2. データソースを設定します。

    VidAuth(推奨)

    AVPVidAuthSource* vidAuthSource = [[AVPVidAuthSource alloc] init];
    [vidAuthSource setVid:@"Vid 情報"]; // 必須。動画 ID(VideoId)。
    [vidAuthSource setPlayAuth:@"<yourPlayAuth>"]; // 必須。再生認証情報。ApsaraVideo VOD の GetVideoPlayAuth 操作を呼び出して生成する必要があります。
    [vidAuthSource setRegion:@"アクセスリージョン"]; // プレーヤー SDK V5.5.5.0 以降では、このパラメーターは非推奨です。リージョンを設定する必要はありません。プレーヤーが自動的にリージョンを解析します。プレーヤー SDK V5.5.5.0 より前のバージョンでは、このパラメーターは必須です。ApsaraVideo VOD のアクセスリージョン。デフォルトは cn-shanghai です。
    [vidAuthSource setQuality:@"選択された解像度"]; //"AUTO" はアダプティブビットレートを表します。

    VidSts

    AVPVidStsSource* vidStsSource = [[AVPVidStsSource alloc] init];
    [vidStsSource setVid: @"Vid 情報"]; // 必須。動画 ID(VideoId)。
    [vidStsSource setRegion:@"アクセスリージョン"]; // 必須。ApsaraVideo VOD のアクセスリージョン。デフォルトは cn-shanghai です。
    [vidStsSource setSecurityToken: @"<yourSecurityToken>"]; // 必須。STS セキュリティトークン。STS の AssumeRole 操作を呼び出して生成する必要があります。
    [vidStsSource setAccessKeySecret: @"<yourAccessKeySecret>"]; // 必須。一時的な STS AccessKey ペアの AccessKey Secret。STS の AssumeRole 操作を呼び出して生成する必要があります。
    [vidStsSource setAccessKeyId: @"<yourAccessKeyId>"]; // 必須。一時的な STS AccessKey ペアの AccessKey ID。STS の AssumeRole 操作を呼び出して生成する必要があります。
    [vidStsSource setQuality:@"選択された解像度"]; //"AUTO" はアダプティブビットレートを表します。

    UrlSource

    NSString* url = @"再生 URL"; // 必須。再生 URL。サードパーティの VOD URL または ApsaraVideo VOD の再生 URL を指定できます。
    AVPUrlSource* urlSource = [[AVPUrlSource alloc]urlWithString:url];
  3. タスクパラメーターを設定します。

    説明

    これはマルチビットレート動画にのみ適用されます。setDefaultBandWidthsetDefaultResolutionsetDefaultQuality のいずれかを選択できます。

    AVPPreloadConfig *config = [[AVPPreloadConfig alloc]init];
    // マルチビットレートストリームのプリロードビットレートを設定します。
    [config setDefaultBandWidth:400000];
    // マルチビットレートストリームのプリロード解像度を設定します。
    [config setDefaultResolution:640 * 480];
    // マルチビットレートストリームのプリロード品質を設定します。
    [config setDefaultQuality:@"FD"];
    // プリロード期間を設定します。
    [config setDuration:1000];
  4. タスクリスナーを追加します。

    コードを表示するには展開

    @interface YourViewController () <OnPreloadListener>
    
    @property(nonatomic,strong) AliMediaLoaderV2* vodMedialoader; // プリローダー
    @property(nonatomic,strong) AVPVidAuthSource* vidSource; // vidAuth データソース
    @property(nonatomic,strong) AVPUrlSource* urlSource; // url データソース
    @property(nonatomic,strong) AVPVidStsSource* vidStsSource; // vidSts データソース
    
    @end
    
    @implementation YourViewController
    
    - (void)onCompleted:(NSString *)taskId urlOrVid:(NSString *)urlOrVid {
        NSLog(@"現在のタスク (%@) が完了しました:%@", taskId,urlOrVid);
    }
    
    - (void)onError:(NSString *)taskId urlOrVid:(NSString *)urlOrVid errorModel:(AVPErrorModel *)errorModel {
        NSLog(@"例外が発生しました:%@", urlOrVid);
    }
    
    - (void)onCanceled:(NSString *)taskId urlOrVid:(NSString *)urlOrVid {
        NSLog(@"タスクがキャンセルされました:%@", urlOrVid);
    }
    
    @end
  5. タスクをビルドし、MediaLoaderV2 インスタンスに追加して、プリロードを開始します。

    VidAuth(推奨)

    // プリロードタスクをビルドします。
    AVPPreloadTask* mPreloadTask = [[AVPPreloadTask alloc]initWithVidAuthSource:vidAuthSource preloadConfig:config];
    // MediaLoaderV2 インスタンスを取得します。
    AliMediaLoaderV2* vodMedialoader = [AliMediaLoaderV2 shareInstance];
    // タスクを追加してプリロードを開始します。
    NSString* taskId = [vodMedialoader addTask:mPreloadTask listener:self];

    VidSts

    // プリロードタスクをビルドします。
    AVPPreloadTask* mPreloadTask = [[AVPPreloadTask alloc]initWithVidStsSource:vidStsSource preloadConfig:config];
    // MediaLoaderV2 インスタンスを取得します。
    AliMediaLoaderV2* vodMedialoader = [[AliMediaLoaderV2 alloc]init];
    // タスクを追加してプリロードを開始します。
    NSString* taskId = [vodMedialoader addTask:mPreloadTask listener:self];

    UrlSource

    // プリロードタスクをビルドします。
    AVPPreloadTask* mPreloadTask = [[AVPPreloadTask alloc]initWithUrlSource:urlSource preloadConfig:config];
    // MediaLoaderV2 インスタンスを取得します。
    AliMediaLoaderV2* vodMedialoader = [[AliMediaLoaderV2 alloc]init];
    // タスクを追加してプリロードを開始します。
    NSString* taskId = [vodMedialoader addTask:mPreloadTask listener:self];
  6. 任意: タスクを管理します。

    [vodMedialoader cancelTask:taskId];// 指定されたタスク ID のプリロードタスクをキャンセルします。
    [vodMedialoader pauseTask:taskId];// 指定されたタスク ID のプリロードタスクを一時停止します。
    [vodMedialoader resumeTask:taskId];// 指定されたタスク ID のプリロードタスクを再開します。
  7. 任意: 読み込まれたファイルを削除します。

    必要に応じて読み込まれたファイルを削除して、スペースを節約できます。SDK は削除インターフェイスを提供していません。アプリ内の読み込みディレクトリにあるファイルを削除する必要があります。

動的プリロード

動的プリロードポリシーにより、現在の動画のキャッシュおよびプリロードされるアイテム数を制御することで、再生体験とコストのバランスを取ることができます。

コードを表示するには展開

// 推奨構成と動的プリロードを有効化します。
[self.listPlayer setScene:AVP_SHORT_VIDEO];

// ベースのプリロード期間を設定します。
// プリロード期間を 1000 ms に設定します。
AVPPreloadConfig *config = [[AVPPreloadConfig alloc] init];
config.preloadDuration = 1000;
[self.listPlayer updatePreloadConfig:config];

// プリロードするアイテム数を設定します。両方向をサポートします。
// 1 は後方にプリロードするアイテム数、3 は前方にプリロードするアイテム数です。
[self.listPlayer setPreloadCount:1 nextCount:3];

// 動的プリロードの減少オフセットを設定します。
[self.listPlayer enableStrategy:AVP_STRATEGY_DYNAMIC_PRELOAD enable:true];
[self.listPlayer setStrategyParam:AVP_STRATEGY_DYNAMIC_PRELOAD strategyParam:@"{\"algorithm\": \"sub\",\"offset\": \"200\"}"];

マルチビットレート HLS 動画のプリロード

listPlayer 内のマルチビットレート HLS 動画では、現在の再生解像度に一致するストリームをプリロードし、プリロードモードを選択できます。

サポートされているプリロードモードを表示するには展開

typedef enum AVPMultiBitratesMode : NSUInteger {
    /**
     * デフォルト構成。デフォルトのビットレートを再生およびプリロードします。
     */
    /****
     * デフォルトモード。ストリームのデフォルトビットレートを再生およびプリロードします。
     */
    AVPMultiBitratesMode_Default = 0,
    /**
     * 初回フレーム優先構成。プリロードが完了したビットレートで動画の再生が開始されます。
     */
    /****
     * 初回フレームコスト(FC)優先。初回フレームコストを削減します。プリロードされた HLS ストリームのビットレートのみを再生します。
     */
    AVPMultiBitratesMode_FCPrio = 1,
    /**
     * 初回フレームとスムーズな再生のバランスを取ります。切り替え(moveToNext)前後で動画のビットレートは一貫しており、初回フレームのパフォーマンスも考慮されます。
     */
    /****
     * 初回フレームとスムーズな再生。moveToNext の前後で同じビットレートを再生します。
     */
    AVPMultiBitratesMode_FC_AND_SMOOTH = 2,
    /**
     * スムーズな再生優先構成。前の動画のビットレートで動画の再生が開始されます。
     */
    /****
     * スムーズな再生優先。moveToNext の前後で同じビットレートを再生します。
     */
    AVPMultiBitratesMode_SmoothPrio = 3,
} AVPMultiBitratesMode;

統合コードを表示するには展開

// マルチビットレート読み込みモードを選択します。
[self.listPlayer->SetMultiBitratesMode(preLoadMode)];

// (任意) 起動ビットレートを選択します。
[self.listPlayer setDefaultBandWidth:defaultBandWidth];

// (任意) preparedone コールバックで、ABR モードを選択します。
-(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType {
    switch (eventType) {
        case AVPEventPrepareDone: {
            [self.listPlayer selectTrack:-1];
        }
            break;
        case AVPEventFirstRenderedStart: {
        }
            break;
        default:
            break;
    }
}

ダウンロード速度の取得

onCurrentDownloadSpeed コールバックで、現在再生中の動画のダウンロード速度を取得します。

- (void)onCurrentDownloadSpeed:(AliPlayer *)player speed:(int64_t)speed{
  intspeed_=speed;
}

ネットワーク機能

HTTPDNS

HTTPDNS 機能は、DNS 名前解決技術を使用して、特定の HTTPDNS サーバーにドメイン名の名前解決リクエストを送信し、迅速かつ安定した解決結果を取得します。これにより、DNS ハイジャックを防止できます。

ApsaraVideo Player SDK は、Alibaba Cloud CDN によって高速化されたドメイン名に対して HTTPDNS サービスを提供します。拡張 HTTPDNS 機能を使用すると、正確なスケジューリングを実装し、リアルタイムのドメイン解決結果が即座に有効になるようにして、ネットワークパフォーマンスを向上させることができます。

拡張 HTTPDNS の使用例

拡張 HTTPDNS 機能は、高速化ドメイン名に対してのみ使用できます。この機能を使用する前に、高速化ドメイン名が追加および構成されていることを確認してください。ApsaraVideo VOD で CDN のドメイン名を追加および構成する方法の詳細については、「高速化ドメイン名の追加」をご参照ください。高速化ドメイン名の詳細については、「Alibaba Cloud CDN とは」をご参照ください。

// 拡張 HTTPDNS を有効化します。
[AliPlayerGlobalSettings enableEnhancedHttpDns:YES];
// 任意。HTTPDNS の事前解決用にドメインを追加します。
[[AliDomainProcessor shareInstance] addPreResolveDomain:@"player.***alicdn.com"];

HTTP/2

説明

ApsaraVideo Player SDK for iOS は、V5.5.0.0 以降、デフォルトで HTTP/2 を有効化しています。

ApsaraVideo Player SDK for iOS は HTTP/2 をサポートしています。このプロトコルは多重化を使用して head-of-line ブロッキングを回避し、再生パフォーマンスを向上させます。

[AliPlayerGlobalSettings setUseHttp2:true];

HTTP 事前確立 TCP 接続

HTTP(HTTPS ではない)動画再生リクエストの場合、TCP 接続を事前に確立することで、ユーザー体験が大幅に向上し、接続時間が短縮され、再生の即時性と継続性が保証され、ネットワークおよびシステムリソースの使用量が最適化されます。

// ドメインの形式は host[:port] です。ポートは任意です。複数のドメインはセミコロン(;)で区切ります。
// グローバル設定。
// 完全なインターフェイスが設定されるたびに、現在の文字列が使用されます(追加する場合は追加、削除する場合は削除)。空の文字列は事前接続を停止します。
[AliPlayerGlobalSettings setOption:SET_PRE_CONNECT_DOMAIN value: @"domain1;domain2"];

動画ダウンロード

説明

詳細なコード例については、「API-Example プロジェクト」の Download モジュールをご参照ください。このプロジェクトは Objective-C をベースとしており、ApsaraVideo Player SDK for iOS のコア SDK 統合を実証しています。

ApsaraVideo Player SDK for iOS は、ApsaraVideo VOD コンテンツの動画ダウンロード機能を提供しており、標準モードとセキュアモードがあります。

  • 標準ダウンロード:ダウンロードされた動画は暗号化されておらず、サードパーティのプレーヤーで再生できます。

  • セキュアダウンロード:ダウンロードされた動画は暗号化されており、ApsaraVideo Player でのみ再生できます。

注意事項

  • この機能は VidSts および VidAuth ソース専用です。

  • ApsaraVideo VOD コンソールでダウンロードモードを有効化および構成します。詳細については、「オフラインダウンロード」をご参照ください。

  • 動画のダウンロードはブレークポイントから再開できます。

操作手順

  1. 任意: セキュアダウンロード用の暗号化検証ファイルを構成します。このファイルはセキュアダウンロード専用です。標準ダウンロードでは不要です。

    説明

    暗号化検証ファイルがアプリ情報と一致していることを確認してください。一致しない場合、動画のダウンロードに失敗します。

    セキュアダウンロードを使用する場合、ApsaraVideo VOD コンソールで生成されたキーファイルを Player SDK に構成します。このキーファイルは、ダウンロードおよび再生用の動画の復号および検証に使用されます。キーファイルの生成方法の詳細については、「セキュアダウンロードの有効化」をご参照ください。

    この構成はアプリケーションで一度だけ行う必要があります。以下に例を示します:

    NSString *encrptyFilePath = [[NSBundle mainBundle] pathForResource:@"encryptedApp" ofType:@"dat"];
    [AliPrivateService initKey:encrptyFilePath];
  2. ダウンローダーを作成および設定します。

    例:

    AliMediaDownloader *downloader = [[AliMediaDownloader alloc] init];
    [downloader setSaveDirectory:self.downLoadPath];
    [downloader setDelegate:self];
  3. イベントリスナーを設定します。

    ダウンロードオブジェクトは複数のリスナーを提供します。

    -(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info {
        // ダウンロード項目が正常に準備されました。
    }
    -(void)onError:(AliMediaDownloader *)downloader errorModel:(AVPErrorModel *)errorModel {
        // ダウンロードエラーが発生しました。
    }
    -(void)onDownloadingProgress:(AliMediaDownloader *)downloader percentage:(int)percent {
        // ダウンロード進捗率。
    }
    -(void)onProcessingProgress:(AliMediaDownloader *)downloader percentage:(int)percent {
        // 処理進捗率。
    }
    -(void)onCompletion:(AliMediaDownloader *)downloader {
        // ダウンロードが成功しました。
    }
  4. ダウンロードソースを準備します。

    prepare メソッドを呼び出してダウンロードソースを準備します。サポートされているソースタイプには VidStsSource および VidAuthSource があります。以下に例を示します:

    • VidSts

      // VidSts を作成します。
      AVPVidStsSource* stsSource = [[AVPVidStsSource alloc] init];
      stsSource.region = @"アクセスリージョン"; // ApsaraVideo VOD のアクセスリージョン。デフォルトは cn-shanghai です。
      stsSource.vid = @"Vid 情報"; // 動画 ID(VideoId)。
      stsSource.securityToken = @"<yourSecurityToken>"; // STS セキュリティトークン。STS の AssumeRole 操作を呼び出して生成する必要があります。
      stsSource.accessKeySecret = @"<yourAccessKeySecret>"; // 一時的な STS AccessKey ペアの AccessKey Secret。STS の AssumeRole 操作を呼び出して生成する必要があります。
      stsSource.accessKeyId = @"<yourAccessKeyId>"; // 一時的な STS AccessKey ペアの AccessKey ID。STS の AssumeRole 操作を呼び出して生成する必要があります。
      
      // VOD コンソールで HLS 標準暗号化パラメーターのパススルーを有効化しており、デフォルトのパラメーター名が MtsHlsUriToken の場合、config を設定して vid に渡す必要があります。以下を参照してください。
      // VOD コンソールで HLS 標準暗号化パラメーターのパススルーを有効化していない場合、以下のコードを統合する必要はありません。
      VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
      [vp setHlsUriToken:yourMtsHlsUriToken];
      stsSource.playConfig = [vp generatePlayerConfig];
      // ダウンロードソースを準備します。
      [downloader prepareWithVid:stsSource];
    • VidAuth

      // VidAuth を作成します。
      AVPVidAuthSource *authSource = [[AVPVidAuthSource alloc] init];
      authSource.vid = @"Vid 情報"; // 動画 ID(VideoId)。
      authSource.playAuth = @"<yourPlayAuth>"; // 再生認証情報。ApsaraVideo VOD の GetVideoPlayAuth 操作を呼び出して生成する必要があります。
      authSource.region = @"アクセスリージョン"; // プレーヤー SDK V5.5.5.0 以降では、このパラメーターは非推奨です。リージョンを設定する必要はありません。プレーヤーが自動的にリージョンを解析します。プレーヤー SDK V5.5.5.0 より前のバージョンでは、このパラメーターは必須です。ApsaraVideo VOD のアクセスリージョン。デフォルトは cn-shanghai です。
      // VOD コンソールで HLS 標準暗号化パラメーターのパススルーを有効化しており、デフォルトのパラメーター名が MtsHlsUriToken の場合、config を設定して vid に渡す必要があります。以下を参照してください。
      // VOD コンソールで HLS 標準暗号化パラメーターのパススルーを有効化していない場合、以下のコードを統合する必要はありません。
      VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
      [vp setHlsUriToken:yourMtsHlsUriToken];
      authSource.playConfig = [vp generatePlayerConfig];
      // ダウンロードソースを準備します。
      [downloader prepareWithVid:authSource];
    説明

    ApsaraVideo VOD コンソールで HLS 暗号化のパラメーターパススルーを有効化する場合、デフォルトのパラメーターは MtsHIsUriToken です。詳細については、「HLS 暗号化のパラメーターパススルー」をご参照ください。その後、前述のコードに従って MtsHIsUriToken の値を ApsaraVideo VOD ソースに設定します。

  5. ダウンロード項目を選択します。

    準備が成功すると、onPrepared メソッドが呼び出されます。返される TrackInfo には、各動画ストリームの解像度などの情報が含まれます。ダウンロードするトラックを選択します。以下に例を示します:

    -(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info {
        NSArray<AVPTrackInfo*>* tracks = info.tracks;
        // 例:最初の TrackInfo をダウンロードします。
        [downloader selectTrack:[tracks objectAtIndex:0].trackIndex];
    }
  6. ダウンロードソースを更新し、ダウンロードを開始します。

    VidSts または VidAuth はダウンロード前に期限切れになる可能性があります。そのため、ダウンロードを開始する前にダウンロードソースを更新することを推奨します。

    // ダウンロードソースを更新します。
    [downloader updateWithVid:vidSource]
    // ダウンロードを開始します。
    [downloader start];
  7. ダウンロードが成功または失敗した後、ダウンローダーを解放します。

    ダウンロードが成功した後、destroy を呼び出してダウンローダーを解放します。

    [self.downloader destroy];
    self.downloader = nil;

暗号化再生

ApsaraVideo VOD は、HLS 標準暗号化、Alibaba Cloud 独自暗号化、DRM 暗号化をサポートしています。手順については、「暗号化された動画の再生」をご参照ください。

ネイティブ RTS 再生

SDK はネイティブ RTS SDK を統合して、低遅延ライブストリーミングを実現します。詳細については、「iOS での RTS ベースのストリームフェッチングの実装」をご参照ください。

リファレンス