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

ApsaraVideo VOD:高度な機能

最終更新日:Feb 12, 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 は高度な機能の列挙です。関連機能を使用すると、プレーヤーはライセンスを検証し、このコールバックを通じて結果を返します。isValid が false の場合、errorMsg には失敗の理由が含まれます。

再生

リスト再生

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

操作手順

  1. プレーヤーの作成

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

    self.listPlayer = [[AliListPlayer alloc] init];
    [self.listPlayer setTraceID:@"xxxxxx"];  // TraceID は、IMEI や IDFA などのデバイスまたはユーザーの一意の識別子です。

  2. 任意: リスナーの設定

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

    プレーヤーは、onPlayerEventonError を含む複数のリスナーの設定をサポートしています。これらを設定することを推奨します。

    /**
     @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 種類のソースタイプをサポートしています。

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

      GetPlayInfo 操作を呼び出すことで、ApsaraVideo VOD のメディアアセットの再生 URL を取得できます。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 ペアを渡す必要があります。事前に取得してください。詳細については、「STS トークンの取得」をご参照ください。
    - (BOOL) moveTo:(NSString*)uid accId:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
  7. 前または次のビデオの再生

    moveTo を呼び出してビデオソースを再生した後、moveToPrevmoveToNext を呼び出して、moveTo 呼び出しのビデオソースをアンカーとして使用して、前または次のビデオを再生します。以下に例を示します。

    説明

    同じ view を使用し、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;
説明

リスト再生の体験を向上させるには、当社の短編ドラマソリューションをご利用ください。詳細については、「短編ドラマのクライアントサイド開発」をご参照ください。

アルファチャンネル付きビデオの再生

概要

ApsaraVideo Player SDK は、アルファチャンネルのレンダリングをサポートしており、アニメーションギフトなどの動的な効果を作成できます。ライブストリーミング中に、メインコンテンツを隠すことなくアニメーションギフトを再生でき、ユーザーエクスペリエンスを向上させます。

制限事項

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

メリット

アニメーション効果に透明度のある MP4 ビデオを使用すると、APNG や IXD などのフォーマットと比較して、品質が向上し、ファイルサイズが小さくなり、互換性が高まります。

  1. より良いアニメーション品質:MP4 ビデオは、他のフォーマットよりも元のアニメーションの詳細と色をより正確に保持します。

  2. より小さいファイルサイズ:MP4 ビデオファイルは、APNG や IXD などの他のフォーマットのファイルよりも小さいため、読み込みが速くなり、ネットワーク帯域幅の消費が削減されます。

  3. より高い互換性:MP4 フォーマットは、デバイスやブラウザで広くサポートされています。

  4. より高い開発効率:ギフト効果に MP4 ビデオを使用することは簡単なアプローチであり、開発者は複雑な解析やレンダリングロジックを調査・実装する必要がなく、他の機能に集中できます。

サンプルコード

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

説明
  • ビデオアセット内のアルファチャンネルの位置は、alphaRenderMode の設定と一致する必要があります。

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

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

//-----------AliPlayer の使用法-----------
// アルファモードを設定します。
[self.player setAlphaRenderMode:AVP_RENDERMODE_ALPHA_AT_LEFT];
// アルファモードに対応する素材を設定します。
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 フレームワークを使用したビデオレンダリングをサポートしています。

説明

現在、背景色、スケーリングモード、ピクチャーインピクチャー (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 モジュールをご参照ください。

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

例:

  1. 字幕を表示するためのビューの作成

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

    // カスタム subTitleLabel を初期化します。
    UILabel *subTitleLabel = [[UILabel alloc] initWithFrame:frame];
    // 字幕ラベルをカスタム 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];

カスタムレンダリングされた外部字幕

AliVttSubtitleViewAliVttRenderImpl を使用して、WebVTT 外部字幕を完全にサポートし、フォントサイズ、色、特定のフォントを柔軟にカスタマイズできます。

説明

ユースケース:

  • フォント、色、サイズなどの WebVTT 字幕スタイルをカスタマイズします。

  • ApsaraVideo Player SDK V7.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 Player SDK は、H.264 および H.265 のハードウェアデコード機能を提供し、enableHardwareDecoder トグルを含みます。デフォルトでは、ハードウェアデコードが有効になっています。ハードウェアデコードの初期化に失敗した場合、ビデオ再生を確実にするためにソフトウェアデコードが自動的に使用されます。以下の例を示します。

// ハードウェアデコードを有効にします。デフォルトで有効です。
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 ソフトウェアデコードにフォールバックします。

説明
  • この機能は、アダプティブ再生を有効にした後にのみ利用可能です。アダプティブ再生は付加価値サービスです。ライセンスを申請するには、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];

ネットワーク状況に応じた画質切り替え

説明

ApsaraVideo Player SDK for iOS は、HTTP Live Streaming (HLS) ビデオストリームと Dynamic Adaptive Streaming over HTTP (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 の最大許容ピクセル数を 1280x720 に設定します。プレーヤーはこの値以下のピクセル数の画質にのみ切り替えます。
[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 (推奨) の両方の再生でサポートされています。設定手順については、「ビデオのプレビュー」をご参照ください。

ビデオプレビュー機能を設定した後、VidPlayerConfigGen インターフェイスを使用して setPreviewTime メソッドを呼び出し、プレーヤーのプレビュー時間を設定します。以下のサンプルコードは、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 メソッドを使用して設定します。以下のサンプルコードは例です。

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

User-Agent の設定

iOS Player SDK は AVPConfig を提供して User Agent を設定します。User Agent を設定すると、プレーヤーはリクエストに User Agent 情報を含めます。例:

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

ネットワークのリトライ回数とタイムアウトの設定

iOS Player 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.code が ERROR_LOADING_TIMEOUT に設定されます。

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

キャッシュと遅延の制御

キャッシュ制御はプレーヤーにとって重要です。適切な構成を使用することで、起動時の読み込み時間を短縮し、再生の滑らかさを向上させることができます。iOS Player SDK は、キャッシュと遅延を構成するための AVPConfig インターフェイスを提供します。以下に例を示します。

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

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

HTTP ヘッダーの設定

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

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

ピクチャーインピクチャー

説明

詳細なコード例については、API-Example プロジェクトPictureInPicture モジュールをご参照ください。

説明
  • 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 は setPictureInPictureEnable メソッドによって制御されます。PiP を有効にするには、AVPEventPrepareDone イベントが発生したときにこのメソッドを呼び出す必要があります。以下の例は、PiP 機能を有効にする方法を示しています。

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

再生を停止するには、まず 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. (グローバル変数) を追加して、プレーヤーの状態変化を制御できます。

      #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;
      // プレーヤーの現在の再生進捗をリッスンします。currentPosition を現在のビデオ再生位置のコールバックの position パラメーターの値に設定します。
      @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. onPlayerEvent イベントをリッスンするときに 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 PiP が停止する前にユーザーインターフェイスを復元するようにデリゲートに指示します。
         @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 UI に一時停止または再生状態を反映します。
         @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 ピクチャーインピクチャーの一時停止ボタンがクリックされました。
         @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 が有効になっているかどうかを判断できます。

/**
 @brief PiP が開始されているかどうか。
 @param pictureInPictureController PiP コントローラー。
 @param isEnable PiP が開始されているかどうか。
 */
