サポート問い合わせ先| システムステータス
ページコンテンツ

    iOS用ネイティブSDKを使用してスニペットをコーディングする

    このトピックでは、SDK を使用して開発する際のリファレンスとして役立つコードスニペットのコレクションを紹介します。より詳細な解決策については、を参照してください。 iOSプレーヤーのサンプル。

    目次

    広告

    アナリティクス

    キャプション

    コンテンツセキュリティ (DRM)

    キューポイント

    再生

    プレイリスト

    スタイル設定

    AirPlay のカスタムコントロール

    Brightcove PlayerUI コントロールを使用している場合は、追加の設定は不要です。AirPlay 機能はすぐに使用でき、ユーザーは Apple TV を使用して高品位ディスプレイに動画をストリーミングできます。

    カスタムコントロールを使用している場合は、以下の手順を実行できます。

    1. AirPlay については、Apple の AirPlay 開発者向けドキュメントを参照してください。

    2. AVPlayer allowsExternalPlayback のプロパティを設定するには、allowsExternalPlayback 再生コントローラのプロパティを使用します。

          _playbackController.allowsExternalPlayback = YES;
          playbackController.allowsExternalPlayback = true
    3. AirPlay ルーターコントロールをセットアップし、その選択を処理します。詳細については、 Apple の AirPlay の概要ドキュメントを参照してください。

    参考

    詳細については、 BCOVPlaybackControllerドキュメンテーション。

    クローズドキャプションボタンのカスタマイズ

    BCovPlayerUI サンプルコードは、iOS 版ネイティブ SDK を使用するときに、Brightcoveプレーヤーをカスタマイズする方法を示しています。詳細については、ネイティブ SDK リファレンスドキュメントの「 PlayerUI コントロールのカスタマイズ」セクションを参照してください。

    PlayerUI を使用してクローズドキャプションボタンをカスタマイズするには、次の手順に従います。

    1. 基本的なビデオ再生アプリから始めます。

    2. ポリシーキー、アカウント ID、ビデオ ID の値を置き換えます。アカウントから、テキストトラックがある動画を選択します。

    3. 標準の VOD レイアウトでプレーヤービューを設定します。

      // Set up our player view. Create with a standard VOD layout.
      BCOVPUIPlayerView *playerView = [[BCOVPUIPlayerView alloc]
      initWithPlaybackController:self.playbackController options:nil controlsView:
      [BCOVPUIBasicControlView basicControlViewWithVODLayout] ];
      // Set up our player view. Create with a standard VOD layout.
      guard let playerView = BCOVPUIPlayerView(playbackController:
      self.playbackController, options: options, controlsView:
      BCOVPUIBasicControlView.withVODLayout()) else {
        return
      }
    4. closedCaptionButtonはと宣言されBCOVPUIButton、UIButtonこれはおよびのサブクラスです。カスタマイズ方法を 3 つ追加しました。BCovPlayerUI コントロールをカスタマイズするときは、いつでもネイティブプレーヤー API を使用できる場所で使用する必要があります。カスタマイズしたコードは次のようになります。

      // Customize the CC button.
      BCOVPUIButton *ccButton = playerView.controlsView.closedCaptionButton;
      ccButton.titleLabel.font = [UIFont systemFontOfSize:14.];
      ccButton.primaryTitle = @"CC";
      [ccButton showPrimaryTitle:YES];
      if let ccButton = playerView.controlsView.closedCaptionButton {
        ccButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        ccButton.primaryTitle = "CC"
        ccButton.showPrimaryTitle(true)
      }

    FairPlay コンテンツを外部画面に表示する

    AVアダプタとHDMIケーブルを使用して外付けディスプレイをiOSデバイスに接続すると、デフォルトの動作ではiOS画面がミラーリングされます。例外は、Fairplay で保護されたビデオを使用する場合です。Appleはミラーリングを禁止します( WWDC 2015、セッション502 )。

    FairPlay で保護された動画を表示するには、Brightcove 再生コントローラを介して公開される AVPlayer プロパティを設定して、FairPlay 動画を外部ディスプレイで再生できるようにします。ビデオが全画面モードで再生されます。これらのプロパティの設定例を次に示します。

    playbackController.allowsExternalPlayback = YES;
    playbackController.usesExternalPlaybackWhileExternalScreenIsActive = YES;
    playbackController.allowsExternalPlayback = true
    playbackController.usesExternalPlaybackWhileExternalScreenIsActive = true

    参考

    詳細については、 BCOVPlaybackControllerドキュメンテーション。

    Google Analytics

    Brightcoveプレーヤーとカタログクラスを使用している場合、動画分析は自動的に収集され、Video Cloud Analytics モジュールに表示されます。その他の指標については、Google アナリティクスをアプリに追加できます。

    Google アナリティクスをアプリと統合するには、次の手順に従います。

    1. Google Analytics for Firebase のセットアップに従い、イベントを処理するファイルに FirebaseAnalytics をインポートしてください。
    2. Googleアナリティクスを使用して、GoogleのFirebase SDKを使用して動画の再生を追跡する方法の1つは次のとおりです。

      @import FirebaseAnalytics;
      
      // This snippet shows one way to track video playback
      // using the Firebase SDK from Google Analytics with
      // the lifecycle event playback controller delegate method.
      - (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent
      {
        // Common parameters
        NSString *video_name = session.video.properties[BCOVVideo.PropertyKeyName] ?: @"";
        NSString *video_ID = session.video.properties[BCOVVideo.PropertyKeyId] ?: @"";
      
        // Session is ready to play
        if ([kBCOVPlaybackSessionLifecycleEventReady isEqualToString:lifecycleEvent.eventType])
        {
          [FIRAnalytics logEventWithName:@"bcov_video_ready"
            parameters:@{
                @"bcov_video_name": video_name,
                @"bcov_video_id": video_ID
            }];
        }
      
        // Session failed to load, failed during playback, or reported a generic error
        NSArray<NSString *> *errorEvents = @[kBCOVPlaybackSessionLifecycleEventFail,
                                                 kBCOVPlaybackSessionLifecycleEventFailedToPlayToEndTime,
                                                 kBCOVPlaybackSessionLifecycleEventError];
        if ([errorEvents containsObject:lifecycleEvent.eventType])
        {
          NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObject:lifecycleEvent.eventType forKey:@"bcov_video_error_event"];
          NSError *error = lifecycleEvent.properties[kBCOVPlaybackSessionEventKeyError];
          if (error)
          {
            parameters[@"bcov_video_error_code"] = @(error.code);
          }
          if (video_name.length > 0)
          {
            parameters[@"bcov_video_name"] = video_name;
          }
          if (video_ID.length > 0)
          {
            parameters[@"bcov_video_id"] = video_ID;
          }
          [FIRAnalytics logEventWithName:@"bcov_video_playback_error" parameters:parameters];
        }
      
        // Session has completed
        if ([kBCOVPlaybackSessionLifecycleEventTerminate isEqualToString:lifecycleEvent.eventType])
        {
          [FIRAnalytics logEventWithName:@"bcov_video_terminate"
            parameters:@{
                @"bcov_video_name": video_name,
                @"bcov_video_id": video_ID
             }];
        }
      }
      import FirebaseAnalytics
      
      // This snippet shows one way to track video playback
      // using the Firebase SDK from Google Analytics with
      // the lifecycle event playback controller delegate method.
      func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) {
      
          // Common parameters
          let video_name = session.video?.properties[BCOVVideo.PropertyKeyName]
          let video_id = session.video?.properties[BCOVVideo.PropertyKeyId]
      
          // Session is ready to play
          if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventReady) {
      
              if let video_name = video_name as? String, let video_id = video_id as? String {
                  Analytics.logEvent("bcov_video_ready", parameters: [
                      "bcov_video_name" : video_name,
                      "bcov_video_id" : video_id
                  ])
              }
      
          }
      
          // Session failed to load, failed during playback, or reported a generic error
          let errorEvents = [kBCOVPlaybackSessionLifecycleEventFail,
                             kBCOVPlaybackSessionLifecycleEventFailedToPlayToEndTime,
                             kBCOVPlaybackSessionLifecycleEventError]
          if errorEvents.contains(lifecycleEvent.eventType) {
      
              var parameters: [String: Any] = ["bcov_video_error_event" : lifecycleEvent.eventType as Any]
              if let error = lifecycleEvent.properties[kBCOVPlaybackSessionEventKeyError] as? NSError {
                  parameters["bcov_video_error_code"] = error.code
              }
              if let video_name = video_name as? String {
                  parameters["bcov_video_name"] = video_name
              }
              if let video_id = video_id as? String {
                  parameters["bcov_video_id"] = video_id
              }
              Analytics.logEvent("bcov_video_playback_error", parameters: parameters)
      
          }
      
          // Session has completed
          if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventTerminate) {
      
              if let video_name = video_name as? String, let video_id = video_id as? String {
                  Analytics.logEvent("bcov_video_terminate", parameters: [
                      "bcov_video_name" : video_name,
                      "bcov_video_id" : video_id
                  ])
              }
      
          }
      
      }

     

    ビットレートの制限

    AVPlayer は HLS レンディションを適応的に選択します。推奨最大ビットレートを設定して選択を調整できますが、厳密な上限ではありません。再生を継続するために必要な場合、AVPlayer は推奨レートを超えることがあります。

    をpreferredPeakBitRate 、指定されたのネットワーク帯域幅消費量の制限値(ビット/秒)に設定しますAVPlayerItem 。

    次のいずれかの宣言を使用します。

    [self.playbackController setPreferredPeakBitRate:1000];
    playbackController.setPreferredPeakBitRate(1000)

    ビデオをループする

    場合によっては、ビデオを自動的に再生したい場合があります。これを行うには、「ビデオの終了」ライフサイクルイベントを取得し、先頭にシークしてもう一度再生します。

    このコードは、このメソッドを使用して PlaybackController のデリゲートをオブジェクトに設定していることを前提としています。

    - (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent
    {
      if ([kBCOVPlaybackSessionLifecycleEventEnd isEqualToString:lifecycleEvent.eventType])
      {
        [controller seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
          if (finished)
          {
            [controller play];
          }
        }];
      }
    }
    func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) {
    
        if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventEnd) {
            controller.seek(to: CMTime.zero) { (finished: Bool) in
                if (finished) {
                    controller.play()
                }
            }
        }
    
    }

    プレイリストの動画を管理する

    ビデオのプレイリストを管理する 1 つの方法は、ビデオオブジェクトをテーブルに格納することです。ユーザーがテーブルからビデオを選択すると、テーブルの行にはビデオオブジェクトが含まれます。

    ここではそれがどのように動作するかについての概要です:

    1. アカウントからプレイリストを取得します。

      - (void)retrievePlaylist
      {
        [self.refreshControl beginRefreshing];
      
        // Retrieve a playlist through the BCOVPlaybackService
        BCOVPlaybackServiceRequestFactory *playbackServiceRequestFactory = [[BCOVPlaybackServiceRequestFactory alloc]
        initWithAccountId:kDynamicDeliveryAccountID
        policyKey:kDynamicDeliveryPolicyKey];
        BCOVPlaybackService *playbackService = [[BCOVPlaybackService alloc] initWithRequestFactory:playbackServiceRequestFactory];
      
        NSDictionary *configuration = @{ BCOVPlaybackService.ConfigurationKeyAssetReferenceID: kDynamicDeliveryPlaylistRefID };
        [playbackService findPlaylistWithConfiguration:configuration queryParameters:nil
        completion:^(BCOVPlaylist *playlist, id jsonResponse, NSError *error)
        {
          [self.refreshControl endRefreshing];
      
          NSLog(@"JSON Response:\n%@", jsonResponse);
      
          if (playlist)
          {
            self.currentVideos = playlist.videos.mutableCopy;
            self.currentPlaylistTitle = playlist.properties[@"name"];
            self.currentPlaylistDescription = playlist.properties[@"description"];
      
            NSLog(@"Retrieved playlist containing %d videos", (int)self.currentVideos.count);
      
            [self usePlaylist:self.currentVideos];
          }
          else
          {
            NSLog(@"No playlist for reference ID %@ was found: %@", kDynamicDeliveryPlaylistRefID, error);
          }
      
        }];
      }
      func retrievePlaylist() {
          refreshControl.beginRefreshing()
      
          let playbackServiceRequestFactory = BCOVPlaybackServiceRequestFactory(withAccountId: kDynamicDeliveryAccountID, policyKey: kDynamicDeliveryPolicyKey)
          let playbackService = BCOVPlaybackService(withRequestFactory: playbackServiceRequestFactory)
      
          let configuration = [BCOVPlaybackService.ConfigurationKeyAssetReferenceID: kDynamicDeliveryPlaylistRefID]
          playbackService.findPlaylist(withConfiguration: configuration, queryParameters: nil, completion: { [weak self] (playlist: BCOVPlaylist?, jsonResponse: Any?, error: Error?) in
      
              guard let strongSelf = self else {
                  return
              }
      
              strongSelf.refreshControl.endRefreshing()
      
              if let playlist = playlist {
                  strongSelf.currentVideos = playlist.videos
                  strongSelf.currentPlaylistTitle = playlist.properties["name"] as? String ?? ""
                  strongSelf.currentPlaylistDescription = playlist.properties["description"] as? String ?? ""
      
                  print("Retrieved playlist containing \(playlist.videos.count) videos")
      
                  strongSelf.usePlaylist(playlist)
              } else {
                  print("No playlist for reference ID \(kDynamicDeliveryPlaylistRefID) was found: \(error?.localizedDescription ?? "unknown error")")
              }
      
          })
      }
    2. 現在のプレイリストのビデオに関連する情報を格納するコンテナを再初期化します。

    3. テーブルビューが選択されると、行のインデックスを使用して新しいが作成されますvideoDictionary。次に、辞書にビデオを依頼してください。ビデオが null でない場合は、にビデオをロードしますplaybackController。

      // Play the video in this row when selected
      - (IBAction)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(nonnull NSIndexPath *)indexPath
      {
        NSDictionary *videoDictionary = self.videosTableViewData[ (int)indexPath.row ];
        BCOVVideo *video = videoDictionary[@"video"];
      
        if (video != nil)
        {
          [self.playbackController setVideos:@[ video ]];
        }
      }
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      
          guard let videosTableViewData = videosTableViewData,
          let videoDictionary = videosTableViewData[indexPath.row] as?
          [AnyHashable:Any], let video = videoDictionary["video"] as? BCOVVideo else {
              return
          }
      
          playbackController.setVideos([video])
      
      }

    プレイリストを操作するには、プレイリストをテーブルなどの別のオブジェクトに保存できます。ユーザーの操作に基づいて、オブジェクトのインデックスをナビゲートし、適切なビデオを選択できます。

    メディアの進行状況値

    メディアの再生中に、Player SDK 進行状況デリゲートメソッドに報告される値には、負の無限大と正の無限大の最終値が含まれます。これらの値は、プリロール広告とポストロール広告を処理するときに使用されます。

    これらの値が重要でない場合、または独自の進捗追跡を妨げている場合は、次のような条件文で簡単に無視できます。

    - (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didProgressTo:(NSTimeInterval)progress
    {
      if (progress < 0.0 || progress >= INFINITY)
      {
        return;
      }
    
      // Your code here
    }
    func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didProgressTo progress: TimeInterval) {
    
        if (progress < 0.0 || progress >= Double.infinity) {
            return;
        }
    
        // Your code here
    }

    参考

    詳細については、 BCOVPlaybackControllerドキュメンテーション。

    プログラムによるキャプションの変更

    字幕は、再生中いつでも設定できます。Readyイベントを受信しました。これを行うには、 BCOVPlaybackControllerDelegate。

    キャプション言語をスペイン語に設定する例を次に示します。

    - (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent
    {
        if ([kBCOVPlaybackSessionLifecycleEventReady isEqualToString:lifecycleEvent.eventType])
        {
            AVMediaSelectionGroup *legibleMediaSelectionGroup = session.legibleMediaSelectionGroup;
            NSArray<AVMediaSelectionOption *> *options = [AVMediaSelectionGroup mediaSelectionOptionsFromArray:legibleMediaSelectionGroup.options withLocale:[NSLocale localeWithLocaleIdentifier:@"es"]];
            AVMediaSelectionOption *option = options.firstObject;
            session.selectedLegibleMediaOption = option;
        }
    }
    func playbackController(_ controller: BCOVPlaybackController?, playbackSession session: BCOVPlaybackSession?, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent?) {
        if kBCOVPlaybackSessionLifecycleEventReady == lifecycleEvent?.eventType {
            if let legibleMediaSelectionGroup = session?.legibleMediaSelectionGroup?.options {
                let locale = NSLocale(localeIdentifier: "es") as Locale
                let mediaSelectionOptions = AVMediaSelectionGroup.mediaSelectionOptions(from: legibleMediaSelectionGroup, with: locale)
                let mediaSelectionOption = mediaSelectionOptions.first
                session?.selectedLegibleMediaOption = mediaSelectionOption
            }
        }
    }

    再生 API を使用したページング

    再生 API から Video Cloud コンテンツを取得するときに、プレイリストのページングを実装できます。

    プレイリストの一連の動画をページに移動するには、次のリクエスト URL パラメータを使用します。

    • limit -再生APIから返す動画の数を定義します
    • offset -再生APIから再生リストでスキップする動画の数を設定します

    この例では、再生リスト内の 10 番目の動画から 6 つの動画を返します。

    NSDictionary *configuration = @{ BCOVPlaybackService.ConfigurationKeyAssetReferenceID: playlistRefID };
    NSDictionary *params = @{
      @"limit": @6,
      @"offset": @9
    };
    
    [playbackService findPlaylistWithConfiguration:configuration queryParameters:params completion:^(BCOVPlaylist *playlist, id jsonResponse, NSError *error)
    {
        // Your code here
    }];
    let configuration = [BCOVPlaybackService.ConfigurationKeyAssetReferenceID: playlistRefID]
    let params = [
        "limit": 6,
        "offset": 9
    ]
    
    playbackService.findPlaylist(withConfiguration: configuration, queryParameters: params, completion: { (playlist: BCOVPlaylist?, jsonResponse: Any?, error: Error?) in
        // Your code here
    })

    プログラムによるキューポイントの追加

    Video Cloud のお客様は、ビデオへのキューポイントの追加ドキュメントに示すように、Video Cloud Studio を使用してビデオにキューポイントを追加できます。

    動画にキューポイントをプログラムで追加することもできます。以下のコードは、Playback API から返された動画の長さの 4 分の 1 ごとにキューポイントを追加します。

    // programmatically add cue points to a video
    - (void)requestContentFromPlaybackService
    {
        NSDictionary *configuration = @{ BCOVPlaybackService.ConfigurationKeyAssetID: kViewControllerVideoID };
        [self.service findVideoWithConfiguration:configuration queryParameters:nil completion:^(BCOVVideo *video, id jsonResponse, NSError *error) {
            if (video)
            {
                // Get the video duration from the properties dictionary
                NSNumber *durationNumber = video.properties[@"duration"]; // milliseconds
                float duration = durationNumber.floatValue / 1000.0; // convert to seconds
                video = [video update:^(BCOVMutableVideo * mutableVideo)
                {
                    // Add quarterly interval cue points of your own type
                    BCOVCuePoint *cp1 = [[BCOVCuePoint alloc] initWithType:@"your cue point type" position:CMTimeMake(duration * 250, 1000)];
                    BCOVCuePoint *cp2 = [[BCOVCuePoint alloc] initWithType:@"your cue point type" position:CMTimeMake(duration * 500, 1000)];
                    BCOVCuePoint *cp3 = [[BCOVCuePoint alloc] initWithType:@"your cue point type" position:CMTimeMake(duration * 750, 1000)];
                    BCOVCuePoint *cp4 = [[BCOVCuePoint alloc] initWithType:@"your cue point type" position:CMTimeMake(duration * 1000, 1000)];
                    // Create new cue point collection using existing cue points and new cue points
                    NSMutableArray *newCuePoints = [NSMutableArray arrayWithArray:mutableVideo.cuePoints.array ?: @[]];
                    [newCuePoints addObject:cp1];
                    [newCuePoints addObject:cp2];
                    [newCuePoints addObject:cp3];
                    [newCuePoints addObject:cp4];
                    mutableVideo.cuePoints = [[BCOVCuePointCollection alloc] initWithArray:newCuePoints];
                }];
    
                [self.playbackController setVideos:@[ video ]];
            }
            else
            {
                NSLog(@"ViewController Debug - Error retrieving video: `%@`", error);
            }
        }];
    }
    // programmatically add cue points to a video
    func requestContentFromPlaybackService() {
        let configuration = [BCOVPlaybackService.ConfigurationKeyAssetID: kViewControllerVideoID]
        playbackService.findVideo(withConfiguration: configuration, queryParameters: nil) { [weak self] (video: BCOVVideo?, jsonResponse: Any?, error: Error?) in
    
            if let error = error {
                print("ViewController Debug - Error retrieving video: `\(error.localizedDescription)`")
            }
    
            if let video = video {
    
                // Get the video duration from the properties dictionary
                guard let durationNumber = video.properties["duration"] as? NSNumber else {
                    return
                }
    
                let duration = durationNumber.floatValue / 1000.0; // convert to seconds
    
                let updatedVideo = video.update({ (mutableVideo: BCOVMutableVideo) in
    
                    // Add quarterly interval cue points of your own type
                    let cp1Position = CMTimeMake(value: Int64(duration * 250), timescale: 1000)
                    let cp1 = BCOVCuePoint(withType: "your cue point type", position: cp1Position)
                    let cp2Position = CMTimeMake(value: Int64(duration * 500), timescale: 1000)
                    let cp2 = BCOVCuePoint(withType: "your cue point type", position: cp2Position)
                    let cp3Position = CMTimeMake(value: Int64(duration * 750), timescale: 1000)
                    let cp3 = BCOVCuePoint(withType: "your cue point type", position: cp3Position)
                    let cp4Position = CMTimeMake(value: Int64(duration * 1000), timescale: 1000)
                    let cp4 = BCOVCuePoint(withType: "your cue point type", position: cp4Position)
    
                    // Create new cue point collection using existing cue points and new cue points
                    var newCuePoints = mutableVideo.cuePoints?.array ?? []
                    newCuePoints.append(cp1)
                    newCuePoints.append(cp2)
                    newCuePoints.append(cp3)
                    newCuePoints.append(cp4)
    
                    mutableVideo.cuePoints = BCOVCuePointCollection(withArray: newCuePoints)
                })
    
                self?.playbackController.setVideos([updatedVideo])
            }
    
        }
    }

     

    の値に注意してくださいyour cue point type を使用していない限り、任意の文字列値にすることができますiOSプラグイン。詳細については、 BCovCuePoint プロトコルリファレンスのドキュメントを参照してください。

    IMA プラグインでキューポイントを使用している場合は、iOS 用 Native SDK 用の IMA プラグインノートの「 VAST および VMap/サーバー側広告ルール」セクションを参照してください。IMA サンプルアプリには、IMA 広告キューポイントに必要な値が表示されます。

    以下のコードは、キューポイントをリッスンし、メッセージを表示します。

    // listen for cue points and display them
    -(void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didPassCuePoints:(NSDictionary *)cuePointInfo
    {
        BCOVCuePointCollection *cpc = cuePointInfo[kBCOVPlaybackSessionEventKeyCuePoints];
        for (BCOVCuePoint *cp in cpc.array)
        {
            if ([cp.type isEqualToString:@"your cue point type"])
            {
                NSLog(@"Found your cue point at %f", CMTimeGetSeconds(cp.position));
            }
        }
    }
    // listen for cue points and display them
    func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didPassCuePoints cuePointInfo: [AnyHashable : Any]!) {
        if let cpc = cuePointInfo[kBCOVPlaybackSessionEventKeyCuePoints] as? BCOVCuePointCollection {
            for cp in cpc.array {
                if cp.type == "your cue point type" {
                    print("Found your cue point at \(CMTimeGetSeconds(cp.position))")
                }
            }
        }
    }

    参考文献

    詳細については、以下を参照してください。

    プレーヤーの削除

    プレイヤーとビューを削除したい場合があります。

    BCOVPlaybackControllerの所有権を持つビューコントローラの割り当てを解除すると、再生コントローラの割り当ても解除されます。これを行うには、スーパービューからプレーヤービューを削除し、再生コントローラポインタをに設定しますnil。

    コードの例は次のとおりです。

    [self.playerView removeFromSuperview];
    self.playerView = nil;
    self.playbackController = nil;
    playerView?.removeFromSuperview()
    playerView = nil
    playbackController = nil

    オーディオ動作の設定

    オーディオセッションは、アプリレベルでオーディオの動作を処理します。複数のオーディオセッションカテゴリと設定から選択して、アプリのオーディオ動作をカスタマイズできます。

    アプリに最適なオーディオセッションカテゴリを選択します。詳細については、Appleのドキュメントを確認してください。

    基本サンプル

    基本的なサンプルには、AVAudioSessionCategoryPlayback。これにより、画面がロックされ、Ring/Silent スイッチがサイレントに設定されている場合でも、オーディオが再生されます。簡単にするために、このコードをAppDelegateに配置します。

    NSError *categoryError = nil;
    BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&categoryError];
    if (!success)
    {
        // Handle error
    }
    var categoryError :NSError?
    var success: Bool
    do {
        try AVAudioSession.sharedInstance().setCategory(.playback)
        success = true
    } catch let error as NSError {
        categoryError = error
        success = false
    }
    if !success {
        // Handle error
    }

    他のオーディオとミックスする

    アプリの音声がミュートされているときに、他のアプリからの音声が聞こえるようにすることができます。これを行うには、AVAudioSession現在のビューコントローラにアクセスできるビューコントローラでAVPlayer。

    詳細については、 mixWithOthersカテゴリオプション。

    - (void)setUpAudioSession
    {
        NSError *categoryError = nil;
        BOOL success;
    
        // If the player is muted, then allow mixing.
        // Ensure other apps can have their background audio active when this app is in foreground
        if (self.currentPlayer.isMuted)
        {
            success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&categoryError];
        }
        else
        {
            success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:0 error:&categoryError];
        }
    
        if (!success)
        {
            NSLog(@"AppDelegate Debug - Error setting AVAudioSession category.  Because of this, there may be no sound. `%@`", categoryError);
        }
    }
    func setUpAudioSession() {
      var categoryError :NSError?
      var success: Bool
      do {
          if let currentPlayer = currentPlayer {
              // If the player is muted, then allow mixing.
              // Ensure other apps can have their background audio active when this app is in foreground
              if currentPlayer.isMuted {
                  try AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
              } else {
                  try AVAudioSession.sharedInstance().setCategory(.playback, options: AVAudioSession.CategoryOptions(rawValue: 0))
              }
          } else {
              try AVAudioSession.sharedInstance().setCategory(.playback, options: AVAudioSession.CategoryOptions(rawValue: 0))
          }
    
          success = true
      } catch let error as NSError {
          categoryError = error
          success = false
      }
      if !success {
          print("AppDelegate Debug - Error setting AVAudioSession category.  Because of this, there may be no sound. \(categoryError!)")
      }
    }

    再生レートの設定

    再生速度を制御するには、AVPlayer.rate を直接設定するのではなく、BCOVPlaybackController の playbackRate プロパティを設定します。これにより、SDK は再生操作の間も速度を維持できます。

    0 以下の値を設定すると、速度は 1.0 になります。1.0 未満の速度には現在の項目の canPlaySlowForward、1.0 を超える速度には canPlayFastForward のサポートが必要です。サポートされていない場合、SDK は 1.0 を使用します。カスタム速度を設定すると、SDK は各項目の audioTimePitchAlgorithm を timeDomain に設定します。以下の例のように、項目ごとに varispeed で上書きすることもできます。この例では速度 1.7 を使用しています。

    avPlayerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;

    の場合BCOVPlaybackSession 、コードは次のようになります。

    - (void)playbackController:(id<BCOVPlaybackController>)controller
      playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent
    {
        if ( [lifecycleEvent.eventType isEqualToString:kBCOVPlaybackSessionLifecycleEventReady] )
        {
            NSLog(@"%@ at time %f", kBCOVPlaybackSessionLifecycleEventReady, CMTimeGetSeconds([session.player currentTime]));
            controller.playbackRate = 1.7;
            AVPlayerItem *avPlayerItem = [session.player currentItem];
            avPlayerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;
        }
    }
    func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) {
    
        if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventReady) {
            guard let player = session.player else { return }
            let seconds = CMTimeGetSeconds(player.currentTime())
            print("kBCOVPlaybackSessionLifecycleEventReady at time \(seconds)")
            controller.playbackRate = 1.7
            let avPlayerItem = player.currentItem
            avPlayerItem?.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithm.varispeed
        }
    
    }

     

    360° 動画の VR ゴーグルモードの設定

    360°ビデオを再生する場合、ユーザーはコントロールバーの [Video 360] ボタンを選択して VR ゴーグルモードに切り替えることができます。再生を開始する前に、これをプログラムで実行することもできます。あなたは更新することによってこれを行うことができますBCOVPlaybackController プロトコルのviewProjection 次のようにプロパティ:

    - (void)playbackController:(id<BCOVPlaybackController>)controller didAdvanceToPlaybackSession:(id<BCOVPlaybackSession>)session
    {
        BCOVVideo360ViewProjection *viewProjection = [self.playbackController.viewProjection copy];
        [viewProjection setProjectionStyle:BCOVVideo360ProjectionStyleVRGoggles];
        [self.playbackController setViewProjection:viewProjection];
    }
    func playbackController(_ controller: BCOVPlaybackController!, didAdvanceTo session: BCOVPlaybackSession!) {
        if let viewProjection: BCOVVideo360ViewProjection = controller.viewProjection.copy() as? BCOVVideo360ViewProjection {
            viewProjection.projectionStyle = BCOVVideo360ProjectionStyle.vrGoggles
            controller.viewProjection = viewProjection
        }
    }

     

    表示範囲に入ったときに再生を開始する

    この例では、プレーヤーが表示範囲に入ると再生を開始し、表示範囲から外れると一時停止するコードを作成します。

    以下のコードは、ウィンドウ座標とクリッピングを行う祖先ビューを使用して、プレーヤービューの表示割合を 0.0 から 1.0 で返します。他のビューがプレーヤーを覆っているか、アプリがバックグラウンドにあるかは検出しません。表示割合が 0.5 以上なら再生を継続し、0.5 未満なら一時停止するなど、動作の条件を決められます。メインスレッドで NSTimer などを使用して表示状態を定期的に確認し、アプリのバックグラウンド移行は別途処理してください。

    + (CGFloat)visibleFractionForView:(UIView *)view
              {
                  UIWindow *window = view.window;
                  if (!window || view.hidden || view.alpha == 0.0)
                  {
                      return 0.0;
                  }
                  CGRect frameInWindow = [view convertRect:view.bounds toView:window];
                  CGFloat viewArea = CGRectGetWidth(frameInWindow) * CGRectGetHeight(frameInWindow);
                  if (viewArea <= 0.0)
                  {
                      return 0.0;
                  }
                  CGRect intersection = CGRectIntersection(frameInWindow, window.bounds);
                  // Account for ancestor views that clip their subviews.
                  for (UIView *ancestor = view.superview; ancestor; ancestor = ancestor.superview)
                  {
                      if (ancestor.hidden || ancestor.alpha == 0.0) { return 0.0; }
                      if (ancestor.clipsToBounds)
                      {
                          CGRect clipRect = [ancestor convertRect:ancestor.bounds toView:window];
                          intersection = CGRectIntersection(intersection, clipRect);
                      }
                  }
                  if (CGRectIsNull(intersection) || CGRectIsEmpty(intersection)) { return 0.0; }
                  CGFloat visibleArea = CGRectGetWidth(intersection) * CGRectGetHeight(intersection);
                  return MIN(1.0, MAX(0.0, visibleArea / viewArea));
              }

    背景色の変更

    ポートレートモードでビデオを再生すると、プレーヤーの上下に黒い境界線が表示されることがあります。プレーヤービューは画面のサイズですが、ビデオはプレーヤービューの中央のごく一部を占めます。ビデオの周囲に表示される部分は、プレーヤーレイヤーの背景です。

    AVPlayer これは正常な動作です。動画はプレーヤーレイヤー内に収まるように縮小され、残りはプレーヤーレイヤーの背景になります。

    プレイヤーレイヤーの背景は、次のコードで変更できます。

    - (void)playbackController:(id<BCOVPlaybackController>)controller didAdvanceToPlaybackSession:(id<BCOVPlaybackSession>)session
    {
        session.playerLayer.backgroundColor = UIColor.whiteColor.CGColor;
    }
    func playbackController(_ controller: BCOVPlaybackController!, didAdvanceTo session: BCOVPlaybackSession!) {
        session.playerLayer.backgroundColor = UIColor.white.cgColor
    }

     

    背景色を白に設定すると、次のようになります。

    Background color
    カスタム背景色

    ページの最終更新日20 Oct 2026