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

ApsaraVideo VOD:高度な機能

最終更新日:Apr 10, 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 は、ショートビデオシナリオ向けの包括的なリスト再生機能を提供します。プリロードなどの技術を使用して、初回フレーム表示時間 (TTTF) を大幅に短縮します。

操作手順

  1. プレーヤーの作成

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

    self.listPlayer = [[AliListPlayer alloc] init];
    [self.listPlayer setTraceID:@"xxxxxx"];  // TraceID は、デバイスまたはユーザーを一意に識別します。通常は IMEI または IDFA です。
  2. 任意:リスナーの設定

    リスナーは任意ですが、再生の失敗、進行状況の更新などのイベント通知を受け取るために設定することを推奨します。

    プレーヤーは複数のリスナーをサポートしています。少なくともonPlayerEventonError のリスナーを設定することを推奨します。

    /**
     @brief エラーコールバック。
     @param player プレーヤーポインター。
     @param errorModel エラーの説明。詳細については、AVPErrorModel をご参照ください。
     */
    - (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. プリロード数の設定

    TTTF を効果的に短縮するために、適切なプリロード数を設定します。例:

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

    リスト再生は、VidSts 再生と UrlSource 再生の 2 種類の再生ソースをサポートしています。UrlSource 再生は再生 URL を使用し、VidSts 再生は ApsaraVideo VOD のメディアアセットの VideoId を使用します。

    • URL:再生アドレスは、サードパーティのサービスまたは ApsaraVideo VOD から取得できます。

      ApsaraVideo VOD サーバー側 SDK を統合して再生アドレスを取得することを推奨します。これにより、URL 署名が自動的に処理され、プロセスが簡素化されます。API オペレーションの呼び出し方法の例については、「開発者ポータル」をご参照ください。

    • Vid:VideoId。メディアファイルをアップロードした後に VideoId を取得できます。ApsaraVideo VOD コンソールの [メディアライブラリ] > [オーディオ/ビデオ] で見つけるか、「メディア情報の検索」などのサーバー側 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. 再生ソースの再生

    再生ソースを追加した後、moveTo を呼び出して特定のソースの再生を開始します。

    // UrlSource 再生にはこの API を使用します。
    - (BOOL) moveTo:(NSString*)uid;
    // VidSts 再生用。一時的な STS 認証情報のコンポーネント (AccessKey ID、AccessKey Secret、STS トークン) を渡す必要があります。これらの取得方法の詳細については、「STS を使用して RAM ロールを作成し、一時的なアクセス権限を付与する」をご参照ください。
    - (BOOL) moveTo:(NSString*)uid accId:(NSString*)accId accKey:(NSString*)accKey token:(NSString*)token region:(NSString*)region;
  7. 前または次のビデオの再生

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

    説明

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

    UrlSource

    // 次のビデオに移動します。
    - (BOOL) moveToNext;
    // 前のビデオに移動します。
    - (BOOL) moveToPrev;

    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 6.8.0 以降、または ApsaraVideo Player SDK 6.9.0 以降でサポートされています。

メリット

alpha チャンネル付きの MP4 ビデオをアニメーションエフェクトに使用すると、アニメーション品質の向上、ファイルサイズの縮小、互換性の向上、開発効率の向上が期待できます。

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

  2. ファイルサイズの縮小:MP4 ファイルは、APNG や IXD などの他のフォーマットよりも効果的に圧縮できるため、読み込み速度が向上し、ネットワーク帯域幅の消費が削減されます。

  3. 互換性の向上:ユニバーサルビデオフォーマットとして、MP4 はほとんどのデバイスとブラウザで広くサポートされています。

  4. 開発効率の向上:実装はシンプルで、開発者が複雑な解析やレンダリングロジックを構築する必要がないため、他の機能に集中できます。

サンプルコード

新しい API を使用すると、alpha モードを設定できます。これは、ビデオアセット内の alpha チャンネルの位置 (上、下、左、または右) を指定します。デフォルト値は none です。

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

  • プレーヤービューの縦横比は、ソースアセット全体ではなく、最終的な出力の縦横比と一致する必要があります。

/**
 @brief Alpha レンダリングモード。右、左、上、または下の 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/business_needs_sample/alpha_channel/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 レンダリング

Alibaba Cloud Player SDK for iOS は、Metal フレームワークを使用したビデオレンダリングをサポートしています。

説明

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

パラメーター

/**
 @brief ビデオレンダリングタイプを指定します。有効な値:0 (デフォルトレンダラー) および 1 (混合レンダラー)。デフォルト:0。
 */
@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 のコア機能を統合する方法を示しています。

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

次の例に、この機能の実装方法を示します。

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

    字幕フォーマットに基づいてビューを作成します。

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

外部字幕 (カスタムレンダリング)

AliVttSubtitleViewAliVttRenderImpl を使用することで、この機能は WebVTT 外部字幕を完全にサポートし、フォント、色、サイズなどのスタイルをカスタマイズできます。

説明

ユースケース:

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

  • ご利用の統合が Alibaba Cloud 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 を呼び出す前に PlayerConfig を設定します。

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

デコーダーの切り替え

ApsaraVideo Player SDK for iOS は、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 フォームを送信する必要があります。

  • クラウドネイティブアダプティブデコードサービスは、主に 2 つの機能を提供します。1. クラウドからのハードウェアデコード互換性データの動的配信。2. 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 は、マルチビットレートアダプティブストリームをサポートしています。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 メソッドを呼び出してアダプティブビットレートストリーミングを有効にする前に、ビデオの解像度の上限を設定して、プレーヤーが予期せず高いビットレートに切り替わるのを防ぐことができます。この設定は、prepare メソッドまたはリスト再生の moveTo メソッドを呼び出す前に適用してください。

AVPConfig *config = [self.player getConfig];
config.maxAllowedAbrVideoPixelNumber = 921600; // ABR の最大ピクセル数を 921600 (1280 * 720) に設定します。これにより、プレーヤーはこの値以下のピクセル数の解像度にのみ切り替わるようになります。
[self.player setConfig:config];

スナップショット

ApsaraVideo Player SDK for iOS は、現在のビデオのスナップショットを撮る機能を提供します。この機能は snapShot API によって実装されます。生データをキャプチャし、bitmap として返します。コールバックは onCaptureScreen です。以下に例を示します。

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

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

プレビュー

ApsaraVideo Player SDK for iOS は、ApsaraVideo VOD と連携して設定した場合にプレビュー機能をサポートします。SDK は VidStsVidAuth の両方の再生をサポートしています。VidAuth が推奨される方法です。詳細については、「ビデオのプレビュー」をご参照ください。

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

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

プレビュー時間を設定して iOS プレーヤー SDK を使用してビデオを再生すると、サーバーは完全なビデオコンテンツではなく、プレビュー期間のビデオコンテンツのみを返します。

説明

VidPlayerConfigGenerator クラスを使用して、サーバー側のリクエストパラメーターを設定できます。詳細については、「リクエストパラメーターの説明」をご参照ください。

Referer の設定

ApsaraVideo Player SDK for iOS では、Referer を設定してアクセスの制御を実装できます。この機能は、ApsaraVideo VOD コンソールで設定した Referer ブラックリストおよびホワイトリストと連携して動作します。AVPConfig オブジェクトで Referer を設定できます。次の例をご参照ください。

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

User-Agent

iOS プレーヤー SDK は、カスタム User-Agent を設定するための AVPConfig を提供します。プレーヤーは、その後のすべてのネットワークリクエストにこの User-Agent を含めます。以下に例を示します。

// 現在の構成を取得します。
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.code は ERROR_LOADING_TIMEOUT になります。

  • networkRetryCount0 の場合、ネットワークタイムアウトは onPlayerEvent コールバックをトリガーし、eventWithString パラメーターは EVENT_PLAYER_NETWORK_RETRY に設定されます。その後、プレーヤーの reload メソッドを呼び出してネットワークリクエストをリトライするか、他のアクションを実行できます。

キャッシュと遅延の制御

キャッシュ制御はプレーヤーのパフォーマンスにとって重要です。適切な設定により、起動速度が向上し、カクつきが減少します。ApsaraVideo Player SDK for iOS は、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 の関係を満たす必要があります。

  • 最大バッファ時間 (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];

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

説明

詳細なコード例については、「API-Example」プロジェクトの PictureInPicture モジュールをご参照ください。この Objective-C サンプルプロジェクトは、Alibaba Cloud Player SDK for iOS のコア機能を統合する方法を示しています。

説明
  • ピクチャーインピクチャー (PiP) には、iOS 15 以降と ApsaraVideo Player SDK for iOS 5.4.9.0 以降が必要です。

  • 5.5.2.0 より前のバージョンの ApsaraVideo Player SDK for iOS は、PiP を有効または無効にするメソッドと、アプリがバックグラウンドに入ったときに PiP ウィンドウを表示するメソッドのみを提供します。バージョン 5.5.2.0 以降では、外部 PiP デリゲートを設定して PiP の動作をカスタマイズすることもできます。

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

PiP の有効化

ピクチャーインピクチャーを有効にすると、アプリがバックグラウンドに入ったときにビデオが小さなウィンドウで再生され続けます。アプリがフォアグラウンドに戻ると、ビデオは元のビューに戻ります。ピクチャーインピクチャーを有効にするには、プレーヤーが AVPEventPrepareDone 状態になった後、setPictureInPictureEnable を呼び出します。以下に例を示します。

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

プレーヤーの stop メソッドを呼び出しても、ピクチャーインピクチャーウィンドウは自動的に閉じません。そのため、stop を呼び出す前に setPictureInPictureEnable を呼び出してピクチャーインピクチャーを無効にする必要があります。

PiP デリゲートの設定

以下のコード例は、ピクチャーインピクチャー (PiP) ウィンドウとプレーヤーウィンドウ間の一般的なインタラクションを示します。 これらの例では、一時停止、再生、早送り、巻き戻しなどの再生コントロールの表示、および再生ロジックの実装について説明します。 デリゲートメソッドの完全なリファレンスについては、プレーヤー SDK デモの SDK フォルダにある AliyunPlayer.framework 内のAliPlayerPictureInPictureDelegate.h ヘッダーファイルをご参照ください。

  1. ピクチャーインピクチャーデリゲートを設定します。

    /**
    * @brief ピクチャーインピクチャーイベントのデリゲートを設定します。
    */
    -(void) setPictureinPictureDelegate:(id<AliPlayerPictureInPictureDelegate>)delegate;
    
    
    // ピクチャーインピクチャーデリゲートを設定します。
    [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;
      // ピクチャーインピクチャーウィンドウが一時停止しているかどうかを追跡します。
      @property (nonatomic, assign) BOOL isPipPaused;
      // onPlayerStatusChanged:oldStatus:newStatus: コールバックによって更新される、プレーヤーの現在の再生ステータスを追跡します。
      @property (nonatomic, assign) AVPStatus currentPlayerStatus;
      // ピクチャーインピクチャーコントローラーへの弱い参照。これは pictureInPictureControllerWillStartPictureInPicture: コールバックで設定され、ビューコントローラーがデアロケートされる前に nil に設定する必要があります。弱い参照の使用を推奨します。
      @property (nonatomic, weak) AVPictureInPictureController *pipController;
      // 再生進行状況を追跡し、再生進行状況コールバックの 'position' パラメーターによって更新されます。
      @property (nonatomic, assign) int64_t currentPosition;
      
      @end
      説明

      pipController プロパティは、リテインサイクルを防ぐために weak または assign 属性で宣言する必要があります。assign を使用する場合は、適切なタイミングで手動でプロパティを nil に設定してください。

    2. onPlayerStatusChanged: デリゲートメソッドで、ピクチャーインピクチャーコントローラーに状態を更新するよう通知します。

      - (void)onPlayerStatusChanged:(AliPlayer*)player oldStatus:(AVPStatus)oldStatus newStatus:(AVPStatus)newStatus {
          self.currentPlayerStatus = newStatus;
      
        if (_pipController) {
           [self.pipController invalidatePlaybackState];
         }
      }
    3. onPlayerEvent: デリゲートメソッドで、再生イベントに応じてピクチャーインピクチャーの状態を更新します。

      - (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. デリゲートメソッドを実装します。

      • ピクチャーインピクチャーが開始されようとしているときのコールバックを実装します。

        /**
         @brief ピクチャーインピクチャーが開始されようとしていることをデリゲートに伝えます。
         @param pictureInPictureController ピクチャーインピクチャーコントローラー。
         */
        - (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
            if (!_pipController) {
             self.pipController = pictureInPictureController;
          }
            self.isPipPaused = !(self.currentPlayerStatus == AVPStatusStarted);
          [pictureInPictureController invalidatePlaybackState];
        }
      • ピクチャーインピクチャーが停止されようとしているときのコールバックを実装します。

        /**
         @brief ピクチャーインピクチャーが停止されようとしていることをデリゲートに伝えます。
         @param pictureInPictureController ピクチャーインピクチャーコントローラー。
         */
        - (void)pictureInPictureControllerWillStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
            self.isPipPaused = NO;
          [pictureInPictureController invalidatePlaybackState];
        }
      • ピクチャーインピクチャーが停止する前に UI を復元するためのコールバックを実装します。

        /**
         @brief ピクチャーインピクチャーが停止する前にユーザーインターフェースを復元するようデリゲートに伝えます。
         @param pictureInPictureController ピクチャーインピクチャーコントローラー。
         @param completionHandler システムが復元を完了できるようにするために YES を指定して呼び出す完了ハンドラ。
         */
        - (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler {
            if (_pipController) {
              _pipController = nil;
          }
          completionHandler(YES);
        }
      • 再生可能な時間範囲を提供するコールバックを実装します。

        /**
         @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);
            }
        }
      • 再生が一時停止しているかどうかを報告するコールバックを実装します。

        /**
         @brief 再生が現在一時停止しているかどうかをデリゲートに問い合わせます。
         @param pictureInPictureController ピクチャーインピクチャーコントローラー。
         @return 再生が一時停止しているかどうかを示すブール値。
         */
        - (BOOL)pictureInPictureControllerIsPlaybackPaused:(nonnull AVPictureInPictureController *)pictureInPictureController{
            return self.isPipPaused;
        }
        説明

        このコールバックは、ピクチャーインピクチャーが開始される前に呼び出されます。PiP ウィンドウを起動するには、この時点で false を返す必要があります。true を返すと、ピクチャーインピクチャーは開始されません。

      • ピクチャーインピクチャーコントロールからの早送りおよび巻き戻しアクションを処理するコールバックを実装します。

        /**
         @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];
        }
      • ピクチャーインピクチャーコントロールからの再生および一時停止アクションを処理するコールバックを実装します。

        /**
         @brief ユーザーが再生/一時停止ボタンを切り替えたことをデリゲートに伝えます。
         @param pictureInPictureController ピクチャーインピクチャーコントローラー。
         @param playing 再生を開始するかどうかを示すブール値。
         */
        - (void)pictureInPictureController:(nonnull AVPictureInPictureController *)pictureInPictureController setPlaying:(BOOL)playing {
            if (!playing){
              [self.player pause];
              self.isPipPaused = YES;
            } else {
              // ヒント:再生完了後に再生ボタンでビデオを再開したい場合は、次のブロックを追加します。
              if (self.currentPlayerStatus == AVPStatusCompletion) {
                 [self.player seekToTime:0 seekMode:AVP_SEEKMODE_ACCURATE];
              }
        
              [self.player start];
              self.isPipPaused = NO;
          }
          [pictureInPictureController invalidatePlaybackState];
        }

アプリ内ピクチャーインピクチャー

ピクチャーインピクチャーはデフォルトでアプリ外です。アプリ内ピクチャーインピクチャーを実装するには、まず次のインターフェイスを呼び出してピクチャーインピクチャーがアクティブかどうかを確認します。

/**
 @brief ピクチャーインピクチャーが有効かどうかをデリゲートに伝えます。
 @param pictureInPictureController 状態を報告するピクチャーインピクチャーコントローラー。
 @param isEnable ピクチャーインピクチャーが有効な場合は `YES`、それ以外の場合は `NO`。
 */
- (void)pictureInPictureControllerIsPictureInPictureEnable:(nullable AVPictureInPictureController *)pictureInPictureController isEnable:(BOOL)isEnable;

自動起動を無効にし、ピクチャーインピクチャーの実行中に手動アクティベーションに切り替えるには、次のサンプルコードを使用します。

- (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 サンプルプロジェクトは、Alibaba Cloud Player SDK for iOS のコア機能を統合する方法を示しています。

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

オーディオチャンネルの切り替え

outputAudioChannel プロパティを使用して、出力オーディオチャンネルを設定します。入力ソースがステレオチャンネルの場合、出力を左または右のオーディオチャンネルに切り替えることができます。入力ソースがモノラルチャンネルの場合、この設定は効果がありません。

説明

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

// AVPOutputAudioChannel 列挙値を使用して出力オーディオチャンネルを設定します。
// AVP_AUDIO_CHANNEL_NONE:入力ソースから元のオーディオチャンネルを再生します。これがデフォルト値です。
// AVP_AUDIO_CHANNEL_LEFT:左のオーディオチャンネルのみを再生します。
// AVP_AUDIO_CHANNEL_RIGHT:右のオーディオチャンネルのみを再生します。
self.player.outputAudioChannel = AVP_AUDIO_CHANNEL_NONE;

ビデオの背景色の設定

ApsaraVideo Player SDK for iOS では、レンダリングビューの背景色を設定できます。

API の例

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

使用方法

// パラメーターは ARGB 形式 (アルファ、赤、緑、青) の 8 桁の 16 進数値です。
// 例えば、0x0000ff00 は緑を表します。
[self.player setVideoBackgroundColor:0x0000ff00]

VidAuth での再生ドメインの指定

VidAuth メソッドを使用して、ビデオ ID (vid) に関連付けられた再生ドメインなどのフィールドを指定します。サポートされているフィールドのリストについては、「GetPlayInfo リクエストパラメーター」をご参照ください。

API の例

/**
 @brief ビデオ ID と再生認証情報 (PlayAuth) を使用してビデオを再生します。詳細については、https://www.alibabacloud.com/help/en/vod/user-guide/use-playback-credentials-to-play-videos をご参照ください。
 @param source AVPVidAuthSource オブジェクト。
 @see AVPVidAuthSource
 */
- (void)setAuthSource:(AVPVidAuthSource*)source;

使用方法

VidPlayerConfigGenerator インターフェイスの addVidPlayerConfigByStringValue メソッドを使用して、playDomain フィールドを追加します。

VidPlayerConfigGenerator* gen = [[VidPlayerConfigGenerator alloc]init];
// playDomain フィールドを追加します。サポートされているフィールドのリストについては、以下をご参照ください。
// https://www.alibabacloud.com/help/en/vod/developer-reference/api-vod-2017-03-21-getplayinfo
[gen addVidPlayerConfigByStringValue:@"playDomain" value: @"com.example.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) とも呼ばれ、大幅に低いビットレートで同等の画質を提供する次世代のビデオエンコーディング規格です。パフォーマンスを最適化し、メイン SDK のサイズを制御するために、H.266 デコーダーは、オンデマンドで統合できる別のプラグインとして提供されています。

前提条件

  1. プレーヤー SDK またはオールインワン SDK V7.6.0 以降。

  2. Professional Edition ライセンスをお持ちであること。詳細については、「ライセンスの取得」をご参照ください。

  3. プレーヤー SDK の H.266 デコードプラグインは、Alibaba Cloud Transcoding によってトランスコードされた H.266 ビデオのみをサポートします。

プラグインの統合

プレーヤー SDK

CocoaPods (推奨)

プラグインの依存関係を Podfile に追加します。

説明

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

// x.x.x をご利用のプレーヤー SDK のバージョンに置き換えます。
pod 'AliPlayerSDK_iOS_VVC_CODEC_PLUGIN', 'x.x.x'

ローカル統合

最新バージョンの ApsaraVideo Player SDK for iOS をダウンロードし、vvcCodecPlugin.framework ファイルを [Frameworks, Libraries, and 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'

ローカル統合

最新バージョンのオールインワン SDK パッケージ for iOS をダウンロードします。パッケージを解凍し、plugins/vvcCodecPlugin.framework ファイルをプロジェクトの [Frameworks, Libraries, and Embedded Content] に追加し、[Embed][Embed & Sign] に設定し、[Framework Search Paths] を構成します。詳細については、「ローカル統合」をご参照ください。

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

説明

ApsaraVideo Player SDK for iOS v7.7.0 以降、プラグインはデフォルトで有効になっており、手動でのアクティベーションは不要です。

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

エラーコード

H.266 デコードプラグインのエラーコードについては、「クロスプラットフォームプレーヤーのよくある質問」をご参照ください。

ソースの自動リフレッシュ

ソースの自動リフレッシュを有効にすると、認証の有効期限切れによる再生の中断を防ぐことができます。ソースの有効期限が切れると、プレーヤーはコールバックをトリガーして新しいソースを取得し、スムーズで連続的な再生を保証します。

前提条件

  1. プレーヤーまたは統合 SDK はバージョン 7.9.0 以降である必要があります。

  2. VidAuth ソースを再生に使用するか、URL 署名が設定されている必要があります。

VidAuth ソース

API の例

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

 このコールバックは、プレーヤーが現在の VidAuth ソースの有効期限が切れたことを検出したときにトリガーされます。VidAuth ソースは、PlayAuth または再生 URL の有効期限が切れると期限切れになります。
 このコールバックで VidAuth ソースをリフレッシュし、`callback` パラメーターを介して新しいオブジェクトを渡すことで、スムーズな再生を保証できます。

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

主要コンポーネント

/**
 @protocol AVPSourceRefreshCallback
 @brief ソースリフレッシュの結果を処理するためのプロトコル。実装する必要があります。

 このプロトコルは、リソースの有効期限が切れたり更新が必要になったりした場合など、プレーヤーがソースのリフレッシュを要求したときにアプリケーションに通知します。このプロトコルのメソッドは、成功または失敗を含むリフレッシュ結果を提供するために呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソース、およびリフレッシュロジックを必要とする同様のシナリオに適用されます。
 */
@protocol AVPSourceRefreshCallback <NSObject>

/**
 @brief リフレッシュ操作が成功したときにプレーヤーによって呼び出されます。
 
 @param newSource 更新された情報を含む新しいソースオブジェクト。

 このメソッドは、リフレッシュ操作が正常に完了したことを示します。更新された `newSource` をプレーヤーに
 返して、新しいリソースをロードできるようにする必要があります。
 */
- (void)onSuccess:(id)newSource;

/**
 @brief リフレッシュ操作が失敗したときにプレーヤーによって呼び出されます。
 
 @param errorMsg 失敗の理由を説明する文字列。

 このメソッドは、リフレッシュ操作が失敗したことを示します。`errorMsg` を使用して失敗の
 詳細をキャプチャし、それに応じてエラーを処理できます。
 */
- (void)onError:(NSString *)errorMsg;

@end

使用方法

PlayAuth は GetVideoPlayAuth オペレーションを呼び出すことで取得できます。手動での URL 署名の必要性を避けるため、VOD のサーバー側 SDK を統合して認証情報を取得することを推奨します。詳細については、「OpenAPI Portal」をご参照ください。

[self.player setOnVidAuthExpiredCallback:^(id expiredSource, id<AVPSourceRefreshCallback> callback) {
    // AVPVidAuthSource オブジェクトを取得します。
    if ([expiredSource isKindOfClass:[AVPVidAuthSource class]]) {
        AVPVidAuthSource *vidAuth = (AVPVidAuthSource *)expiredSource;

        // ------------------- ユーザー実装の開始 -------------------
        // カスタム関数を呼び出して、アプリサーバーから新しい PlayAuth を取得します。
        // clinetGetPlayAuthFunction はサンプル関数名です。実際の
        // 実装に置き換えてください。
        [self clinetGetPlayAuthFunction:vidAuth.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/en/vod/user-guide/configure-url-signing
 
 @param callback URL ソースの有効期限が切れたときにトリガーされるコールバックブロック。
 このコールバックを使用して、有効な `URLSource` オブジェクトを提供してプレーヤーを更新できます。
 */
-(void)setOnURLSourceExpiredCallback:(void (^)(id expiredSource, id<AVPSourceRefreshCallback> callback))callback;

主要コンポーネント

/**
 @protocol AVPSourceRefreshCallback
 @brief ソースリフレッシュの結果を処理するためのプロトコル。実装する必要があります。

 このプロトコルは、リソースの有効期限が切れたり更新が必要になったりした場合など、プレーヤーがソースのリフレッシュを要求したときにアプリケーションに通知します。このプロトコルのメソッドは、成功または失敗を含むリフレッシュ結果を提供するために呼び出されます。

 @note このプロトコルは、URL ソース、VidAuth ソース、およびリフレッシュロジックを必要とする同様のシナリオに適用されます。
 */
@protocol AVPSourceRefreshCallback <NSObject>

/**
 @brief リフレッシュ操作が成功したときにプレーヤーによって呼び出されます。
 
 @param newSource 更新された情報を含む新しいソースオブジェクト。

 このメソッドは、リフレッシュ操作が正常に完了したことを示します。更新された `newSource` をプレーヤーに
 返して、新しいリソースをロードできるようにする必要があります。
 */
- (void)onSuccess:(id)newSource;

/**
 @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];

        // URL に "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

オーディオの強化

ApsaraVideo Player SDK for iOS は、オーディオ再生体験を向上させるための音質拡張プラグインを提供します。これには、音量ノーマライゼーション、ダイアログエンハンスメント、サラウンドサウンドの 3 つの主要機能が含まれています。

特徴

  • 音量ノーマライゼーション:すべてのオーディオコンテンツを一定の音量レベルに自動的に調整し、元の音量が極端に低いまたは高いビデオの再生を改善します。

    • サポートされるチャンネル:モノラル、ステレオ、5.1、7.1。

    • サポートされるサンプルレート:16 kHz、44.1 kHz、48 kHz。

  • ダイアログエンハンスメント:対話をインテリジェントに強調し、元の音色を変えることなく、騒がしいシーンでの声をよりクリアにします。

    • サポートされるチャンネル:ステレオ。

    • サポートされるサンプルレート:44.1 kHz、48 kHz。

  • サラウンドサウンド:マルチチャンネルおよびステレオオーディオに仮想サラウンドレンダリングを適用し、ヘッドフォンや標準デバイスで没入感のある体験を提供します。3DSurround と MegaBass の 2 つのモードが含まれています。

    • サポートされるチャンネル:モノラル、ステレオ、5.1、7.1。

    • サポートされるサンプルレート:44.1 kHz、48 kHz。

前提条件

  1. ApsaraVideo Player SDK for iOS またはオールインワン SDK は v7.13.0 以降である必要があります。

  2. Professional Edition ライセンスが必要です。詳細については、「ApsaraVideo Player SDK のライセンスを取得する」をご参照ください。

重要

音質拡張機能は、次のオーディオソースをサポートしています。

プラグインの統合

CocoaPods 統合

プラグインの依存関係を Podfile に追加します。

説明

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

// x.x.x はプレーヤー SDK のバージョンと一致する必要があります。
pod 'AliPlayerSDK_iOS_AUDIO_ENHANCE_FILTER', 'x.x.x'

ローカル統合

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

API

setFilterValid

音質拡張機能のマスター スイッチを制御します。音質拡張フィルターの target 名は audioEnhance です。この機能を無効にすると、そのすべてのサブ機能も無効になります。デフォルトでは、この機能は無効になっています。

[player setFilterValid:@"audioEnhance" valid:YES];  // 有効化
[player setFilterValid:@"audioEnhance" valid:NO];   // 無効化
setFilterConfig

prepare メソッドを呼び出す前に FilterConfig オブジェクトを設定します。構成は再生開始時に有効になります。

AVPFilterConfig *filterConfig = [[AVPFilterConfig alloc] init];
AVPFilter *filterItem = [[AVPFilter alloc] initWithTarget:@"audioEnhance"];
AVPFilterOptions *opts = [[AVPFilterOptions alloc] init];
// サラウンドサウンド
[opts setOptions:@"enable_surround" value:@YES];
[opts setOptions:@"surround_effect_type" value:@"3DSurround"]; // サラウンドサウンドを初めて有効にするときにタイプを設定する必要があります。
// ダイアログエンハンスメント
[opts setOptions:@"enable_dialoguenhance" value:@YES];
[opts setOptions:@"dialoguenhance_voice" value:@(1.0)]; // 範囲:1.0 から 10.0。ダイアログエンハンスメントを初めて有効にするときに音声レベルを設定する必要があります。
// 音量ノーマライゼーション
[opts setOptions:@"enable_normalizer" value:@YES];

[filterItem setOptions:opts];
[filterConfig addFilter:filterItem];
[player setFilterConfig:filterConfig];

パラメーター

タイプ

説明

enable_surround

ブール値

サラウンドサウンド機能を有効にするかどうかを指定します。

surround_effect_type

文字列

サラウンドサウンドモード。有効な値:"3DSurround" および "MegaBass"

enable_dialoguenhance

ブール値

ダイアログエンハンスメント機能を有効にするかどうかを指定します。

dialoguenhance_voice

Float

ダイアログエンハンスメントの強度。範囲:1.0 から 10.0

enable_normalizer

ブール値

音量ノーマライゼーション機能を有効にするかどうかを指定します。

updateFilterConfig

プレーヤーの準備ができた後、または再生中にパラメーターを動的に調整するには、このメソッドを呼び出します。

説明

prepare メソッドの前に updateFilterConfig を呼び出しても効果はありません。初期構成には setFilterConfig メソッドを使用してください。

AVPFilterOptions *opts = [[AVPFilterOptions alloc] init];
[opts setOptions:@"enable_surround" value:@YES];
[opts setOptions:@"surround_effect_type" value:@"3DSurround"]; // タイプは、サラウンドサウンドを初めて有効にするときにのみ設定できます。フィルターはすでに初期化されているため、後続の呼び出しでは無視されます。
[player updateFilterConfig:@"audioEnhance" options:opts];
重要

サラウンドサウンドタイプ ("3DSurround" または "MegaBass") とダイアログエンハンスメント強度 (dialoguenhance_voice) は、最初に有効にするときに enable プロパティで構成する必要があります。そうしないと、デフォルト値 ("3DSurround" (サラウンドサウンド) および 1.0 (ダイアログエンハンスメント強度)) に初期化され、再生中に変更することはできません。

パフォーマンス

プレーヤーシーンの設定

プレーヤーシーンを設定すると、バッファ設定や機能の切り替えなど、そのシナリオに最適なパラメーターが自動的に適用されます。setConfig メソッドで設定したカスタムパラメーターは、シーンのデフォルトをオーバーライドします。

説明
  • プレーヤーシーンを設定した後、getConfig メソッドを呼び出して有効な構成を表示できます。

API の例

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

プレーヤーシーン

typedef enum _AVPScene {
    /**
     * 特定のシーンは設定されていません。
     */
    SceneNone,
    /**
     * 長編ビデオシーン。30 分以上のビデオに適しています。
     */
    SceneLong,
    /**
     * 中編ビデオシーン。5 分から 30 分のビデオに適しています。
     */
    SceneMedium,
    /**
     * 短編ビデオシーン。最大 5 分のビデオに適しています。
     */
    SceneShort,
    /**
     * ライブストリーミングシーン。
     */
    SceneLive,
    /**
     * RTS ライブシーン。
     */
    SceneRTSLive
} AVPScene;

使用方法

// 短編ビデオシーンを設定します。
[self.player setPlayerScene:SceneShort];

// 中編ビデオシーンを設定します。
[self.player setPlayerScene:SceneMedium]; 

// 長編ビデオシーンを設定します。
[self.player setPlayerScene:SceneLong];  

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

プリレンダリング

Alibaba Cloud Player SDK for iOS は、再生開始前にビデオの最初のフレームをレンダリングでき、これにより起動速度が向上します。

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

  2. フレームが準備でき次第 View にレンダリングされるように、Prepare を呼び出す前にプレーヤーの View を設定する必要があります。

  3. この機能を有効にすると、準備完了イベントと最初のフレームレンダリングイベントがトリガーされる順序に影響します。この機能が無効の場合、準備完了イベントは最初のフレームレンダリングイベントの前にトリガーされます。この機能が有効の場合、デコードとレンダリングの速度によっては、最初のフレームレンダリングイベントが準備完了イベントの前にトリガーされることがあります。これは再生には影響しません。

次の例に、この機能を有効にする方法を示します。

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

ローカルキャッシュ

説明

詳細なコード例については、「API-Example」プロジェクトの PreloadUrl モジュールをご参照ください。この Objective-C で書かれたサンプルプロジェクトは、Alibaba Cloud Player SDK for iOS のコア機能を統合する方法を示しています。

Alibaba Cloud Player SDK for iOS は、ローカルキャッシュ機能を提供します。この機能は、起動速度とシーク速度を向上させ、カクつきを減らし、繰り返し再生時のネットワークトラフィックを節約します。

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

ローカルキャッシュ機能はデフォルトで無効になっています。この機能を使用するには、AliPlayerGlobalSettings クラスの enableLocalCache メソッドで有効にする必要があります。以下に例を示します。

/**
 * ローカルキャッシュを有効にします。有効にすると、コンテンツはローカルファイルにキャッシュされます。
 * @param enable ローカルキャッシュを有効にするかどうかを指定するブール値。true:有効、false:無効。デフォルト値: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。クリーンアップ中に、合計キャッシュサイズがこの制限を超えた場合、合計サイズが制限内に収まるまで、最も古いキャッシュ項目が 1 つずつ削除されます。
 @param freeStorageMB 最小空きディスク領域 (MB)。デフォルト値:0。クリーンアップ中に、利用可能なディスク領域がこの値より小さい場合、空き領域がこの値以上になるか、すべてのキャッシュファイルが削除されるまで、キャッシュファイルが 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 ビデオの場合、認証パラメーターを削除した後にその keyURL のハッシュ値を計算すると、異なるビデオが同じキャッシュされたキーにヒットし、再生に失敗する可能性があります。解決策:setCacheUrlHashCallback コールバックで、ドメイン名を確認し、再生 URL (http(s)://xxxxx.m3u8?aaaa) からのみ認証パラメーターを削除し、keyURL (http(s)://yyyyy?bbbb) からは削除しないでください。进阶功能-本地缓存.png

  • サーバーが HTTP と HTTPS の両方で同じメディアファイルを提供する場合、ハッシュ値を計算する前にプロトコルを削除または正規化することで、キャッシュヒット率を向上させることができます。例:

    • 再生 URL が https://****.mp4http://****.mp4 の場合、****.mp4 を使用してハッシュ値を計算します。

    • 再生 URL が https://****.mp4 の場合、一貫して http://****.mp4 を使用してハッシュ値を計算できます。

  • Alibaba Cloud 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。
// この URL のローカルキャッシュを有効にするには、この設定と AliPlayerGlobalSettings のグローバル設定の両方を有効にする必要があります。
// これを false に設定すると、この URL のローカルキャッシュは無効になります。
config.enableLocalCache = false;
....// その他の設定

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

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

デフォルトのキャッシュパスを使用するには、AliPlayerGlobalSettings でディレクトリを指定せずにローカルキャッシュを有効にします。

[AliPlayerGlobalSettings enableLocalCache:true];

プリロード

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

プリロードには以下の制限があります。

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

説明

デフォルトでは、Alibaba Cloud Player SDK for iOS は、現在再生中のビデオへの干渉を最小限に抑えるために、プリロード用のネットワークリソースを自動的にスケジュールします。プリロードリクエストは、現在再生中のビデオのバッファが特定のしきい値に達した後にのみ送信されます。この動作を無効にしてプリロードリクエストをリアルタイムで管理するには、次のメソッドを呼び出します。

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

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

    VidAuth (推奨)

    AVPVidAuthSource* vidAuthSource = [[AVPVidAuthSource alloc] init];
    [vidAuthSource setVid:@"your_video_id"]; // 必須。ビデオ ID。
    [vidAuthSource setPlayAuth:@"<yourPlayAuth>"]; // 必須。再生認証情報。ApsaraVideo for VOD の GetVideoPlayAuth オペレーションを呼び出して認証情報を生成する必要があります。
    [vidAuthSource setRegion:@"your_region"]; // このパラメーターは SDK v5.5.5.0 以降では非推奨です。プレーヤーはリージョンを自動的に解析します。以前のバージョンでは、このパラメーターは必須で、デフォルトは cn-shanghai です。
    [vidAuthSource setQuality:@"AUTO"]; // "AUTO" はアダプティブビットレートストリーミングを有効にします。

    VidSts

    AVPVidStsSource* vidStsSource = [[AVPVidStsSource alloc] init];
    [vidStsSource setVid: @"<your_video_id>"]; // 必須。ビデオ ID。
    [vidStsSource setRegion:@"<your_region>"]; // 必須。ApsaraVideo VOD が有効化されているリージョン。デフォルト値:cn-shanghai。
    [vidStsSource setSecurityToken: @"<yourSecurityToken>"]; // 必須。STS セキュリティトークン。STS の AssumeRole API オペレーションを呼び出してトークンを取得する必要があります。
    [vidStsSource setAccessKeySecret: @"<yourAccessKeySecret>"]; // 必須。一時的な STS AccessKey ペアの AccessKey Secret。STS の AssumeRole API オペレーションを呼び出して AccessKey Secret を取得する必要があります。
    [vidStsSource setAccessKeyId: @"<yourAccessKeyId>"]; // 必須。一時的な STS AccessKey ペアの AccessKey ID。STS の AssumeRole API オペレーションを呼び出して AccessKey ID を取得する必要があります。
    [vidStsSource setQuality:@"<your_video_quality>"]; // "AUTO" はアダプティブビットレートストリーミングを指定します。</your_video_quality></your_region></your_video_id>

    UrlSource

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

    説明

    これらのパラメーターはマルチビットレートビデオにのみ適用されます。setDefaultBandWidthsetDefaultResolutionsetDefaultQuality のいずれか 1 つだけを設定する必要があります。

    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; // UrlSource データソース。
    @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. 任意:ロードされたファイルの削除

    スペースを節約するために、キャッシュされたファイルを削除できます。Alibaba Cloud Player SDK for iOS は削除インターフェイスを提供していないため、アプリ内でキャッシュディレクトリから手動でファイルを削除する必要があります。

動的プリロード

動的プリロード戦略により、現在のビデオのキャッシュとプリロードするビデオの数を制御できます。これにより、再生体験とコストのバランスを取ることができます。

コード例

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

// ベースのプリロード時間を設定します。
// プリロード時間を 1,000 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 ビデオのプリロード

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

サポートされているプリロードモード

typedef enum AVPMultiBitratesMode : NSUInteger {
    /**
     * デフォルト構成。デフォルトのビットレートを再生およびプリロードします。
     */
    AVPMultiBitratesMode_Default = 0,
    /**
     * 初回フレーム表示時間を優先します。プレーヤーは、プリロードが完了したビットレートから再生を開始します。
     */
    AVPMultiBitratesMode_FCPrio = 1,
    /**
     * 初回フレーム表示時間とスムーズな再生のバランスを取ります。プレーヤーは、`moveToNext` 呼び出しの前後で同じビットレートを再生しようとします。
     */
    AVPMultiBitratesMode_FC_AND_SMOOTH = 2,
    /**
     * スムーズな再生を優先します。プレーヤーは、前のビデオと同じビットレートで次のビデオを開始しようとします。
     */
    AVPMultiBitratesMode_SmoothPrio = 3,
} AVPMultiBitratesMode;

統合コード

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

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

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

ダウンロード速度

onCurrentDownloadSpeed コールバックの speed パラメーターから、現在再生中のビデオのダウンロード速度を取得できます。以下に例を示します。

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

ネットワーク機能

HTTPDNS

HTTPDNS は、専用の HTTPDNS サーバーに HTTP 経由でリクエストを送信することでドメイン名を解決します。このプロセスにより、より高速で安定したドメイン名解決が提供され、DNS ハイジャックのリスクが軽減されます。

Alibaba Cloud Player SDK は、Alibaba Cloud CDN ドメイン名専用の拡張 HTTPDNS 機能を提供します。正確なネットワークスケジューリングとリアルタイムの解決更新をサポートし、ネットワークパフォーマンスを向上させます。

拡張 HTTPDNS の例

拡張 HTTPDNS 機能は、Alibaba Cloud CDN ドメイン名でのみ利用可能です。適切に構成され、運用可能な Alibaba Cloud CDN ドメイン名を使用していることを確認してください。Alibaba Cloud VOD で高速化ドメイン名を追加および構成するには、「高速化ドメイン名の追加」をご参照ください。CDN ドメイン名の詳細については、「Alibaba Cloud CDN」をご参照ください。

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

HTTP/2

説明

v5.5.0.0 以降、Alibaba Cloud Player SDK for iOS はデフォルトで HTTP/2 を有効にします。

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

[AliPlayerGlobalSettings setUseHttp2:true];

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 のコア機能を統合する方法を示しています。

ApsaraVideo Player SDK for iOS を使用すると、ApsaraVideo VOD コンテンツをダウンロードしてオフライン再生できます。SDK は、標準ダウンロードとセキュアダウンロードの 2 つのダウンロードモードを提供します。

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

  • セキュアダウンロード:ダウンロードされたビデオデータは Alibaba Cloud によって暗号化されています。サードパーティのプレーヤーでは再生できず、ApsaraVideo Player でのみ再生できます。

使用方法

  • ビデオダウンロード機能は、VidSts および VidAuth ソースでのみ利用可能です。

  • ビデオダウンロード機能を使用するには、ApsaraVideo VOD コンソールでダウンロードモードを有効にして構成する必要があります。詳細については、「オフラインダウンロード」をご参照ください。

  • ビデオダウンロード機能は、再開可能なダウンロードをサポートしています。

操作手順

  1. 任意:セキュアダウンロード用のキーファイルを設定します。この手順はセキュアダウンロードの場合にのみ必要です。

    説明

    設定されたキーファイルの情報がアプリの情報と一致していることを確認してください。そうでない場合、ビデオのダウンロードは失敗します。

    セキュアダウンロードモードを使用する場合、ApsaraVideo VOD コンソールで生成したキーファイルを ApsaraVideo 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 メソッドを呼び出してダウンロードソースを準備します。VidSts および VidAuth ソースがサポートされています。次のコードに例を示します。

    • VidSts

      // VidSts ソースを作成します。
      AVPVidStsSource* stsSource = [[AVPVidStsSource alloc] init];
      stsSource.region = @"your_region"; // ご利用の ApsaraVideo VOD サービスリージョン。デフォルト値:cn-shanghai。
      stsSource.vid = @"your_video_id"; // ビデオ ID。
      stsSource.securityToken = @"<yourSecurityToken>"; // STS セキュリティトークン。このトークンを取得するには、STS AssumeRole オペレーションを呼び出します。
      stsSource.accessKeySecret = @"<yourAccessKeySecret>"; // 一時的な STS 認証情報の AccessKey Secret。このシークレットを取得するには、STS AssumeRole オペレーションを呼び出します。
      stsSource.accessKeyId = @"<yourAccessKeyId>"; // 一時的な STS 認証情報の AccessKey ID。この ID を取得するには、STS AssumeRole オペレーションを呼び出します。
      
      // ApsaraVideo VOD コンソールで HLS 暗号化のパラメーターパススルーを有効にしている場合
      // かつ、デフォルトのパラメーター名が MtsHlsUriToken の場合は、config を設定して VidSts ソースに渡す必要があります。
      // この機能が有効でない場合は、次のコードをスキップできます。
      VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
      [vp setHlsUriToken:yourMtsHlsUriToken];
      stsSource.playConfig = [vp generatePlayerConfig];
      // ダウンロードソースを準備します。
      [downloader prepareWithVid:stsSource];
    • VidAuth

      // VidAuth ソースを作成します。
      AVPVidAuthSource *authSource = [[AVPVidAuthSource alloc] init];
      authSource.vid = @"your_video_id"; // ビデオ ID。
      authSource.playAuth = @"<yourPlayAuth>"; // 再生認証情報。この認証情報を取得するには、ApsaraVideo VOD GetVideoPlayAuth オペレーションを呼び出します。
      authSource.region = @"your_region"; // ApsaraVideo Player SDK V5.5.5.0 以降では非推奨です。プレーヤーがリージョンを自動的に解析するためです。
      // 以前のバージョンでは必須です。
      // ご利用の ApsaraVideo VOD サービスリージョン。デフォルト値:cn-shanghai。
      // ApsaraVideo VOD コンソールで HLS 暗号化のパラメーターパススルーを有効にしている場合
      // かつ、デフォルトのパラメーター名が MtsHlsUriToken の場合は、config を設定して VidAuth ソースに渡す必要があります。
      // この機能が有効でない場合は、次のコードをスキップできます。
      VidPlayerConfigGenerator* vp = [[VidPlayerConfigGenerator alloc] init];
      [vp setHlsUriToken:yourMtsHlsUriToken];
      authSource.playConfig = [vp generatePlayerConfig];
      // ダウンロードソースを準備します。
      [downloader prepareWithVid:authSource];
    説明

    ApsaraVideo VOD コンソールで HLS 暗号化のパラメーターパススルーを有効にし、デフォルトのパラメーター名が MtsHlsUriToken の場合は、上記のコードに示すようにダウンロードソースに MtsHlsUriToken の値を設定する必要があります。詳細については、「HLS 暗号化のパラメーターパススルー」をご参照ください。

  5. ソース準備後のビデオトラックの選択

    ダウンロードソースの準備が完了すると、onPrepared メソッドが呼び出されます。コールバックの mediaInfo パラメーターには、ビデオ品質など、利用可能な各ビデオトラックに関する情報が含まれています。ダウンロードするトラックを選択します。次のコードに例を示します。

    -(void)onPrepared:(AliMediaDownloader *)downloader mediaInfo:(AVPMediaInfo *)info {
        NSArray<AVPTrackInfo*>* tracks = info.tracks;
        // 例えば、最初のトラックをダウンロードする場合:
        [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 暗号化をサポートしています。ライブビデオは DRM 暗号化のみをサポートしています。詳細については、「暗号化再生」をご参照ください。

ネイティブ RTS 再生

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

参考