/****
 @brief ピクチャーインピクチャーが有効かどうか
 @param pictureInPictureController ピクチャーインピクチャーコントローラー
 @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 モジュールをご参照ください。

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

左右の音声チャンネルの切り替え

iOS Player 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 の例

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

使用方法

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

VidAuth の再生ドメインの指定

VidAuth メソッドを使用すると、vid の再生ドメインなどのパラメーターを指定できます。サポートされているフィールドのリストについては、「GetPlayInfo」をご参照ください。以下では、vidAuth ベースの再生でドメイン名を指定する方法とサンプルコードについて説明します。

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 Transcoding によってエンコードされた H.266 ビデオのみをサポートします。

プラグインの統合

Player SDK

CocoaPods (推奨)

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

説明

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

// x.x.x は ApsaraVideo Player SDK のバージョン番号と同じでなければなりません。
pod 'AliPlayerSDK_iOS_VVC_CODEC_PLUGIN', 'x.x.x'

ローカル統合

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

オールインワン SDK

CocoaPods (推奨)

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

// x.x.x は、使用している統合 SDK のバージョン番号と同じでなければなりません。
pod 'AliVCSDK_Standard/AliPlayerSDK_iOS_VVC_CODEC', 'x.x.x'

ローカル統合

最新バージョンの iOS オールインワンパッケージをダウンロードし、展開して plugins/vvcCodecPlugin.frameworkFrameworks, Libraries, and Embedded Content に追加し、EmbedEmbed & Sign に設定し、Framework Search Paths を構成します。詳細については、「ローカル統合」をご参照ください。

プラグインのアクティベート

説明

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 ソースを更新し、新しい VidAuth ソースオブジェクトを `callback` 経由で送信して、安定したスムーズな再生を保証できます。

 @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 が有効な場合はそれを使用
        NSString *key = (self.authKey.length > 0) ? self.authKey : @"";
        if (!NOT_EMPTY(key)) {
            [callback onError:@"REFRESH_ERROR:key fail"];
            return;
        }       
        
        // クラスメンバーの 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];   

プリレンダリング

iOS Player SDK は、再生開始前に最初のフレームを高速にレンダリングし、起動速度を向上させることをサポートしています。

説明
  1. この機能はデフォルトで無効になっています。

  2. 有効にすると、準備完了イベントと初回フレームレンダリングイベントの順序に影響します。デフォルトでは、準備完了イベントが最初に発生し、次に初回フレームレンダリングイベントが発生します。プリレンダリングを有効にすると、デコードとレンダリングの速度によっては、初回フレームレンダリングイベントが準備完了イベントの前に発生する可能性がありますが、再生には影響しません。

例:

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

ローカルキャッシュ

説明

詳細なコード例については、API-Example プロジェクトPreloadUrl モジュールをご参照ください。

iOS Player SDK は、ローカルキャッシュを提供して、起動速度、シーク速度を向上させ、繰り返しビデオ再生の途切れを減らし、帯域幅を節約します。

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

デフォルトでは、ローカルキャッシュ機能は無効になっています。この機能を使用するには、手動で有効にする必要があります。この機能は、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: メガバイト単位の最大キャッシュ容量。デフォルトは 20 GB です。クリーンアップ中に、合計キャッシュ容量がこのサイズを超えた場合、cacheItem の最終キャッシュ時間でソートされた最も古いキャッシュファイルが、容量が最大キャッシュ容量以下になるまで 1 つずつ削除されます。
 @param freeStorageMB: メガバイト単位の最小空きディスク領域。デフォルトは 0 です。クリーンアップ中に、最大キャッシュ容量と同様に、現在のディスク領域がこの値より小さい場合、freeStorage がこの値以上になるか、すべてのキャッシュがクリアされるまで、ルールに従ってキャッシュファイルも 1 つずつ削除されます。
 */
