目次
広告
アナリティクス
コンテンツセキュリティ (DRM)
キューポイント
再生
プレイリスト
スタイル設定
AirPlay のカスタムコントロール
Brightcove PlayerUI コントロールを使用する場合は、すべて設定されています。AirPlay 機能はすぐに使用できるので、ユーザーは Apple TV を使用して高品位ディスプレイにビデオをストリーミングできます。
カスタムコントロールを使用している場合は、以下の手順を実行できます。
-
AirPlay については、 Apple の AirPlay 開発者向けドキュメントを参照してください。
-
AVPlayer
allowsExternalPlayback
のプロパティを設定するには、allowsExternalPlayback
再生コントローラのプロパティを使用します。- Obj-C
- スウィフト
_playbackController.allowsExternalPlayback = YES;
playbackController.allowsExternalPlayback = true
-
AirPlay ルーターコントロールをセットアップし、その選択を処理します。詳細については、 Apple の AirPlay の概要ドキュメントを参照してください。
参考
詳細については、 BCOVPlaybackControllerドキュメンテーション。
クローズドキャプションボタンのカスタマイズ
BCovPlayerUI サンプルコードは、iOS 版ネイティブ SDK を使用するときに、Brightcoveプレーヤーをカスタマイズする方法を示しています。詳細については、ネイティブ SDK リファレンスドキュメントの「 PlayerUI コントロールのカスタマイズ」セクションを参照してください。
PlayerUI を使用してクローズドキャプションボタンをカスタマイズするには、次の手順に従います。
-
ポリシーキー、アカウント ID、ビデオ ID の値を置き換えます。アカウントから、テキストトラックがある動画を選択します。
-
標準の VOD レイアウトでプレーヤービューを設定します。
- Obj-C
- スウィフト
// 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 }
-
closedCaptionButton
はと宣言されBCOVPUIButton
、UIButton
これはおよびのサブクラスです。カスタマイズ方法を 3 つ追加しました。BCovPlayerUI コントロールをカスタマイズするときは、いつでもネイティブプレーヤー API を使用できる場所で使用する必要があります。カスタマイズしたコードは次のようになります。- Obj-C
- スウィフト
// 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 動画を外部ディスプレイで再生できるようにします。ビデオが全画面モードで再生されます。これらのプロパティの設定例を次に示します。
- Obj-C
- スウィフト
playbackController.allowsExternalPlayback = YES;
playbackController.usesExternalPlaybackWhileExternalScreenIsActive = YES;
playbackController.allowsExternalPlayback = true
playbackController.usesExternalPlaybackWhileExternalScreenIsActive = true
参考
詳細については、 BCOVPlaybackControllerドキュメンテーション。
Google Analytics
Brightcoveプレーヤーとカタログクラスを使用している場合、動画分析は自動的に収集され、Video Cloud Analytics モジュールに表示されます。その他の指標については、Google アナリティクスをアプリに追加できます。
Google アナリティクスをアプリと統合するには、次の手順に従います。
- Google のドキュメントを確認して iOS アプリにアナリティクスを追加してください。
-
Googleアナリティクスを使用して、GoogleのFirebase SDKを使用して動画の再生を追跡する方法の1つは次のとおりです。
- Obj-C
- スウィフト
// 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[kBCOVVideoPropertyKeyName]; NSString *video_ID = session.video.properties[kBCOVVideoPropertyKeyId]; // 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 encountered an error if ([kBCOVPlaybackSessionLifecycleEventError isEqualToString:lifecycleEvent.eventType]) { NSError *error = lifecycleEvent.properties[kBCOVPlaybackSessionEventKeyError]; int error_code = error.code; [FIRAnalytics logEventWithName:@"bcov_video_playback_error" parameters:@{ @"bcov_video_name": video_name, @"bcov_video_id": video_ID, @"bcov_video_error_code": @(error_code) }]; } // Session has completed if ([kBCOVPlaybackSessionLifecycleEventTerminate isEqualToString:lifecycleEvent.eventType]) { [FIRAnalytics logEventWithName:@"bcov_video_terminate" parameters:@{ @"bcov_video_name": video_name, @"bcov_video_id": video_ID }]; } }
// 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[kBCOVVideoPropertyKeyName] let video_id = session.video.properties[kBCOVVideoPropertyKeyId] // 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 encountered an error if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventError) { if let error = lifecycleEvent.properties[kBCOVPlaybackSessionEventKeyError] as? NSError { let error_code = error.code if let video_name = video_name as? String, let video_id = video_id as? String { Analytics.logEvent("bcov_video_playback_error", parameters: [ "bcov_video_name" : video_name, "bcov_video_id" : video_id, "bcov_video_error_code" : error_code ]) } } } // 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 ]) } } }
ビットレートの制限
HLS マニフェストでどのソース(レンディション)がによって選択されるかを制御することはできませんがAVPlayer
、再生時にビットレートキャップを付けることはできます。これにより、プレーヤーは指定されたビットレートを超えるビットレートのソース (レンディション) を使用できなくなります。
をpreferredPeakBitRate
、指定されたのネットワーク帯域幅消費量の制限値(ビット/秒)に設定しますAVPlayerItem
。
次のいずれかの宣言を使用します。
- Obj-C
- スウィフト
[self.playbackController setPreferredPeakBitRate:1000];
playbackController.setPreferredPeakBitRate(1000)
ビデオをループする
場合によっては、ビデオを自動的に再生したい場合があります。これを行うには、「ビデオの終了」ライフサイクルイベントを取得し、先頭にシークしてもう一度再生します。
このコードは、このメソッドを使用して PlaybackController のデリゲートをオブジェクトに設定していることを前提としています。
- Obj-C
- スウィフト
- (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 つの方法は、ビデオオブジェクトをテーブルに格納することです。ユーザーがテーブルからビデオを選択すると、テーブルの行にはビデオオブジェクトが含まれます。
ここではそれがどのように動作するかについての概要です:
-
アカウントからプレイリストを取得します。
- Obj-C
- スウィフト
- (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]; [playbackService findPlaylistWithReferenceID:kDynamicDeliveryPlaylistRefID parameters:nil completion:^(BCOVPlaylist *playlist, NSDictionary *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 ID %@ was found.", kDynamicDeliveryPlaylistRefID); } }]; }
func retrievePlaylist() { refreshControl.beginRefreshing() let playbackServiceRequestFactory = BCOVPlaybackServiceRequestFactory(accountId: kDynamicDeliveryAccountID, policyKey: kDynamicDeliveryPolicyKey) let playbackService = BCOVPlaybackService(requestFactory: playbackServiceRequestFactory) playbackService?.findPlaylist(withPlaylistID: kDynamicDeliveryPlaylistRefID, parameters: nil, completion: { [weak self] (playlist: BCOVPlaylist?, jsonResponse: [AnyHashable: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 ID \(kDynamicDeliveryPlaylistRefID) was found."); } }) }
-
現在のプレイリストのビデオに関連する情報を格納するコンテナを再初期化します。
-
テーブルビューが選択されると、行のインデックスを使用して新しいが作成されます
videoDictionary
。次に、辞書にビデオを依頼してください。ビデオが null でない場合は、にビデオをロードしますplaybackController
。- Obj-C
- スウィフト
// 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] as NSFastEnumeration) }
プレイリストを操作するには、プレイリストをテーブルなどの別のオブジェクトに保存できます。ユーザーの操作に基づいて、オブジェクトのインデックスをナビゲートし、適切なビデオを選択できます。
メディアの進行状況値
メディアの再生中に、Player SDK 進行状況デリゲートメソッドに報告される値には、負の無限大と正の無限大の最終値が含まれます。これらの値は、プリロール広告とポストロール広告を処理するときに使用されます。
これらの値が重要でない場合、または独自の進捗追跡を妨げている場合は、次のような条件文で簡単に無視できます。
- Obj-C
- スウィフト
- (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。
キャプション言語をスペイン語に設定する例を次に示します。
- Obj-C
- スウィフト
- (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 パラメータを使用します。
この例では、再生リスト内の 10 番目の動画から 6 つの動画を返します。
- Obj-C
- スウィフト
NSDictionary *params = @{
@"limit": @6,
@"offset": @9
};
[playbackService findPlaylistWithReferenceID:playlistRefID parameters:params completion:^(BCOVPlaylist *playlist, NSDictionary *jsonResponse, NSError *error)
{
// Your code here
}];
let params = [
"limit": 6,
"offset": 9
]
playbackService?.findPlaylist(withPlaylistID: playlistRefID, parameters: params, completion: { (playlist: BCOVPlaylist?, jsonResponse: [AnyHashable:Any]?, error: Error?) in
// Your code here
})
プログラムによるキューポイントの追加
Video Cloud のお客様は、ビデオへのキューポイントの追加ドキュメントに示すように、Video Cloud Studio を使用してビデオにキューポイントを追加できます。
プログラムを使用してビデオにキューポイントを追加することもできます。以下のコードは、Playback API から返されたビデオに 4 分ごとのインターバルキューポイントを追加します。
- Obj-C
- スウィフト
// programmatically add cue points to a video
- (void)requestContentFromPlaybackService
{
[self.service findVideoWithVideoID:kViewControllerVideoID parameters:nil completion:^(BCOVVideo *video, NSDictionary *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:^(id<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 alloc] initWithArray: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() {
playbackService?.findVideo(withVideoID: kViewControllerVideoID, parameters: nil)
{ [weak self] (video: BCOVVideo?, jsonResponse: [AnyHashable: Any]?, error: Error?) -> Void 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
guard let mutableVideo = mutableVideo else {
return
}
// Add quarterly interval cue points of your own type
let cp1Position = CMTimeMake(value: Int64(duration * 250), timescale: 1000)
let cp1 = BCOVCuePoint(type: "your cue point type", position: cp1Position)!
let cp2Position = CMTimeMake(value: Int64(duration * 500), timescale: 1000)
let cp2 = BCOVCuePoint(type: "your cue point type", position: cp2Position)!
let cp3Position = CMTimeMake(value: Int64(duration * 750), timescale: 1000)
let cp3 = BCOVCuePoint(type: "your cue point type", position: cp3Position)!
let cp4Position = CMTimeMake(value: Int64(duration * 1000), timescale: 1000)
let cp4 = BCOVCuePoint(type: "your cue point type", position: cp4Position)!
// Create new cue point collection using existing cue points and new cue points
var newCuePoints = [BCOVCuePoint]()
newCuePoints.append(cp1)
newCuePoints.append(cp2)
newCuePoints.append(cp3)
newCuePoints.append(cp4)
mutableVideo.cuePoints = BCOVCuePointCollection(array: newCuePoints)
})
self?.playbackController.setVideos([updatedVideo] as NSFastEnumeration)
}
}
}
の値に注意してくださいyour cue point type
を使用していない限り、任意の文字列値にすることができますiOSプラグイン。詳細については、 BCovCuePoint プロトコルリファレンスのドキュメントを参照してください。
IMA プラグインでキューポイントを使用している場合は、iOS 用 Native SDK 用の IMA プラグインノートの「 VAST および VMap/サーバー側広告ルール」セクションを参照してください。IMA サンプルアプリには、IMA 広告キューポイントに必要な値が表示されます。
以下のコードは、キューポイントをリッスンし、メッセージを表示します。
- Obj-C
- スウィフト
// 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 let cp = cp as? BCOVCuePoint {
if (cp.type == "your cue point type") {
print("Found your cue point at \(CMTimeGetSeconds(cp.position))")
}
}
}
}
}
参考文献
詳細については、以下を参照してください。
- BCOVVideoドキュメンテーション
- BCOVCuePointドキュメンテーション
プレーヤーの削除
プレイヤーとビューを削除したい場合があります。
BCOVPlaybackController
の所有権を持つビューコントローラの割り当てを解除すると、再生コントローラの割り当ても解除されます。これを行うには、スーパービューからプレーヤービューを削除し、再生コントローラポインタをに設定しますnil
。
コードの例は次のとおりです。
- Obj-C
- スウィフト
[self.playerView removeFromSuperview];
self.playerView = nil;
self.playbackController = nil;
playerView?.removeFromSuperview()
playerView = nil
playbackController = nil
オーディオ動作の設定
オーディオセッションは、アプリレベルでオーディオの動作を処理します。複数のオーディオセッションカテゴリと設定から選択して、アプリのオーディオ動作をカスタマイズできます。
アプリに最適なオーディオセッションカテゴリを選択します。詳細については、Appleのドキュメントを確認してください。
- AVAudioSessionクラス
- AVAudioSessionCategory
基本サンプル
基本的なサンプルには、AVAudioSessionCategoryPlayback
。これにより、画面がロックされ、Ring/Silent スイッチがサイレントに設定されている場合でも、オーディオが再生されます。簡単にするために、このコードをAppDelegateに配置します。
- Obj-C
- スウィフト
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カテゴリオプション。
- Obj-C
- スウィフト
- (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!)")
}
}
再生レートの設定
再生速度を制御するには、rate
のプロパティAVPlayer
セッションで公開されたクラス。
デフォルトでは、再生レートは一定間隔(0.50、0.67、1.0、1.25、1.50、2.0)にのみ設定できます。AudioTimePitchAlgorithm を設定すると、より詳細なレート値(1.7 など)を使用できます。詳細については、この stackoverflow のディスカッションを参照してください。
avPlayerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;
の場合BCOVPlaybackSession
、コードは次のようになります。
- Obj-C
- スウィフト
- (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]));
AVPlayerItem *avPlayerItem = [session.player currentItem];
avPlayerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmVarispeed;
session.player.rate = 1.7;
}
}
func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) {
if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventReady) {
let seconds = CMTimeGetSeconds(session.player.currentTime())
print("kBCOVPlaybackSessionLifecycleEventReady at time \(seconds)")
let avPlayerItem = session.player.currentItem
avPlayerItem?.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithm.varispeed
session.player.rate = 1.7
}
}
360° 動画の VR ゴーグルモードの設定
360°ビデオを再生する場合、ユーザーはコントロールバーの [Video 360] ボタンを選択して VR ゴーグルモードに切り替えることができます。再生を開始する前に、これをプログラムで実行することもできます。あなたは更新することによってこれを行うことができますBCOVPlaybackController
プロトコルのviewProjection
次のようにプロパティ:
- Obj-C
- スウィフト
- (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
playbackController.viewProjection = viewProjection
}
}
背景色の変更
ポートレートモードでビデオを再生すると、プレーヤーの上下に黒い境界線が表示されることがあります。プレーヤービューは画面のサイズですが、ビデオはプレーヤービューの中央のごく一部を占めます。ビデオの周囲に表示される部分は、プレーヤーレイヤーの背景です。
AVPlayer
これは正常な動作です。動画はプレーヤーレイヤー内に収まるように縮小され、残りはプレーヤーレイヤーの背景になります。
プレイヤーレイヤーの背景は、次のコードで変更できます。
- Obj-C
- スウィフト
- (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
}
背景色を白に設定すると、次のようになります。