[AliPlayerGlobalSettings setCacheFileClearConfig:0 maxCapacityMB:0 freeStorageMB:0];

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

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

[AliPlayerGlobalSettings setCacheUrlHashCallback:&CaheUrlHashHandle];
説明
  • ビデオ再生 URL に認証パラメーターがある場合、これらのパラメーターはローカルキャッシュと再生中に変更されます。異なる認証を持つ同じ URL のキャッシュヒット率を向上させるには、setCacheUrlHashCallback インターフェイスでハッシュ値 (たとえば MD5) を計算する前に、URL から認証パラメーターを削除できます。たとえば、認証付きの再生 URL が http://****.mp4?aaa の場合、読み込み時にハッシュ値を計算するために http://****.mp4 を使用します。ただし、ビデオが暗号化された M3U8 ビデオの場合、ハッシュ値を計算する前に認証パラメーターを削除してキー URL を処理すると、異なるビデオがキャッシュ内の同じキーにヒットし、再生に失敗します。解決策:setCacheUrlHashCallback コールバックで、ドメインチェックを実行し、再生ドメイン (http(s)://xxxxx.m3u8?aaaa) の認証パラメーターのみを削除し、キー URL のドメイン (http(s)://yyyyy?bbbb) の認証パラメーターは削除しません。进阶功能-本地缓存.png

  • サーバーが HTTP と HTTPS の両方のプロトコルをサポートしているが、異なるプロトコルが指すメディアファイルが同一である場合、MD5 値を計算する前にリクエストヘッダーを削除または統一できます。例:

    • ビデオ再生 URL が https://****.mp4http://****.mp4 の場合、MD5 値を計算するために ****.mp4 を使用します。

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

  • ApsaraVideo Player SDK V5.5.4.0 以降で、ビデオ再生 URL に認証パラメーターが含まれ、再生プロトコルが HLS の場合、AVPConfig.enableStrictAuthMode フィールドを設定して異なる認証モードを選択できます。以前のバージョンのデフォルト値は false です。V7.13.0 以降のデフォルト値は true です。

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

    • 厳密認証 (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];

プリロード

iOS Player SDK は、ローカルキャッシュのアップグレードであるプリロードを提供し、再生開始前にビデオの一部をキャッシュにダウンロードすることで、起動速度をさらに向上させます。

プリロードの制限:

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

説明

iOS Player 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:@"アクセスリージョン"]; // Player SDK V5.5.5.0 以降、このパラメーターは非推奨です。リージョンを設定する必要はありません。プレーヤーが自動的にリージョンを解析します。Player 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. タスクパラメーターの設定

    説明

    これはマルチビットレートビデオにのみ適用されます。setDefaultBandWidthsetDefaultResolution、または setDefaultQuality のいずれかを選択できます。

    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];

// ベースのプリロード時間を構成する
// プリロード時間を 1000ms に設定
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 ビデオのプリロード

マルチビットレート HLS ビデオを使用する listPlayer シナリオでは、現在の再生画質に一致するストリームをプリロードし、ビジネスニーズに基づいてプリロードモードを選択できます。

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

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 機能を提供し、Alibaba Cloud CDN ネットワークの正確なスケジューリングとリアルタイムの名前解決をサポートし、ネットワークパフォーマンスを効果的に向上させます。

強化された HTTPDNS の使用例

強化された HTTPDNS は、Alibaba Cloud CDN ドメイン名に対してのみ HTTPDNS サービスを提供します。構成するドメイン名が Alibaba Cloud CDN ドメイン名であり、ドメイン名構成が完全で正常に使用できることを確認してください。ApsaraVideo VOD で CDN ドメイン名を追加および構成するには、「高速化ドメイン名の追加」をご参照ください。CDN ドメイン名の詳細については、「Alibaba Cloud CDN」をご参照ください。

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

HTTP/2

説明

iOS Player SDK は、バージョン 5.5.0.0 以降、デフォルトで HTTP/2 を有効にします。

iOS Player SDK は 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 モジュールをご参照ください。

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

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

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

使用上の注意

  • ビデオダウンロード機能は、VidSts および VidAuth メソッドでのみサポートされています。

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

  • ビデオダウンロードは、レジューム転送をサポートしています。

操作手順

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

    説明

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

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

    キーファイルは Application で一度構成することを推奨します。

    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 = @"アクセスリージョン"; // Player SDK V5.5.5.0 以降、このパラメーターは非推奨です。リージョンを設定する必要はありません。プレーヤーが自動的にリージョンを解析します。Player 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 ベースのストリームフェッチングの実装」をご参照ください。

参照情報