Brightcove fournit une prise en charge active du dernier SDK iOS sur la dernière version publique des versions iOS suivantes :
Brightcove fournit une prise en charge passive pour les versions iOS suivantes :
Le SDK Core est localisé en arabe (ar), anglais (en), français (fr), allemand (de), japonais (ja), coréen (ko), espagnol (es), chinois simplifié (zh-Hans) et traditionnel. Chinois (zh-Hant). Pour bénéficier d’une localisation, votre application doit également être localisée dans la même langue et dans les mêmes paramètres régionaux. Consultez la section Localisation personnalisée pour plus d’informations.
Tous les composants du SDK (les frameworks de base et de plugin) sont publiés avec le même numéro de version. Lors de la mise à niveau d'un seul composant, mettez à niveau tous les composants vers la même version.
Pour les projets utilisant Xcode 12 sur Apple Silicon M1 et Universal Frameworks (.framework), une erreur de construction est renvoyée lors de la création du projet pour le simulateur arm64.
*ld: building for iOS Simulator, but linking in dylib built for iOS, file for architecture arm64*
Pour créer un simulateur arm64, assurez-vous arm64
a été ajouté à votre paramètre de construction « Architectures exclues » pour Any iOS Simulator SDK
dans l'onglet « Paramètres de construction » de votre application cible.
La version 6.10.0 du SDK Brightcove Player ajoute des sous-spécifications pour le noyau et chaque plugin afin de prendre en charge XCFrameworks. La valeur par défaut de chaque sous-spécification est /XCFramework
.
Nom de la spécification de pod | Noms des sous-espèces |
---|---|
Brightcove-Player-Core | Brightcove-Player-Core/Framework Brightcove-Player-Core/XCFramework |
Brightcove-Player-DAI | Brightcove-Player-DAI/Framework Brightcove-Player-DAI/XCFramework |
Brightcove-Player-FreeWheel | Brightcove-Player-FreeWheel/Framework Brightcove-Player-FreeWheel/XCFramework |
Brightcove-Player-GoogleCast | Brightcove-Player-GoogleCast/Framework Brightcove-Player-GoogleCast/XCFramework |
Brightcove-Player-IMA | Brightcove-Player-IMA/Framework Brightcove-Player-IMA/XCFramework |
Brightcove-Player-Omniture | Brightcove-Player-Omniture/Framework Brightcove-Player-Omniture/XCFramework |
Brightcove-Player-Pulse | Brightcove-Player-Pulse/Framework Brightcove-Player-Pulse/XCFramework |
Brightcove-Player-SSAI | Brightcove-Player-SSAI/Framework Brightcove-Player-SSAI/XCFramework |
Brightcove-Player-OpenMeasurement | - |
La version 6.12.0 du SDK Brightcove Player met à jour les spécifications de podspecs Brightcove-Player-FreeWheel
et Brightcove-Player-Omniture
pour installer la version dynamique de BrightcovePlayerSDK
.
Nom de la spécification de pod | Type de cadre | Dépendance |
---|---|---|
Brightcove-Player-Core | dynamique | - |
Brightcove-Player-DAI (disponible depuis 6.12.7) | dynamique | Brightcove-Player-Core |
Brightcove-Player-FreeWheel | dynamique | Brightcove-Player-Core pour iOS, Brightcove-Player-Core pour tvOS |
Brightcove-Player-GoogleCast | statique | Brightcove-Player-Core |
Brightcove-Player-IMA | dynamique | Brightcove-Player-Core |
Brightcove-Player-Omniture | dynamique | Brightcove-Player-Core |
Brightcove-Player-Pulse | dynamique | Brightcove-Player-Core |
Brightcove-Player-SSAI | dynamique | Brightcove-Player-Core, Brightcove-Player-OpenMeasurement (uniquement pour la mesure ouverte) |
Brightcove-Player-OpenMeasurement (disponible depuis 6.10.0) | dynamique | - |
La prise en charge des vidéos protégées par FairPlay est intégrée au framework principal BrightcovePlayerSDK . Reportez-vous au guide FairPlay pour plus de détails sur l'utilisation de FairPlay avec le SDK Brightcove Native Player.
La prise en charge des sous-titres Sidecar est intégrée au framework principal BrightcovePlayerSDK . Pour plus de détails sur l'utilisation des sous-titres Sidecar avec le SDK Brightcove Native Player, reportez-vous au guide des sous-titres Sidecar.
Depuis la version 6.0.0, le SDK Brightcove Native Player vous permet de télécharger des vidéos HLS, y compris celles protégées par le cryptage FairPlay, pour les lire ultérieurement, que ce soit en ligne ou hors ligne. Reportez-vous au guide du développeur d'applications pour plus de détails :
Guide du développeur d'applications iOS pour le téléchargement de vidéos et la lecture hors ligne avec FairPlay
Le SDK Brightcove Player fournit des packages d'installation pour iOS et tvOS sous forme de bibliothèques dynamiques regroupées sous forme de Frameworks et XCFrameworks. Le déploiement est pris en charge sur iOS 12.0 et supérieur.
Vous pouvez utiliser CocoaPods pour ajouter le SDK Brightcove Player à votre projet. Vous pouvez trouver la dernière podspec Brightcove-Player-Core
ici. Le podspec prend en charge iOS et tvOS.
Lorsque vous utilisez Brightcove CocoaPods dans votre projet, ajoutez source 'https://github.com/brightcove/BrightcoveSpecs.git'
au début de votre Podfile.
nom.
source ' https://github.com/CocoaPods/Specs '
source ' https://github.com/brightcove/BrightcoveSpecs.git '
platform :ios, ' 12.0 '
use_frameworks !
target ' MyVideoPlayer ' do
pod ' Brightcove-Player-Core '
end
Le Framework peut être installé en ajoutant la sous-spécification /Framework
au pod.
source ' https://github.com/CocoaPods/Specs '
source ' https://github.com/brightcove/BrightcoveSpecs.git '
platform :ios, ' 12.0 '
use_frameworks !
target ' MyVideoPlayer ' do
pod ' Brightcove-Player-Core/Framework '
end
Lors de la mise à jour de votre installation, c'est une bonne idée d'actualiser la copie locale de votre référentiel BrightcoveSpecs afin que vous disposiez localement des dernières spécifications de pod, tout comme vous mettriez à jour votre référentiel principal CococaPods. Généralement, si vous exécutez pod update
dans le terminal, cela se produira automatiquement, ou bien vous pouvez mettre à jour explicitement avec pod repo update
.
Pour ajouter manuellement le SDK Brightcove Player à votre projet :
BrightcovePlayerSDK.framework
ou BrightcovePlayerSDK.xcframework
à votre projet. Assurez-vous d'utiliser la version correspondant à votre cible, iOS ou tvOS.BrightcovePlayerSDK.framework
/ BrightcovePlayerSDK.xcframework
bash ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/BrightcovePlayerSDK.framework/strip-frameworks.sh
. Cochez "Exécuter le script uniquement lors de l'installation". Cela supprimera les architectures inutiles de la version, ce qui est important pour la soumission à l'App Store. Cette étape n'est plus nécessaire lors de l'utilisation de XCFramework.bash ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/BrightcovePlayerSDK.framework/strip-frameworks.sh
. Cochez "Exécuter le script uniquement lors de l'installation". Cela supprimera les architectures inutiles de la version, ce qui est important pour la soumission à l'App Store.arm64
a été ajouté à votre paramètre de construction « Architectures exclues » pour Any iOS Simulator SDK
.À titre de référence, voici tous les composants du SDK et les URL correspondantes pour vous aider à localiser et télécharger les dernières versions :
Composant | URL |
---|---|
Brightcove-Player-Core | https://github.com/brightcove/brightcove-player-sdk-ios/tags |
Brightcove-Player-DAI | https://github.com/brightcove/brightcove-player-sdk-ios-dai/tags |
Brightcove-Player-FreeWheel | https://github.com/brightcove/brightcove-player-sdk-ios-fw/tags |
Brightcove-Player-GoogleCast | https://github.com/brightcove/brightcove-player-sdk-ios-googlecast/tags |
Brightcove-Player-IMA | https://github.com/brightcove/brightcove-player-sdk-ios-ima/tags |
Brightcove-Player-Omniture | https://github.com/brightcove/brightcove-player-sdk-ios-omniture/tags |
Brightcove-Player-Pulse | https://github.com/brightcove/brightcove-player-sdk-ios-pulse/tags |
Brightcove-Player-SSAI | https://github.com/brightcove/brightcove-player-sdk-ios-ssai/tags |
Pour ajouter le SDK Brightcove Player à votre projet avec Swift Package Manager :
https://github.com/brightcove/brightcove-player-sdk-ios.git
Remarque : seul le XCFramework dynamique est pris en charge pour Swift Package Manager.
Le SDK Brightcove Player pour iOS peut être importé en utilisant :
import BrightcovePlayerSDK;
Lecture de vidéo avec le SDK Brightcove Player pour iOS :
// ** Customize these values with your own account information **
let kAccountId = " ... "
let kPolicyKey = " ... "
let kVideoId = " ... "
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let playbackController = sdkManager . createPlaybackController ( )
self . playbackController = playbackController // store this to a strong property
view . addSubview ( playbackController . view )
let playbackService = BCOVPlaybackService ( withAccountId : kAccountId ,
policyKey : kPolicyKey )
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : kVideoId
]
playbackService . findVideo ( withConfiguration : configuration ,
queryParameters : nil ) { ( video : BCOVVideo ? ,
jsonResponse : Any ? ,
error : Error ? ) in
if let video {
self . playbackController ? . setVideos ( [ video ] )
self . playbackController ? . play ( )
}
}
Vous devez empêcher le contrôleur d'être automatiquement libéré à la fin de la méthode. Une manière courante de procéder consiste à stocker une référence au contrôleur dans une variable d'instance forte.
Depuis la version 5.1.0, Brightcove PlayerUI est entièrement intégré au framework Core SDK. PlayerUI fournit un ensemble complet de commandes pour la lecture et la publicité, dès la sortie de la boîte.
Le PlayerUI est rapide à configurer, affiche les contrôles publicitaires pour SSAI, Pulse et FreeWheel et peut être personnalisé en créant vos propres mises en page.
Suivez les instructions ci-dessous pour configurer les contrôles PlayerUI.
Créez une propriété dans votre UIViewController pour garder une trace de BCOVPUIPlayerView. Le BCOVPUIPlayerView contiendra à la fois la vue du contrôleur de lecture et la vue des contrôles.
// PlayerUI's Player View
var playerView : BCOVPUIPlayerView ?
Créez le BCOVPUIBasicControlView, puis le BCOVPUIPlayerView. C'est là que nous associons le contrôleur de lecture (et donc toutes les vidéos qu'il lit) aux commandes.
// Create and configure Control View.
let controlView = BCOVPUIBasicControlView . withVODLayout ( )
playerView = BCOVPUIPlayerView ( playbackController : self . playbackController , options : nil )
// Add BCOVPUIPlayerView to your video view.
if let playerView {
videoView . addSubview ( playerView )
}
Vous devrez configurer la mise en page pour la vue du joueur, vous pouvez le faire avec la mise en page automatique ou l'ancienne approche Springs & Struts.
Définissez la vue du lecteur pour qu'elle corresponde au conteneur vidéo de votre mise en page ( videoView
) lors de son redimensionnement.
playerView . frame = videoView . bounds
playerView . autoresizingMask = [ . flexibleHeight , . flexibleWidth ]
Définissez translatesAutoresizingMaskIntoConstraints
sur BCOVPUIPlayerView sur false
.
playerView . translatesAutoresizingMaskIntoConstraints = false
Ajoutez ensuite les contraintes pour la mise en page ; définir les ancres supérieure, droite, gauche et inférieure de votre BCOVPUIPlayerView pour qu'elles soient égales à celles de videoView
NSLayoutConstraint . activate ( [
playerView . topAnchor . constraint ( equalTo : videoView . topAnchor ) ,
playerView . rightAnchor . constraint ( equalTo : videoView . rightAnchor ) ,
playerView . bottomAnchor . constraint ( equalTo : videoView . bottomAnchor ) ,
playerView . leftAnchor . constraint ( equalTo : videoView . leftAnchor )
] )
La classe BCOVPUIPlayerViewOptions
vous permet de personnaliser certains comportements de BCOVPlayerUI lors de l'initialisation. Vous pouvez personnaliser les éléments suivants :
jumpBackInterval
Le temps en secondes pendant lequel le joueur recherchera en arrière lorsque le bouton de retour en arrière est enfoncé.
hideControlsInterval
Le temps en secondes après le dernier événement tactile, avant que les contrôles soient masqués.
hideControlsAnimationDuration
Le temps en secondes nécessaire pour que les contrôles s'animent et deviennent masqués.
showControlsAnimationDuration
Le temps en secondes nécessaire pour que les contrôles s'animent et deviennent visibles.
learnMoreButtonBrowserStyle
Paramètre qui détermine si le fait d'appuyer sur le bouton "En savoir plus" sur une annonce affichera le lien de clic dans un navigateur externe (paramètre par défaut) ou dans un navigateur interne.
presentingViewController
La sous-classe UIViewController à utiliser pour présenter d'autres contrôleurs de vue (comme le contrôleur de vue de sélection de sous-titres codés).
automaticControlTypeSelection
Indique si vous souhaitez ou non que BCOVPUIPlayerView
sélectionne automatiquement un type BCOVPUIBasicControlView
en fonction du type de média. Lorsque cette valeur est définie sur true
la propriété BCOVPUIBasicControlView
transmise à l'initialiseur BCOVPUIPlayerView
sera ignorée.
Flux vidéo + audio
basicControlViewWithVODLayout
basicControlViewWithLiveLayout
basicControlViewWithLiveDVRLayout
Flux audio uniquement
basicControlViewWithAODLayout
basicControlViewWithLiveAudioLayout
basicControlViewWithLiveDVRAudioLayout
REMARQUE : automaticControlTypeSelection
choisit les mises en page parmi celles fournies par BCOVPlayerUI, et ainsi, les contrôles et mises en page personnalisés seront écrasés ; automaticControlTypeSelection
et la personnalisation de l’interface utilisateur du lecteur sont incompatibles.
Les options peuvent être définies en utilisant la méthode suivante :
let manager = BCOVPlayerSDKManager . sharedManager ( )
let playbackController = manager . createPlaybackController ( )
let options = BCOVPUIPlayerViewOptions ( )
options . jumpBackInterval = 5
let playerView = BCOVPUIPlayerView ( playbackController : playbackController ,
options : options )
Trois mises en page sont fournies pour prendre en charge différents types de vidéo :
BCOVPUIControlLayout basicVODControlLayout
est une présentation de base pour les flux vidéo généraux à la demande.
BCOVPUIControlLayout basicLiveControlLayout
est une mise en page pour la vidéo en direct.
BCOVPUIControlLayout basicLiveDVRControlLayout
est une mise en page pour les flux vidéo en direct avec des commandes DVR.
Vous définissez généralement une nouvelle mise en page immédiatement après la création de votre BCOVPUIPlayerView
, mais vous pouvez également définir une nouvelle mise en page à tout moment. Par exemple, vous pouvez définir une nouvelle mise en page VOD comme celle-ci :
playerView ? . controlsView . layout = BCOVPUIControlLayout . basicVOD ( )
En plus des mises en page par défaut, vous pouvez créer vos propres mises en page hautement personnalisées en instanciant un nouveau BCOVPUIControlLayout
avec votre propre conception. Notez cependant que automaticControlTypeSelection
choisit les mises en page parmi celles fournies par BCOVPlayerUI et que les contrôles et mises en page personnalisés seront donc écrasés ; automaticControlTypeSelection
et la personnalisation de l’interface utilisateur du lecteur sont incompatibles.
Tout d’abord, créez les contrôles qui iront dans votre mise en page à l’aide de BCOVPUIBasicControlView layoutViewWithControlFromTag:width:elasticity:
. Chaque contrôle est regroupé dans un BCOVPUILayoutView
qui détermine l'espacement des contrôles.
Vous pouvez définir la width
de chaque affichage de mise en page sur la largeur par défaut (qui dépend du type de contrôle) ou vous pouvez spécifier votre propre largeur.
Utilisez l’argument elasticity
pour déterminer dans quelle mesure la vue de présentation contenant le contrôle adapte sa largeur pour remplir la barre de contrôle.
Voici des exemples de création d’une variété de contrôles de base.
// Create various standard layout views
// Standard play/pause button
let playbackLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . buttonPlayback ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
// Standard jump back button
let jumpBackButtonLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . buttonJumpBack ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
// Current time indicator
let currentTimeLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . labelCurrentTime ,
width : kBCOVPUILayoutUseDefaultValue
elasticity : 0.0 )
// Time separator - typically the '/' character
let timeSeparatorLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . labelTimeSeparator ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
// Video duration label
let durationLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . labelDuration ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
// Slider bar used for seeking through the video
// The elasticity is set to 1 so that it can resize to fill available space
let progressLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . sliderProgress ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 1.0 )
// Closed caption button
// This button is initially hidden ('removed'), and will be shown
// if closed captions or audio tracks are available.
let closedCaptionLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . buttonClosedCaption ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
closedCaptionLayoutView ? . isRemoved = true
// The full-screen button
let screenModeLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . buttonScreenMode ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
// AirPlay button
// This button is initially hidden ('removed'), and will be shown
// if AirPlay devices are available.
let externalRouteLayoutView = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . viewExternalRoute ,
width : kBCOVPUILayoutUseDefaultValue ,
elasticity : 0.0 )
externalRouteLayoutView ? . isRemoved = true
// Empty view - used as a spacer
let spacerLayoutView1 = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . viewEmpty ,
width : 1.0 ,
elasticity : 1.0 )
// Empty view - used as a spacer
let spacerLayoutView2 = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . viewEmpty ,
width : 1.0 ,
elasticity : 1.0 )
// Empty view - will have a custom UIImageView added as a subview
let logoLayoutView1 = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . viewEmpty ,
width : 88.0 ,
elasticity : 1.0 )
// Empty view - will have a custom UIImageView added as a subview
let logoLayoutView2 = BCOVPUIBasicControlView . layoutViewWithControl ( from : BCOVPUIViewTag . viewEmpty ,
width : 36.0 ,
elasticity : 1.0 )
Notez que vous pouvez également créer une vue de mise en page vide, dans laquelle vous pouvez placer votre propre vue (logo, contrôle, rien, etc.). Ce code montre comment placer un logo UIImage
dans le logoLayoutView1 que nous avons créé ci-dessus.
// Create logo image inside an image view for display in control bar.
let logoImage1 = UIImage ( named : " myLogo " )
let logoImageView1 = UIImageView ( image : logoImage1 )
logoImageView1 . autoresizingMask = [ . flexibleWidth , . flexibleHeight ]
logoImageView1 . contentMode = . scaleAspectFit
logoImageView1 . frame = logoLayoutView1 . frame
// Add image view to our empty layout view.
logoLayoutView1 . addSubview ( logoImageView1 )
Maintenant qu'il existe différents contrôles regroupés dans des vues de mise en page, ils sont classés dans des tableaux, dont chacun représente une seule ligne de contrôles, c'est-à-dire une barre de contrôle. Notez que vous pouvez avoir différentes dispositions pour les orientations portrait et paysage, vous configurerez donc généralement deux tableaux différents de barres de contrôle.
Dans la disposition standard pour l’orientation paysage, les contrôles sont disposés dans un seul tableau, puis ce tableau est stocké dans un autre tableau représentant l’ensemble des contrôles.
let standardLayoutLine1 = [
playbackLayoutView ,
jumpBackButtonLayoutView ,
currentTimeLayoutView ,
timeSeparatorLayoutView ,
durationLayoutView ,
progressLayoutView ,
spacerLayoutView1 ,
logoLayoutView1 ,
spacerLayoutView2 ,
closedCaptionLayoutView ,
screenModeLayoutView ,
externalRouteLayoutView
]
let standardLayoutLines = [ standardLayoutLine1 ]
Dans la disposition compacte pour l’orientation portrait, deux tableaux de contrôles sont créés, un pour chaque ligne. Ces tableaux sont regroupés dans un autre tableau représentant la disposition compacte.
Notez que exactement les mêmes objets sont utilisés pour la plupart des contrôles de chaque disposition. Lorsque cela est fait et que vous basculez entre les orientations portrait et paysage, l'objet sera déplacé vers sa nouvelle position à l'aide d'une animation fluide.
let compactLayoutLine1 = [
currentTimeLayoutView ,
progressLayoutView ,
durationLayoutView
]
let compactLayoutLine2 = [
playbackLayoutView ,
jumpBackButtonLayoutView ,
spacerLayoutView1 ,
closedCaptionLayoutView ,
screenModeLayoutView ,
externalRouteLayoutView ,
logoLayoutView2
]
let compactLayoutLines = [
compactLayoutLine1 ,
compactLayoutLine2
]
Enfin, maintenant qu'il existe deux configurations de mise en page (une pour la pleine largeur et une pour la largeur compacte), vous pouvez créer un nouvel objet BCOVPUIControlLayout
et le définir dans la vue de contrôle du lecteur.
let customLayout = BCOVPUIControlLayout . init ( standardControls : standardLayoutLines ,
compactControls : compactLayoutLines )
playerView ? . controlsView . layout = customLayout
Si vous avez des contrôles que vous devez afficher ou masquer fréquemment, vous pouvez définir la propriété removed
dans la vue Mise en page de ce contrôle. Lorsque vous avez modifié vos contrôles, appelez setNeedsLayout
sur le controlView de playerView :
logoLayoutView1 ? . isRemoved = true
playerView ? . controlsView . setNeedsLayout ( )
Vous pouvez également personnaliser plusieurs propriétés générales BCOVPUIControlLayout
:
controlBarHeight
définit la taille de chaque ligne de contrôles.horizontalItemSpacing
définit l'espacement entre chaque BCOVPUILayoutView
dans chaque barre de contrôle.compactLayoutMaximumWidth
détermine quel ensemble de contrôles est utilisé. Si la vue de contrôle est plus petite que compactLayoutMaximumWidth
, l’ensemble de contrôles compact sera utilisé, sinon les contrôles standard seront utilisés. Pour modifier l'ensemble des contrôles affichés, vous devez créer et installer un nouveau BCOVPUIControlLayout
. De nouveaux contrôles peuvent être installés à tout moment.
Pour plus d'exemples de personnalisation de PlayerUI, vous pouvez consulter l'exemple de code dans le dossier PlayerUI du référentiel BrightcoveOS GitHub :
https://github.com/BrightcoveOS/ios-player-samples
Le SDK Brightcove Native Player comprend des commandes intégrées pour la lecture dans tvOS sur Apple TV. Pour plus de détails sur l'utilisation de l'interface utilisateur intégrée du lecteur TV avec le SDK Brightcove Native Player, consultez notre guide du lecteur TV.
Activez la fonctionnalité AirPlay en définissant la propriété setAllowsExternalPlayback
sur votre BCOVPlaybackController
sur true
. Le bouton AirPlay sera affiché dans les commandes de lecture si des appareils AirPlay sont trouvés sur votre réseau.
Actuellement, IMA est le seul plugin publicitaire qui prend en charge AirPlay et uniquement lors de l'utilisation d'annonces pré-roll et/ou post-roll. L'utilisation d'AirPlay avec les plugins publicitaires Pulse, SSAI ou FreeWheel peut entraîner un comportement inattendu.
Si vous souhaitez également prendre en charge AirPlay 2 et permettre la sélection de plusieurs appareils pour la sortie audio, vous devrez effectuer quelques opérations supplémentaires. Tout d’abord, vous devrez configurer AVAudioSession afin de pouvoir définir le routeSharingPolicy
. Par exemple:
do {
try AVAudioSession . sharedInstance ( ) . setCategory ( . playback , mode : . moviePlayback , policy : . longFormVideo )
} catch {
print ( " Error setting AVAudioSession category " )
}
Vous devrez également configurer au moins une commande de lecture via MPRemoteCommandCenter
. À tout le moins, vous souhaiterez configurer à la fois pauseCommand
et playCommand
. Par exemple:
let center = MPRemoteCommandCenter . shared ( )
center . pauseCommand . addTarget { _ in
playbackController . pause ( )
return . success
}
center . playCommand . addTarget { _ in
playbackController . play ( )
return . success
}
Les appareils profiteront de AVRoutePickerView
qui dispose de deux méthodes déléguées. Ces méthodes déléguées sont transmises à BCOVPUIPlayerViewDelegate
. Les méthodes sont :
func routePickerViewDidEndPresentingRoutes ( _ routePickerView : AVRoutePickerView )
func routePickerViewWillBeginPresentingRoutes ( _ routePickerView : AVRoutePickerView )
L' AVRouteDetector
utilisé pour découvrir les routes AirPlay est disponible sur l'objet BCOVPUIBasicControlView
afin que vous puissiez activer ou désactiver sa propriété routeDetectionEnabled
selon vos besoins.
Selon la documentation d'Apple : " La détection d'itinéraire augmente considérablement la consommation d'énergie et doit être désactivée lorsqu'elle n'est plus nécessaire. "
playerView ? . controlsView . routeDetector . isRouteDetectionEnabled = false
Pour plus d'informations sur l'intégration d'AirPlay 2 dans votre application, veuillez consulter la documentation Obtenir Airplay 2 dans votre application.
Le SDK Native Player inclut la prise en charge de l’affichage interactif de vidéos sphériques à 360 degrés. Les vidéos à 360° doivent être taguées avec une propriété de champ « projection » contenant la valeur « équirectangulaire ». Ces vidéos seront chargées et lues de la même manière que les autres vidéos, mais elles seront affichées dans un CAMétalLayer au lieu d'un AVPlayerLayer.
Remarque : « équirectangulaire » est actuellement le seul format de projection pris en charge pour les vidéos sources à 360°.
PlayerUI prend également en charge Video 360, fournissant des gestes de panoramique par défaut, une détection de mouvement gyroscopique pour la vue et un nouveau bouton Video 360 qui apparaît lors de la lecture d'un élément Video 360. Ce bouton apparaît uniquement sur les iPhones et vous permet de basculer entre la vue normale et une vue "VR Goggles", où l'écran est divisé en deux, avec la même scène rendue pour chaque œil afin que l'appareil puisse être utilisé dans une vue frontale. configuration montée. Sur les iPad, aucun bouton Video 360 n'est nécessaire car il n'existe qu'un seul mode de fonctionnement : la détection de mouvement avec prise en charge des gestes panoramiques.
La prise en charge de Video 360 est aussi simple que la lecture d'une vidéo. Lorsque la propriété du champ « projection » est détectée, le SDK Native Player gérera automatiquement la configuration et l'affichage de la vidéo dans Metal, ainsi que l'installation du bouton Video 360 le cas échéant.
Si vous lisez des vidéos 360° en dehors de Video Cloud, veillez à ajouter une propriété « projection » à l'objet BCOVVideo
avec la valeur « équirectangulaire ».
Pour offrir la meilleure expérience utilisateur avec le mode VR Goggles, vous devez utiliser une méthode BCOVPUIPlayerViewDelegate
pour détecter quand ce mode est activé. Cela vous permet de forcer l'appareil en orientation paysage (puisque c'est la seule orientation qui a du sens pour une vue VR Goggles).
Le code suivant montre comment gérer un changement d'orientation forcé lors du basculement entre une vue normale à 360° et le mode VR Goggles.
// Set this to YES when displaying a VR goggles video
var landscapeOnly = false
// UIViewController override:
// Lets us control the orientation of the device
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
get {
if landscapeOnly {
return . landscape
}
return . all
}
}
// BCOVPUIPlayerViewDelegate method
func didSetVideo360NavigationMethod ( _ navigationMethod : BCOVPUIVideo360NavigationMethod ,
projectionStyle : BCOVVideo360ProjectionStyle ) {
switch projectionStyle {
case . normal :
print ( " BCOVVideo360ProjectionStyleNormal " )
landscapeOnly = false
case . vrGoggles :
print ( " BCOVPUIVideo360NavigationDeviceMotionTracking " )
landscapeOnly = true
let currentDeviceOrientation = UIDevice . current . orientation
switch currentDeviceOrientation {
case . landscapeLeft ,
. landscapeRight :
// all good
break
default :
// switch orientation
UIDevice . current . setValue ( UIInterfaceOrientation . landscapeLeft . rawValue , forKey : " orientation " )
break
}
break
default :
break
}
UIViewController . attemptRotationToDeviceOrientation ( )
}
Le PlayerUI installera des gestes pour gérer la navigation autour de la vidéo 360, mais si vous utilisez vos propres commandes, vous pouvez définir vous-même les paramètres d'affichage de la caméra virtuelle. La propriété viewProjection
du protocole BCOVPlaybackController
vous permet de définir ces paramètres. La propriété est une classe BCOVVideo360ViewProjection
avec des paramètres de base de caméra virtuelle tels que pan
, tilt
et zoom
. Pour modifier les paramètres, effectuez une copie de l'instance actuelle, modifiez les paramètres de la nouvelle instance, puis réattribuez-la à la propriété viewProjection
.
Le point d'entrée du SDK Brightcove Player pour iOS est l'objet singleton BCOVPlayerSDKManager
. Ce gestionnaire gère l'enregistrement des composants du plugin et certaines autres tâches de maintenance, mais il sert principalement de fabrique d'objets. Le contrôleur de vue de votre application obtient une référence au Manager et l'utilise pour créer un BCOVPlaybackController
. La propriété view
du contrôleur de lecture expose un UIView contenant l'objet AVPlayerLayer qui présente finalement votre contenu vidéo à l'écran. Le contrôleur de lecture accepte également un BCOVPlaybackControllerDelegate
, que vous pouvez implémenter pour répondre à divers événements de lecture vidéo.
Le contrôleur de lecture propose des méthodes et des propriétés pour affecter la lecture de la vidéo en cours. Cependant, en interne, le contrôleur de lecture délègue à un objet BCOVPlaybackSession
. Les sessions de lecture effectuent le travail réel de préparation et de lecture du contenu vidéo et contiennent les métadonnées de la vidéo et AVPlayer
. Le contrôleur de lecture dispose de mécanismes pour passer de la session de lecture en cours à la session de lecture suivante, soit automatiquement à la fin d'une vidéo, soit manuellement avec un appel de méthode. Une fois que le contrôleur de lecture a avancé vers une nouvelle session, la session précédente est supprimée et ne peut plus être utilisée.
Il existe deux autres éléments du contrôleur de lecture : un BCOVPlaybackSessionProvider
et une liste de BCOVPlaybackSessionConsumer
. Comme son nom l'indique, le fournisseur de session de lecture est responsable de la création des sessions de lecture et de leur transmission au contrôleur de lecture. Le contrôleur de lecture délivre ensuite la session à chacun des consommateurs de session de lecture dans la liste. Les API du fournisseur de session et du consommateur de session sont conçues pour être utilisées par les développeurs de plugins et ne sont pas détaillées dans ce document.
En plus de la fonctionnalité de lecture fournie par les classes décrites ci-dessus, il existe une poignée de classes de valeurs. Ceux-ci sont utilisés pour contenir des données spécifiques au SDK Player pour iOS. Chacun d’entre eux est décrit plus en détail dans sa propre section ci-dessous.
Le SDK Brightcove Player pour iOS fournit des méthodes de lecture, de pause et de recherche sur BCOVPlaybackController
. Il est important d'utiliser ces méthodes au lieu d'utiliser l'équivalent AVPlayer. Dans leurs implémentations par défaut, ces objets transmettent les appels directement à la méthode correspondante sur AVPlayer. Cependant, si vous utilisez des plugins, ils peuvent remplacer le comportement par défaut pour ajouter des fonctionnalités. Par exemple, si vous utilisez un plugin publicitaire, le premier appel de playbackController.play()
peut provoquer la lecture du pré-roll avant de démarrer le contenu. Pour en savoir plus sur la manière dont un plugin peut remplacer le comportement par défaut, veuillez vous référer au fichier README.md de chaque plugin ou en recherchant une extension de catégorie sur BCOVSessionProviderExtension
que le plugin peut ajouter.
L'appel direct de lecture, de pause ou de recherche sur AVPlayer peut provoquer un comportement indéfini.
Pour définir un taux de lecture personnalisé pour AVPlayer, vous pouvez utiliser la propriété playbackRate
sur BCOVPlaybackController
. Il est important que vous définissiez la vitesse de lecture à l'aide de cette propriété au lieu de la définir directement sur AVPlayer.
Si vous tentez de définir playbackRate
sur une valeur inférieure ou égale à 0, la valeur sera définie sur 1,0. Si currentItem
d'AVPlayer ne prend pas en charge canPlaySlowForward
(pour les valeurs inférieures à 1) ou canPlayFastForward
(pour les valeurs supérieures à 1), alors le taux de lecture par défaut de 1,0 sera utilisé. La lecture des publicités ne sera pas affectée.
Si une valeur personnalisée a été définie pour playbackRate
l' audioTimePitchAlgorithm
pour chaque AVPlayerItem
sera défini sur AVAudioTimePitchAlgorithmTimeDomain
. Vous pouvez également définir votre propre valeur pour audioTimePitchAlgorithm
comme ceci :
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didReceive lifecycleEvent : BCOVPlaybackSessionLifecycleEvent ) {
if lifecycleEvent . eventType == kBCOVPlaybackSessionLifecycleEventReady {
session . player . currentItem ? . audioTimePitchAlgorithm = . varispeed
}
}
Vous pouvez en savoir plus sur audioTimePitchAlgorithm
ici.
Depuis la version 6.12.0, le SDK iOS utilise AVQueuePlayer qui gère le préchargement de la vidéo suivante dans la file d'attente.
Cependant, vous souhaiterez peut-être avoir plus de contrôle sur le préchargement des vidéos à venir dans une liste de lecture. Une approche possible consiste à doubler une liste de vidéos en utilisant deux contrôleurs de lecture, par exemple :
playbackController1.setVideos([videos.firstObject])
)playbackController:didProgressTo:
du contrôleur de lecture, déterminez si la vidéo actuelle a suffisamment progressé jusqu'à l'endroit où vous souhaitez commencer à précharger la vidéo suivante.Pour un exemple fonctionnel, vous pouvez télécharger notre exemple d'application VideoPreloading à partir de notre référentiel Player Samples.
Remarque : Vous souhaiterez peut-être prendre en compte la quantité de mémoire disponible sur l'appareil du client et la vitesse de sa connexion. S'ils ne sont pas connectés au Wifi, le préchargement d'une vidéo peut affecter les ressources réseau de la vidéo actuelle.
Le SDK Brightcove Player pour iOS offre aux clients la possibilité d'associer plusieurs URL et types de diffusion ( BCOVSource
) à une seule vidéo ( BCOVVideo
). Par exemple, si vos vidéos sont récupérées par le service de lecture, il peut y avoir un mélange de rendus HLS ou MP4 pour une seule vidéo, ainsi que des versions HTTP et HTTPS. Laquelle de ces sources est sélectionnée est déterminée par un bloc de stratégie de sélection de source. La stratégie de sélection de source par défaut sélectionnera le premier HLS BCOVSource
sur chaque BCOVVideo
, les sources HTTPS étant préférées à HTTP.
La sélection de source peut être remplacée en créant un BCOVBasicSessionProviderOptions
et en l'utilisant pour créer un BCOVBasicSessionProvider
. Par exemple:
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let options = BCOVBasicSessionProviderOptions ( )
options . sourceSelectionPolicy = < policy >
let provider = sdkManager . createBasicSessionProvider ( withOptions : options )
let playbackController = sdkManager . createPlaybackController ( withSessionProvider : provider , viewStrategy : nil )
Si cette politique de sélection par défaut ne fonctionne pas pour vous, il existe quelques alternatives pour sélectionner une source :
Si vous récupérez des vidéos de Video Cloud via le service de lecture, avant d'appeler playbackController.setVideos()
, utilisez la méthode de mise à jour sur BCOVVideo
pour contenir uniquement la source souhaitée (voir la section « Valeurs » pour plus d'informations).
Vous pouvez utiliser la méthode d'assistance [BCOVBasicSourceSelectionPolicy sourceSelectionHLSWithScheme:scheme]
pour créer une stratégie qui préfère un schéma spécifique. Il s'agit de la méthode utilisée pour créer la stratégie de sélection de source par défaut qui préfère HTTPS.
Semblable à la mise à jour de l'objet vidéo, vous pouvez également implémenter votre propre bloc de sélection de source.
options . sourceSelectionPolicy = { ( video : BCOVVideo ? ) -> BCOVSource ? in
< Check video . sources for source >
< Return source >
}
Veuillez noter qu'il existe des limitations sur l'App Store concernant l'utilisation de vidéos MP4. Consultez les dernières informations sur les développeurs Apple pour plus de détails.
Le SDK Brightcove Player pour iOS permet de définir le débit binaire préféré pour une vidéo. Vous pouvez créer un objet BCOVPreferredBitrateConfig qui contient les options de débit binaire souhaitées, ainsi qu'une configuration pour le contrôleur de vue créé pour afficher les options.
Le titre du menu est facultatif. Les options de débit sont un tableau de NSDictionary, chaque dictionnaire ayant une paire clé:valeur. La clé sera utilisée comme nom d'option et la valeur est un NSNumber avec le débit binaire de cette option en bps (bits par seconde). Les débits que vous saisissez sont des valeurs qui peuvent être mappées aux débits des rendus de vos ressources vidéo. Vous pouvez en savoir plus sur les rendus dans les meilleures pratiques d’ingestion de profils.
Voici un exemple :
let bitrates = [
[ " Auto " : NSNumber ( 0 ) ] ,
[ " Setting 1 " : NSNumber ( 518100 ) ] ,
[ " Setting 2 " : NSNumber ( 2596000 ) ]
]
let options = BCOVPUIPlayerViewOptions ( )
options . preferredBitrateConfig = BCOVPreferredBitrateConfig ( menuTitle : " Select an Option " ,
andBitrateOptions : bitrates )
Lorsque l'utilisateur final sélectionne l'une des options, la propriété PreferPeakBitRate de l'AVPlayerItem actuel sera définie sur la valeur de l'option. Si la vidéo se trouve dans une liste de lecture, la prochaine vidéo lue aura également la valeur préféréePeakBitRate définie.
Après avoir défini une valeur non nulle pour PreferredPeakBitRate, vous ne remarquerez peut-être pas de différence de qualité jusqu'à ce qu'AVPlayer ait atteint la fin de son cache tampon actuel.
Vous pouvez également utiliser l'initialiseur configWithMenuTitle:bitrateOptions:andIndexofInitialSelection:
qui offre la possibilité de définir l'index de votre valeur initiale préférée. L'index doit être en corrélation avec l'index de l'option souhaitée dans le tableau bitrateOptions
.
Vous pouvez également utiliser la méthode setPreferredPeakBitRate:
sur votre objet BCOVPlaybackController
pour définir par programme le débit binaire préféré pour les sessions actuelles et futures.
REMARQUE : Les utilisateurs finaux doivent disposer d'un moyen de revenir à la valeur par défaut (0) de PreferredPeakBitRate. Vous pouvez le faire en fournissant une option avec une valeur de débit binaire de 0. Si vous ne fournissez pas d'option de débit binaire de 0, une option « Automatique » sera ajoutée à votre liste d'options pour l'utilisateur final.
Veuillez consulter la documentation d'Apple sur PreferredPeakBitRate pour plus d'informations.
Le SDK Brightcove Player pour iOS fournit deux mécanismes pour obtenir des informations de lecture. Le contrôleur de lecture fournit une propriété délégué qui implémente BCOVPlaybackControllerDelegate
. Un délégué peut implémenter ces méthodes facultatives pour être informé des métadonnées de lecture telles que la progression, les changements de durée et d'autres événements. Si un plugin publicitaire est installé, il peut également utiliser ce délégué pour fournir des informations sur la lecture des publicités. La méthode déléguée d’événement de cycle de vie fournit des événements pour signaler les changements dans l’état de lecture. Par exemple, lorsqu'un lecteur passe de l'état en pause à l'état de lecture, la méthode déléguée d'événement de cycle de vie sera appelée avec l'événement kBCOVPlaybackSessionLifecycleEventPlay
. Les événements du cycle de vie par défaut sont déclarés dans BCOVPlaybackSession
. Les plugins fournis par Brightcove ajoutent des événements de cycle de vie supplémentaires qui sont définis dans chaque plugin.
Le contrôleur de lecture autorise un seul délégué. Dans de nombreux cas, cela suffira pour récupérer des informations ; les implémentations déléguées peuvent diffuser des valeurs et des événements vers différentes parties de l'application si nécessaire. Dans les cas où plusieurs délégués seraient nécessaires, comme c'est le cas lors du développement d'un plugin, les délégués BCOVPlaybackSessionConsumer
fournissent des fonctionnalités équivalentes aux méthodes BCOVPlaybackControllerDelegate
, y compris les données publicitaires.
Voici un exemple de la façon dont on pourrait utiliser BCOVPlaybackSessionConsumer
pour créer un plugin d'analyse:
class XYZAnalytics : NSObject , BCOVPlaybackSessionConsumer {
func playbackSession ( _ session : BCOVPlaybackSession , didProgressTo progress : TimeInterval ) {
//react to progress event
}
}
Pour utiliser le plugin:
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let controller = sdkManager . createPlaybackController ( )
let analytics = XYZAnalytics ( )
controller . add ( analytics )
Lorsque l'application subit des interruptions de réseau, l' AVPlayer
utilisé par le BCOVPlaybackController
peut cesser d'essayer de récupérer si l'interruption dure trop longtemps. Si cela se produit, la méthode du délégué du cycle de vie sera appelée avec un événement kBCOVPlaybackSessionLifecycleEventFailedToPlayToEndTime
. Lorsque cet événement se produit, la lecture ne récupérera pas automatiquement. Afin de vous remettre de cet événement, vous devrez détecter quand le réseau se remet dans votre code client.
Une fois que vous avez déterminé que le réseau s'est rétabli, vous pouvez utiliser playbackController.resumeVideo(at:withAutoPlay:)
pour réinitialiser le lecteur. Vous devrez garder une trace de l'endroit où vous souhaitez reprendre. Le joueur fera de son meilleur effort pour supprimer les événements du cycle de vie et les événements de progression, afin d'empêcher les annonces de rejouer ou d'interférer des analyses.
En appelant playbackController.resumeVideo(at:withAutoPlay:)
, le joueur enverra un événement de cycle de vie de kBCOVPlaybackSessionLifecycleEventResumeBegin
. kBCOVPlaybackSessionLifecycleEventResumeComplete
sera envoyé si cette action réussit, sinon kBCOVPlaybackSessionLifecycleEventResumeFail
sera envoyé.
Vous devez attendre avant d'appeler playbackController.resumeVideo(at:withAutoPlay:)
Une deuxième fois jusqu'à ce que vous ayez reçu kBCOVPlaybackSessionLifecycleEventResumeComplete
ou kBCOVPlaybackSessionLifecycleEventResumeFail
de l'appel précédent. Vous voudrez peut-être imposer une limite de réessayer, avant de donner à l'utilisateur un message selon lequel leur réseau est trop instable.
Lorsque l' AVPlayer
est toujours en mesure d'accéder au réseau, mais que la vidéo cale car le réseau est trop lent, la méthode du délégué de cycle de vie sera appelée avec un événement kBCOVPlaybackSessionLifecycleEventPlaybackStalled
. Lorsque la lecture est capable de reprendre, la méthode du délégué du cycle de vie sera appelée avec un événement kBCOVPlaybackSessionLifecycleEventPlaybackRecovered
. Ces événements ne couvrent que le cas où la lecture normale s'est arrêtée et ne couvre pas la mise en mémoire tampon qui se produit lors d'une recherche ou d'une charge initiale de la vidéo.
Lorsque la vidéo est initialement chargée, lorsqu'une recherche se produit, ou lorsque la lecture des stands due à un réseau lent, la méthode du délégué du cycle de vie sera appelée avec un événement kBCOVPlaybackSessionLifecycleEventPlaybackBufferEmpty
. Lorsque la lecture est capable de reprendre, la méthode du délégué du cycle de vie sera appelée avec un événement kBCOVPlaybackSessionLifecycleEventPlaybackLikelyToKeepUp
.
Sauf lorsqu'il est explicitement documenté autrement, aucune des classes du SDK Player pour iOS n'est conçue pour être sous-classée. La création d'une sous-classe de toute classe SDK qui n'est pas explicitement conçue pour être sous-classée, en particulier l'une des classes de valeur, pourrait entraîner un comportement imprévisible.
Également connues sous le nom de "Modèles d'objets", ces classes ( BCOVPlaylist
, BCOVVideo
, BCOVSource
, BCOVCuePoint
, BCOVCuePointCollection
) sont utilisées pour représenter les données du SDK du joueur pour iOS. Il est crucial de comprendre que ces types de données sont traités comme des valeurs plutôt que comme des identités . Par cela, nous voulons dire que si vous avez deux instances d'une classe de valeur qui ont exactement les mêmes données, elles représentent la même idée ou la même valeur, même s'ils sont techniquement deux objets différents à des adresses de mémoire distinctes. En d'autres termes, ni le code SDK ni votre code client ne devraient jamais utiliser de comparaisons d'identité ("l'égalité du pointeur") avec des objets de valeur. Au lieu de cela, chaque classe de valeur implémente -isEqual:
et fournit une surcharge de méthode d'égalité spécifique à la classe, qui doit être utilisée à la place.
C'est mauvais:
if myVideo == session . video // Could lead to bugs!
Ce sont bons (et fonctionnellement équivalents):
if myVideo . isEqual ( session . video )
if myVideo . isEqual ( toVideo : session . video )
Les internes du SDK du joueur pour iOS peuvent faire des choses telles que les valeurs de mémoire ou faire des copies défensives, donc s'appuyer sur l'adresse du pointeur pour vérifier l'égalité finira par vous causer de la douleur.
Une autre qualité de classes de valeur dans le SDK du joueur pour iOS est qu'ils sont immuables . Une fois que vous avez une instance de valeur, vous ne devez pas essayer de renverser cette immuabilité de quelque manière que ce soit, car cela peut conduire à un comportement imprévisible. Si dans votre code, vous souhaitez "modifier" une valeur d'une certaine manière, votre seul recours est de créer une nouvelle valeur. En tant que commodité pour aider les clients à obtenir des valeurs "modifiées", chacune des classes de valeur propose une -update:
qui prend un bloc qui vous permet de fonctionner sur une copie mutable de la valeur d'origine.
Voici un exemple d'utilisation de cette méthode pour créer une version "modifiée" d'un objet vidéo existant, mais avec différentes propriétés:
let video1 : BCOVVideo // (properties include a key "foo" whose value is "bar")
let video2 = video1 . update { ( mutableVideo : BCOVMutableVideo ) in
mutableVideo . properties = [ " foo " : " quux " ]
}
if let foo1 = video1 . properties [ " foo " ] ,
let foo2 = video2 . properties [ " foo " ] {
print ( " foo is ( foo1 ) " ) // prints "foo is bar"
print ( " foo is ( foo2 ) " ) // prints "foo is quux"
}
// Both video1 and video2 are still immutable objects:
video1 . properties = [ " foo " : " fail " ] // causes compiler error
video2 . properties = [ " foo " : " fail " ] // causes compiler error
Comme vous pouvez le voir dans l'exemple, video1
n'a pas été modifiée par l'appel de méthode -update
. Au lieu de cela, cette méthode renvoie une copie de video1
, sauf avec les modifications apportées dans le corps du bloc. Vous ne devez jamais autoriser la copie mutable pour échapper au bloc (par exemple en l'attribuant à une variable __block
), utilisez plutôt l'objet immuable renvoyé par la méthode -update
après avoir apporté vos modifications.
La classe de service de lecture, BCOVPlaybackService
, offre des fonctionnalités pour récupérer vos actifs vidéo et listes de lecture Brightcove via l'API de lecture Brightcove, y compris des métadonnées riches telles que des pistes de texte, des aperçus et des vignettes. L'exemple suivant montre comment récupérer une vidéo avec un ID vidéo. Des méthodes pour récupérer une vidéo ou une liste de lecture avec l'ID de référence de cette vidéo sont également disponibles.
[ 1 ] let kPolicyKey = " ... "
let kAccountId = " ... "
let kVideoId = " ... "
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let playbackController = sdkManager . createPlaybackController ( )
self . playbackController = playbackController
view . addSubview ( playbackController . view )
let playbackService = BCOVPlaybackService ( withAccountId : kAccountId ,
policyKey : kPolicyKey )
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : kVideoId
]
playbackService . findVideo ( withConfiguration : configuration ,
queryParameters : nil ) { ( video : BCOVVideo ? ,
jsonResponse : Any ? ,
error : Error ? ) in
if let video {
self . playbackController ? . setVideos ( [ video ] )
self . playbackController ? . play ( )
}
}
Remarque: Si vous utilisez le service d'autorisation de lecture, veuillez consulter la section de cette lecture liée à cette fonctionnalité.
Pour les méthodes BCOVPlaybackService
qui renvoient une liste de lecture, vous pouvez demander une liste de lecture partielle, ou "pages" de la liste de lecture en spécifiant un paramètre limite et décalage dans le dictionnaire Paramètres. La limite spécifie le nombre maximum de vidéos qui seront renvoyées et le décalage spécifie l'index dans la playlist où les vidéos seront renvoyées.
Par exemple, si vous avez une liste de lecture avec 100 vidéos, vous ne pouvez demander que 6 vidéos à partir de la vidéo numéro 10 comme suit:
let parameters = [
" limit " : 6 ,
" offset " : 10
]
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : kVideoId
]
playbackService . findVideo ( withConfiguration : configuration ,
queryParameters : parameters ) { ( video : BCOVVideo ? ,
jsonResponse : Any ? ,
error : Error ? ) in
if let video {
self . playbackController ? . setVideos ( [ video ] )
self . playbackController ? . play ( )
}
}
L'objet BCOVPlaybackController
est construit avec une stratégie de vue, qui vous permet, en tant que client du SDK, de définir l'objet UIView exact qui est renvoyé de la propriété de vue du contrôleur de lecture. Ceci est important lors de l'utilisation de plugins qui affectent la vue du contrôleur de lecture, comme un plugin publicitaire qui superpose la vue vidéo avec une vue d'annonce. De nombreuses applications n'auront pas besoin de créer une stratégie de vue et peuvent simplement passer nil
lors de la création d'un nouveau contrôleur de lecture. Cela créera une vue vidéo standard dans le contrôleur de lecture.
BCOVPlaybackControllerViewStrategy
types (et documents) Cette signature de bloc plus complexe:
UIView *(^)(UIView *videoView, id playbackController);
Cette signature décrit un bloc d'objectif-C qui renvoie un UIView et prend deux paramètres: un UIView et un contrôleur de lecture. La valeur de retour est l'objet UIView que la propriété de vue du contrôleur de lecture pointera. Le premier paramètre est un uiView qui contient le calque vidéo, l'UiView affichera la vidéo. Le deuxième paramètre est l'objet de contrôleur de lecture dans lequel la stratégie de vue a été donnée, le contrôleur de lecture peut être utilisé pour ajouter les consommateurs de session nécessaires tels que les commandes vidéo ou les contrôles d'annonces.
Exemple de mise en œuvre de la stratégie:
let viewStrategy = { ( videoView : UIView ? , playbackController : BCOVPlaybackController ? ) in
guard let videoView ,
let playbackController else {
return UIView ( )
}
// Create some custom controls for the video view,
// and compose both into a container view.
[ 1 ] let myControlsView = MyControlsView ( ) // Conforms to BCOVPlaybackSessionConsumer
[ 2 ] let controlsAndVideoView = UIView ( )
[ 3 ] controlsAndVideoView . addSubview ( videoView )
controlsAndVideoView . addSubview ( myControlsView )
// Compose the container with an advertising view
// into another container view.
[ 4 ] let adView = SomeAdPluginView ( ) // Conforms to BCOVPlaybackSessionConsumer
[ 5 ] let adAndVideoView = UIView ( )
[ 6 ] adAndVideoView . addSubview ( controlsAndVideoView )
adAndVideoView . addSubview ( adView )
[ 7 ] playbackController . add ( myControlsView )
playbackController . add ( adView )
// This container view will become `playbackController.view`.
return adAndVideoView
}
Décomposer le code en étapes: [1] Créez une vue de contrôle personnalisée conforme au protocole BCOVPlaybackSessionConsumer
. Le protocole BCOVPlaybackSessionConsumer
permet de recevoir des informations de lecture de base pour chaque vidéo en plus de la publicité. [2] Créez une vue de conteneur pour la vue vidéo et les contrôles personnalisés. [3] Ajouter sous forme de sous-vue le conteneur vidéo et les contrôles personnalisés. La hiérarchie est composée dans le même ordre que des vues sont ajoutées. [4] Créez une vue de contrôles d'annonces conforme au protocole BCOVPlaybackSessionConsumer
. [5] Créez une vue de conteneur pour la vue et les contrôles vidéo, et la vue publicitaire. [6] Ajouter comme sous-vue le conteneur vidéo et la vue de contrôle AD. [7] Enregistrez la vue des contrôles personnalisés et la vue des contrôles AD en tant que consommateurs de session à l'aide de l'objet de contrôleur de lecture renvoyé par le bloc.
Il y a une mise en garde à utiliser une stratégie de vue: vous ne devez pas accéder à la propriété view
du contrôleur de lecture à partir du bloc de stratégie de vue. Étant donné que le bloc est appelé parce que la propriété view
du contrôleur de lecture a été accessible pour la première fois, l'accès à la propriété view
à nouveau dans le bloc de stratégie de vue provoquera un plan de votre programme.
Par défaut, lorsqu'une application iOS est envoyée à l'arrière-plan ou que l'appareil est verrouillé, iOS en suspension toute vidéo en lecture. Pour modifier ce comportement, définissez la propriété allowsBackgroundAudioPlayback
de l'objet BCOVPlaybackController
sur true
. (La valeur par défaut est false
, indiquant que la lecture s'arrêtera en arrière-plan.)
Vous devez également suivre les lignes directrices définies par Apple dans des questions et réponses techniques Q&R1668 pour définir les modes d'arrière-plan et la catégorie de session audio appropriés pour votre application.
Il est important que l' AVPlayerLayer
soit détaché de l' AVPlayer
avant que l'application ne soit basée à l'arrière-plan (et reattait lorsque l'application revient au premier plan). Le SDK de BrightCove Player gère cela pour vous lorsque allowsBackgroundAudioPlayback
est défini sur true
.
Enfin, lors de la lecture de vidéos d'arrière-plan (et en particulier lorsque vous utilisez des listes de lecture), vous devez utiliser l'API iOS MPRemoteCommandCenter
pour donner le contrôle de la lecture de l'utilisateur sur l'écran de verrouillage et dans le centre de contrôle.
Pour activer l'image dans votre application, définissez la propriété showPictureInPictureButton
de l'objet BCOVPUIPlayerViewOptions
sur true
lors de l'instanciation de votre objet BCOVPUIPlayerView
. Le bouton Image-in-Ianting sera ensuite affiché dans la barre de commandes sur n'importe quel appareil qui le prend en charge.
Pour que l'image dans la valeur fonctionne correctement, vous devrez vous assurer que l' Audio, AirPlay, and Picture in Picture
sont tournés dans la section des Background Modes
de l'onglet Capacités cibles de votre projet. Vous devez également suivre les lignes directrices définies par Apple dans des questions et réponses techniques Q&R1668 pour définir les modes d'arrière-plan et la catégorie de session audio appropriés pour votre application.
Les méthodes AVPictureInPictureControllerDelegate
sont transmises via BCOVPUIPlayerViewDelegate
. Ces méthodes sont:
func pictureInPictureControllerDidStartPicture ( inPicture pictureInPictureController : AVPictureInPictureController )
func pictureInPictureControllerDidStopPicture ( inPicture pictureInPictureController : AVPictureInPictureController )
func pictureInPictureControllerWillStartPicture ( inPicture pictureInPictureController : AVPictureInPictureController )
func pictureInPictureControllerWillStopPicture ( inPicture pictureInPictureController : AVPictureInPictureController )
func picture ( _ pictureInPictureController : AVPictureInPictureController , failedToStartPictureInPictureWithError error : Error )
func picture ( _ pictureInPictureController : AVPictureInPictureController , restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler : ( Bool ) -> Void )
Voir AvPictureInpiCtureControllerDelegate Documentation pour plus d'informations.
Pour mettre en œuvre votre propre comportement d'image dans la situation, laissez la propriété allowsBackgroundAudioPlayback
de BCOVPlaybackController
définie sur false
et conservez la propriété pictureInPictureActive
de BCOVPlaybackController
mise à jour avec le statut d'image. Si vous utilisez le AVPictureInPictureController
, vous pouvez utiliser le pictureInPictureControllerDidStartPicture(inPicture:)
et pictureInPictureControllerDidStopPicture(inPicture:)
Déléguer les méthodes pour mettre à jour cette propriété.
Vous pouvez en savoir plus sur la mise en œuvre de l'image dans l'image dans l'image d'adoption d'Apple dans l'image dans une documentation de joueur personnalisée.
L'utilisation d'une playlist de vidéos avec des formats mixtes avec une image dans la situation entraînera la fermeture de la fenêtre d'image dans chaque vidéo.
iOS et iPados 14 ont introduit un comportement automatique d'image dans l'image qui peut être activé / désactivé dans Settings > General > Picture in Picture
. Pour que cette fonction fonctionne comme prévu, la vue du joueur doit être égale à la largeur de l'écran et la hauteur doit avoir un rapport d'au moins 0,57 à la largeur (16: 9 ou plus). Si la largeur ou la hauteur de la vue de votre joueur est plus petite que ces valeurs, l'image dans l'image peut ne pas être automatiquement déclenchée lorsque l'application entre en arrière-plan.
IMPORTANT: Les plugins IMA, Freewheel, Pulse et SSAI chèrent chacun différemment les fonctionnalités d'image dans l'image. Passez en revue la section Image-in-Ipture dans chaque Plugin Readme pour plus d'informations.
La recherche de vignettes permet aux utilisateurs de faire glisser la tête de jeu le long de la chronologie et de considérer les vignettes comme un aperçu du contenu associé. Cela donne aux utilisateurs la possibilité de naviguer rapidement dans un fichier vidéo et de trouver le contenu qui les intéresse.
Cette fonctionnalité est également appelée Apple comme un jeu de trucs et est référencée dans leur spécification de création HLS.
Cette fonction est activée par défaut. Si vous souhaitez désactiver la recherche de vignettes, vous pouvez le faire en définissant la propriété thumbnailSeekingEnabled
sur votre BCOVPlaybackController
sur false
.
playbackController . thumbnailSeekingEnabled = false
Vous pouvez personnaliser la mise en page de l'aperçu miniature en utilisant une méthode de délégué avec votre BCOVPUIPlayerView
ou BCOVTVPlayerView
.
Sur iOS, vous pouvez ajuster la hauteur, la largeur et le décalage vertical:
func setUpPlayerView ( ) {
let playerView = BCOVPUIPlayerView ( playbackController : nil )
playerView ? . delegate = self
...
}
// MARK: BCOVPUIPlayerViewDelegate
func playerViewShouldDisplayThumbnailPreview ( withRect playerView : BCOVPUIPlayerView ) -> CGRect {
let width : CGFloat = 100
let height : CGFloat = 56
let verticalOffset : CGFloat = - 60
var modifier : CGFloat = 1
if UIDevice . current . userInterfaceIdiom == . pad {
modifier = 2
}
return CGRect ( x : 0 , y : verticalOffset * modifier , width : width * modifier , height : height * modifier )
}
Sur TVOS, vous pouvez ajuster la hauteur et la largeur:
func setUpPlayerView ( ) {
let playerView = BCOVTVPlayerView ( options : nil )
playerView ? . delegate = self
...
}
// MARK: BCOVTVPlayerViewDelegate
func playerViewShouldDisplayThumbnailPreview ( withSize playerView : BCOVTVPlayerView ) -> CGSize {
var size = self . view . frame . size
size . width = size . width / 6
size . height = size . height / 6
return size
}
Si vous construisez manuellement un objet BCOVVideo
vous pouvez définir l'URL à utiliser pour la source WebVTT Source:
if let url = URL ( string : " https://mydomain.com/master.m3u8 " ) {
var video = BCOVVideo . video ( withURL : url )
video = video . update ( { ( mutableVideo : BCOVMutableVideo ) in
mutableVideo . thumbnailVTTURL = URL ( string : " https://mydomain.com/thumbnail.webvtt " )
} )
}
La recherche de vignettes n'est disponible que pour les vidéos en ligne; Les vidéos téléchargées / hors ligne ne prennent pas en charge cette fonctionnalité.
Vous pouvez insérer un Bcovvideo supplémentaire, après un autre Bcovvideo déjà dans la file d'attente, dans votre BCOVPlaybackController
en appelant insertVideo:afterVideoAtIndex:
.
Par exemple:
// This will insert the new video after the first video in the queue
playbackController . insert ( videoToInsert , afterVideoAt : 0 )
Il existe deux méthodes de délégué que vous pouvez utiliser pour être alertées du succès ou de l'échec de la demande.
func playbackController(_ controller: BCOVPlaybackController, didInsert video: BCOVVideo, at index: UInt)
func playbackController(_ controller: BCOVPlaybackController, failedToInsert video: BCOVVideo)
La concurrence générique du flux (GSC) est un service qui détermine si la lecture est autorisée en fonction des sessions de lecture actives pour le spectateur et une limite de concurrence prédéfinie. Le service est demandé via le service d'autorisation de lecture Edge (EPA). Le même JWT utilisé pour récupérer la vidéo est utilisé ici et devrait inclure une réclamation uid
, une réclamation climit
et éventuellement, une réclamation sid
. Cette fonctionnalité doit être activée dans votre Account.
La concurrence générique du flux n'est pas activée dans le SDK par défaut. Si vous souhaitez l'activer, définissez la propriété streamConcurrencyEnabled
de votre BCOVPlaybackController
sur true
.
playbackController . streamConcurrencyEnabled = true
La valeur sid
peut être incluse dans le JWT ou envoyée comme une option BCOVPlaybackController
, toutes deux facultatives. La valeur sid
dans le JWT a la priorité sur l'option BCOVPlaybackController
.
playbackController . options [ kBCOVAuthHeartbeatPropertyKeySessionId ] = " sessionId "
Une nouvelle méthode de délégué a été ajoutée à BCOVPlaybackControllerDelegate
pour récupérer les sessions actives lorsque la limite de concurrence a été atteinte.
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didReachMaxConcurrency sessions : [ AnyHashable : Any ] ) {
print ( " ( sessions ) " )
}
Les erreurs de lecture sont généralement gérées et rapportées via des événements de lecture vidéo du contrôleur de lecture. Si vous avez besoin de creuser plus profondément et de suivre les problèmes avec des vidéos ou des séances d'applications particulières, vous pouvez profiter de l' ID de session du SDK BrightCove Player. L'ID de session est une propriété du BCOVPlayerSDKManager
que vous pouvez récupérer comme ceci:
let sdkSessionID = BCOVPlayerSDKManager . sharedManager ( ) . sessionID
L'ID de session est une chaîne unique qui ne change pas pendant le cycle de vie de l'application. Cette chaîne est rapportée avec diverses autres données d'analyse aux serveurs de métriques Brightcove. Si vous rencontrez des problèmes avec une instance d'application ou une vidéo particulière, vous pouvez enregistrer l'ID de session et le renvoyer à vos propres serveurs d'entreprise. Ensuite, vous pouvez envoyer l'ID de session, l'ID vidéo et toutes les autres données pertinentes aux ingénieurs de service Brightcove pour aider à diagnostiquer tous les problèmes.
Si vous devez combiner les plugins SDK Player, par exemple pour ajouter des sous-titres à une vidéo Protected DRM qui lit les annonces gérées par Google IMA, BCOVSessionProviders
de chaque plugin est créé et enchaîné et que la chaîne est utilisée pour construire le BCOVPlaybackController
.
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let imaSettings = IMASettings ( )
imaSettings . ppid = kIMAPublisherID
if let languageCode = NSLocale . current . languageCode {
imaSettings . language = languageCode
}
let renderSettings = IMAAdsRenderingSettings ( )
renderSettings . linkOpenerPresentingController = self
let adsRequestPolicy = BCOVIMAAdsRequestPolicy . videoPropertiesVMAPAdTagUrl ( )
// create the sidecar subtitles session provider. it has no upstream session provider.
let sidecarSessionProvider = sdkManager . createSidecarSubtitlesSessionProvider ( withUpstreamSessionProvider : nil )
// create a fairplay session provider with the sidecar session provider as its upstream session
let authProxy = BCOVFPSBrightcoveAuthProxy ( withPublisherId : nil ,
applicationId : nil )
let fairPlaySessionProvider = sdkManager . createFairPlaySessionProvider ( withAuthorizationProxy : authProxy ,
upstreamSessionProvider : sidecarSessionProvider )
// create the IMA session provider with an upstream sidecar subtitles session provider.
let imaSessionProvider = sdkManager . createIMASessionProvider ( with : imaSettings ,
adsRenderingSettings : renderSettings ,
adsRequestPolicy : adsRequestPolicy ,
adContainer : playerView ? . contentOverlayView ,
viewController : self ,
companionSlots : nil ,
upstreamSessionProvider : fairPlaySessionProvider )
Les développeurs ont un contrôle sur la taille du tampon de lecture vers l'avant utilisé par l' AVPlayer
. Ceci se fait en définissant la propriété preferredForwardBufferDuration
dans la classe AVPlayerItem
.
Par défaut, le SDK de Brightcove Native Player définit la propriété preferredForwardBufferDuration
de la bande passante globale sans sacrifier la qualité de lecture. Ce comportement peut être remplacé par vos propres valeurs.
Tout le monde paie la bande passante, il est donc important de réduire la consommation de bande passante sans affecter la qualité de la lecture. Nouveau avec la version 5.2.0, le SDK de Brightcove Native Player gère la taille du tampon pour vous dynamiquement pendant que la vidéo joue.
Avant iOS 10, l' AVPlayer
a tamponné autant de données vidéo qu'elle le pouvait, jusqu'à environ 50 mégaoctets. C'est bien pour le modèle de visualisation vidéo où un utilisateur sélectionne une vidéo, puis le regarde jusqu'à la fin, mais de nombreuses applications modernes "taquinent" des vidéos avec la lecture automatique, espérant sécuriser l'engagement après quelques secondes. De nombreux utilisateurs passent simplement à différentes vidéos. Avec une mise en mémoire tampon agressive, vous pouvez vous retrouver avec plusieurs minutes de vidéo tamponnée qui sont jetées à chaque impression vidéo.
Le SDK de Brightcove Native Player aborde ce problème en commençant la vidéo avec un petit tampon de base, puis en l'augmentant lorsque l'utilisateur regarde davantage la vidéo. Après un certain point, la taille du tampon est plafonnée car il n'est pas pratique ou utile de le rendre trop grand.
Si vous souhaitez conserver le comportement par défaut du SDK du joueur natif de Brightcove, mais modifiez les valeurs minimales et maximales utilisées pour les tailles de tampon, vous pouvez effectuer ce qui suit lors de la configuration du BCOVPlaybackController
:
// Create mutable dictionary to hold new values
if var options = playbackController . options {
// Set new values in dictionary
options [ kBCOVBufferOptimizerMethodKey ] = BCOVBufferOptimizerMethod . default . rawValue
options [ kBCOVBufferOptimizerMinimumDurationKey ] = minValue
options [ kBCOVBufferOptimizerMaximumDurationKey ] = maxValue
// Set new dictionary in your playback controller
playbackController . options = options
}
Ces options doivent être définies avant d'appeler playbackController.setVideos()
.
Valeurs min
et max
:
AVPlayer
peut tamponner des données qui ne sont jamais visualisées.AVPlayerItem
qui indique à l' AVPlayer
de déterminer sa propre taille de tampon.Si vous ne voulez pas d'optimisation de tampon active dans votre session de lecture actuelle, vous pouvez utiliser la même technique, mais définir la méthode Optimziation sur "Aucun" comme suit:
// Create mutable dictionary to hold new values
if var options = playbackController . options {
// Set new values in dictionary
options [ kBCOVBufferOptimizerMethodKey ] = BCOVBufferOptimizerMethod . none
// Set new dictionary in your playback controller
playbackController . options = options
}
Avec la méthode définie sur .none
, iOS maintiendra le contrôle total de la taille du tampon avant.
Si vous souhaitez définir votre propre taille tampon pour la lecture, désactivez d'abord l'optimisation du tampon comme décrit dans la section précédente. Ensuite, vous pouvez implémenter la méthode du délégué BCOVPlaybackController
suivant:
func playbackController ( _ controller : BCOVPlaybackController , didAdvanceTo session : BCOVPlaybackSession ) {
if let currentItem = session . player . currentItem {
// Set your preferredForwardBufferDuration value here.
currentItem . preferredForwardBufferDuration = newPreferredForwardBufferDurationValue
}
}
Si vous souhaitez modifier dynamiquement la taille du tampon au fil du temps, vous pouvez définir session.player.currentItem.preferredForwardBufferDuration
dans la méthode du délégué de progrès du BCOVPlaybackController
de la même manière:
func playbackController ( _ controller : BCOVPlaybackController , playbackSession session : BCOVPlaybackSession , didProgressTo progress : TimeInterval ) {
if let currentItem = session . player . currentItem {
// Set your preferredForwardBufferDuration value here.
currentItem . preferredForwardBufferDuration = newPreferredForwardBufferDurationValue
}
}
Remarque: Apple met spécifiquement "préféré" dans preferredForwardBufferDuration
car vous pouvez définir n'importe quelle valeur que vous souhaitez, mais d'une manière générale, le lecteur AVPlayer
ne l'utilisera que comme guide. Gardez également à l'esprit que le réglage sur zéro renvoie le contrôle total de la taille du tampon à l' AVPlayer
.
Vous pouvez utiliser AVPlayerviewController au lieu de l'AVPlayerLayer utilisé par la classe BCOVPlayBackSession. L'utilisation du AVPlayerviewController permet au lecteur d'utiliser les contrôles natifs iOS et TVOS Player, mais il y a des limites à cette approche (voir ci-dessous).
Pour utiliser le AVPlayerviewController, vous pouvez définir une propriété BCOVPlayBackController Dictionary appelée kBCOVAVPlayerViewControllerCompatibilityKey
:
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let playbackController = sdkManager . createPlaybackController ( )
if var mutableOptions = playbackController . options {
// To use the AVPlayerViewController
mutableOptions [ kBCOVAVPlayerViewControllerCompatibilityKey ] = true
// To use the BCOVPlaybackSession's AVPlayerLayer
// mutableOptions[kBCOVAVPlayerViewControllerCompatibilityKey] = false
playbackController . options = mutableOptions
}
La valeur par défaut de KBCovAvPlayerviewControllerCathibilibleKey est false
, ce qui signifie qu'un BCOVPlayBackContrller créé sans cette propriété de dictionnaire explicitement définie utilisera par défaut le BCOVPlayBackSession AVPlayerlayer.
Les plugins Brightcove IMA, Freewheel, Pulse et SSAI sont compatibles lors de l'utilisation d'AVPlayerviewController. Vous pouvez utiliser le contentOverlayView
de l'AVPlateViewController pour la vue dans laquelle afficher les annonces (non applicable à SSAI).
Vous souhaiterez peut-être masquer / afficher les contrôles de lecture d'AvPlayerviewController avant et après les publicités:
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didEnter adSequence : BCOVAdSequence ) {
avpvc . showsPlaybackControls = false
}
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didExitAdSequence adSequence : BCOVAdSequence ) {
avpvc . showsPlaybackControls = true
}
Lorsque vous utilisez un AVPlayerviewController avec le plugin BrightCove IMA et les publicités avec un bouton "En savoir plus", vous devrez créer un uiView supplémentaire à utiliser comme vue du conteneur d'annonce. En effet, contentOverlayView
d'AvPlayerViewController n'est pas interactif, donc tenter d'exploiter le bouton "En savoir plus" n'aura aucun effet. Vous pouvez utiliser playbackController:playbackSession:didEnterAdSequence:
et playbackController:playbackSession:didExitAdSequence:
déléguer les méthodes pour afficher et masquer votre vue de conteneur d'annonces.
Si vous utilisez l'IMA, les plugins Freewheel, Pulse ou SSAI sur TVOS, un tableau de AVInterstitialTimeRange
sera créé pour chaque point d'annonce et défini sur les interstitialTimeRanges
de l' AVPlayerItem
associé. Pour les plugins IMA, Freewheel et Pulse, vous voudrez créer un geste de lecture / pause afin que lorsqu'une annonce soit active, vous pouvez s'arrêter correctement et reprendre l'annonce et ne pas affecter la lecture de la vidéo elle-même. Voici un exemple:
func setUpAdPlayPauseGesture ( ) {
let playPauseGesture = UITapGestureRecognizer ( target : self , action : #selector ( playPauseAd ( _ : ) ) )
playPauseGesture . allowedPressTypes = [ NSNumber ( value : UIPress . PressType . playPause . rawValue ) ]
avpvc . view . addGestureRecognizer ( playPauseGesture )
self . playPauseGesture = playPauseGesture
}
@ objc
func playPauseAd ( _ gesture : UITapGestureRecognizer ) {
if insideAdSequence {
if adPlaying {
playbackController ? . resumeAd ( )
adPlaying = false
} else {
playbackController ? . pauseAd ( )
adPlaying = true
}
} else {
if avpvc . player ? . rate == 0 {
playbackController ? . play ( )
} else {
playbackController ? . pause ( )
}
}
}
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didEnterAdSequence adSequence : BCOVAdSequence ) {
insideAdSequence = true
}
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didExitAdSequence adSequence : BCOVAdSequence ) {
insideAdSequence = false
}
Pour afficher une superposition d'annonces, comme un compte à rebours, veuillez consulter la section AVPlayerviewController de la lecture du plugin AD que vous utilisez pour des conseils.
Notez que la compatibilité AVPlayerViewController
de SSAI est spécifique à TVOS en raison de la disponibilité d' AVInterstitialTimeRange
. Vous pourrez toujours avoir la lecture sur iOS, mais la durée de la vidéo inclura la durée de toutes les annonces.
Nous avons des exemples de projets démontrant l'utilisation d'AVPlayerviewController avec le SDK iOS de Brightcove. Vous pouvez trouver le projet d'échantillon iOS ici et le projet TVOS Exemple ici.
Lorsque vous utilisez AVPlayerviewController, les événements vidéo_engagement envoyés au serveur d'analyse Brightcove rapporteront 0 pour Player_Width et Player_Height.
Si vous utilisez le service d'autorisation de lecture, vous devrez utiliser le service de lecture BCOVPlaybackService.ConfigurationKeyAuthToken
Key.
// Video Request
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : videoID ,
BCOVPlaybackService . ConfigurationKeyAuthToken : authToken
]
playbackService . findVideo ( withConfiguration : configuration ,
queryParameters : nil ) { ( video : BCOVVideo ? ,
jsonResponse : Any ? ,
error : Error ? ) in
...
}
// Playlist Request
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : playlistID ,
BCOVPlaybackService . ConfigurationKeyAuthToken : authToken
]
playbackService . findPlaylist ( withConfiguration : configuration ,
queryParameters : nil ) { ( playlist : BCOVPlaylist ? ,
jsonResponse : Any ? ,
error : Error ? ) in
...
}
Remarque: Dans le cas des listes de lecture, toutes les vidéos de la playlist doivent utiliser le même jeton. Dans une version ultérieure, l'attribution d'un jeton différent à chaque vidéo d'une liste de lecture sera possible. Vous serez chargé de maintenir la cartographie entre l'ID vidéo et le jeton.
La voix off est prise en charge à l'extérieur des contrôles de lecture. Par défaut, si VoiceOver est activé, la vue de contrôle BCOVPlayerUI ne tire pas automatiquement. L'utilisation du geste d'activation de la voix off à double tour sur la vue du contrôleur de lecture basculera la visibilité de la vue de contrôle. Il existe une accessibilityHint
associée qui est définie sur la vue du contrôleur de lecture. L' accessibilityLabel
à chaque contrôle BCOVPlayerUI peut être personnalisée dans votre application.
Pour modifier les valeurs accessibilityLabel
à l'un des boutons de la vue de contrôle, vous devez définir un objet pour être un BCOVPUIButtonAccessibilityDelegate
comme ceci:
playerView . controlsView . setButtonsAccessibilityDelegate ( self )
Vous devez alors avoir cet objet conforme au protocole BCOVPUIButtonAccessibilityDelegate
en mettant en œuvre le - (NSString *)accessibilityLabelForButton:(BCOVPUIButton *)button isPrimaryState:(BOOL)isPrimaryState
similaire à celle-ci:
func accessibilityLabel ( for button : BCOVPUIButton ,
isPrimaryState : Bool ) -> String ? {
switch button . tag {
case BCOVPUIViewTag . buttonPlayback . rawValue :
return isPrimaryState ? NSLocalizedString ( " Start Playback " , comment : " playback button " ) : NSLocalizedString ( " Pause Playback " , comment : " playback button " )
case BCOVPUIViewTag . buttonScreenMode . rawValue :
return isPrimaryState ? NSLocalizedString ( " Enter Fullscreen " , comment : " screenmode button " ) : NSLocalizedString ( " Exit Fullscreen " , comment : " screenmode button " )
case BCOVPUIViewTag . buttonJumpBack . rawValue :
return nil
case BCOVPUIViewTag . buttonClosedCaption . rawValue :
return nil
case BCOVPUIViewTag . buttonVideo360 . rawValue :
return nil
case BCOVPUIViewTag . buttonPreferredBitrate . rawValue :
return nil
default :
return nil
}
}
Si une valeur nil
est renvoyée, la valeur par défaut sera utilisée.
La définition accessibilityHint
sur le contrôleur de lecture peut être fait comme ceci:
playbackController . view . accessibilityHint = " Double tap to show or hide controls "
De même, vous pouvez définir l' accessibilityLabel
à la réalisation des étiquettes d'heure et de durée actuelles, ainsi que le curseur de progression, comme ceci:
playerView . controlsView . durationLabel . accessibilityLabelPrefix = " Total Time "
playerView . controlsView . currentTimeLabel . accessibilityLabelPrefix = " Current Time "
playerView . controlsView . progressSlider . accessibilityLabel = " Timeline "
Vous pouvez fournir des localisations linguistiques supplémentaires que le SDK iOS de Brightcove ne prend pas en charge l'emploi.
+
sous la section "Localizations". Pour définir un domaine proxy pour les services de lecture, les métriques et les serveurs d'analyse en Chine, définissez la propriété chinaProxyDomain
du Singleton BCOVGlobalConfiguration
à un nom de domaine entièrement qualifié. Par exemple:
BCOVGlobalConfiguration . sharedConfig . chinaProxyDomain = " host.mydomain.com "
Assurez-vous de définir le nom de domaine proxy avant d'utiliser tout autre service du SDK du joueur natif. Reportez-vous à la référence de la classe BcovGlobalConfiguration pour plus de détails.
Selon la façon dont vous avez besoin de fonctionner votre application en ce qui concerne la lecture audio, vous pouvez configurer Avaudiosession en fonction de vos besoins spécifiques. Par exemple, si vous souhaitez prendre en charge AirPlay 2 et plusieurs itinéraires audio, consultez la section AirPlay de cette lecture.
Une avaudiossion de base peut être configurée comme ceci:
var categoryError : NSError ?
var success : Bool
do {
// see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback
try AVAudioSession . sharedInstance ( ) . setCategory ( . playback )
success = true
} catch let error as NSError {
categoryError = error
success = false
}
if !success {
// Handle error
}
Cette configuration peut généralement être effectuée dans application:didFinishLaunchingWithOptions:
Méthode. Il peut y avoir des situations où vous avez besoin d'une configuration Avaudiosession plus sophistiquée, par exemple si vous souhaitez autoriser l'audio à partir d'autres applications lorsque l'audio de votre application est muet. Dans cette situation, vous pouvez configurer l'Avaudiosession dans le contrôleur de vue qui a accès à votre AVPlayer actuel. Par exemple:
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! ) " )
}
}
Un exemple de code peut être trouvé dans notre exemple de projet VideoCloudBasicPlayer.
Vous pouvez en savoir plus sur Avaudiosession ici.
Le SDK BrightCove Player prend en charge les flux audio uniquement et comprend quelques fonctionnalités audio uniquement. Si vous avez configuré une image d'affiche pour votre vidéo, cette image sera affichée dans le contentOverlayView
de votre BCOVPUIPlayerView
. Vous pouvez ajuster la UIViewContentMode
de la vue de l'image de l'affiche en utilisant la propriété contentModeForPosterImage
sur BCOVPUIPlayerViewOptions
, la valeur par défaut est UIViewContentModeScaleAspectFit
.
Vous pouvez également garder les commandes des joueurs visibles à tout moment, dans ce cas, vous pouvez activer keepControlsVisible
sur BCOVPUIPlayerViewOptions
.
Si vous ne souhaitez pas afficher l'image de l'affiche ou simplement une vue de lecture plus compacte, vous pouvez définir la hauteur de votre vue parent BCOVPUIPlayerView
à une hauteur de 88 pt pour une disposition compacte (<450 pt) ou une hauteur de 44 pt pour une disposition standard.
Il existe trois dispositions préconfigurées audio BCOVPUIBasicControlView
que vous pouvez utiliser si vous n'utilisez pas automaticControlTypeSelection
:
basicControlViewWithAODLayout
basicControlViewWithLiveAudioLayout
basicControlViewWithLiveDVRAudioLayout
Vous pouvez également être informé si un flux est uniquement audio ou vidéo + audio avec le playbackController:playbackSession:determinedMediaType
:
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
determinedMediaType mediaType : BCOVSourceMediaType ) {
switch mediaType {
case BCOVSourceMediaType . audio :
print ( " Source is Audio Only " )
case BCOVSourceMediaType . audioVideo :
print ( " Source is Audio and Video " )
default :
break
}
}
Notre VideoCloudBasicPlayer prend en charge l'affichage des informations multimédias sur l'écran de verrouillage, le centre de contrôle et sur AirPlay. Voir la classe NowPlayingHandler
pour les détails de mise en œuvre.
Un pare-chocs vidéo est un actif court, généralement 10 secondes ou moins, qui joue avant tous les autres médias et montre généralement la marque ou l'entreprise que votre vidéo représente. Un lecteur demandera un pare-chocs à l'API de lecture comme n'importe quelle autre vidéo et l'inservera avant les publicités et le contenu.
Les pare-chocs sont une fonctionnalité au niveau du joueur, ce qui signifie qu'un joueur donné ne peut être associé qu'à un seul pare-chocs. Les listes de lecture partagent la même vidéo de pare-chocs. Il existe deux façons de configurer un lecteur pour lire une vidéo pare-chocs:
bumperID
. L'ID de la vidéo à trouver. // Using `bumperID`
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : videoID ,
BCOVPlaybackService . ConfigurationKeyBumperID : bumperID
]
// Using `bumperReferenceID`
let configuration = [
BCOVPlaybackService . ConfigurationKeyAssetID : playlistID ,
BCOVPlaybackService . ConfigurationKeyBumperReferenceID : bumperReferenceID
]
// With a Video Request
playbackService . findVideo ( withConfiguration : configuration ,
queryParameters : nil ) { ( video : BCOVVideo ? ,
jsonResponse : Any ? ,
error : Error ? ) in
...
}
// With a Playlist Request
playbackService . findPlaylist ( withConfiguration : configuration ,
queryParameters : nil ) { ( playlist : BCOVPlaylist ? ,
jsonResponse : Any ? ,
error : Error ? ) in
...
}
Le champ bumper_id
peut être défini dans des champs personnalisés dans VideoCloud / Studio. Le bumper_id
peut être utilisé sans les signatures précédemment définies. Le bumper_id
doit être un ID vidéo valide.
Remarque: le buatterid passé via les champs personnalisés (champ bumper_id
) prenez la priorité sur n'importe quel ID dans le service de lecture.
Les commandes de lecture peuvent être cachées pendant que le pare-chocs joue.
let options = BCOVPUIPlayerViewOptions ( )
options . automaticControlTypeSelection = true
options . showBumperControls = false
let playerView = BCOVPUIPlayerView ( playbackController : nil , options : options , controlsView : nil )
Si l'option automaticControlTypeSelection
est définie sur true
, la mise en page du pare-chocs s'adaptera au contenu (vidéo ou audio uniquement). basicControlViewWithVODLayout
et basicControlViewWithAODLayout
Les dispositions sont conçues pour les pare-chocs, les dispositions Live
ou LiveDVR
ne sont pas disponibles. Les commandes de lecture ont une apparence unique lorsqu'un pare-chocs actif:
La prise en charge de l'interactivité est intégrée dans le cadre de base BrightCovePlayersDK . Pour plus de détails sur l'utilisation de l'interactivité avec le SDK du joueur natif de Brightcove, reportez-vous au guide d'interactivité.
Si le contenu est emballé sous forme de MP4, vous pouvez coller l'URL directement dans la plupart des navigateurs Web, et la vidéo doit lire (ou télécharger sur votre système de fichiers, où vous pouvez la lire localement). Si le contenu est emballé sous forme de HLS, vous pouvez utiliser Quicktime Player pour le tester: Sélectionnez File -> Open Location…
et coller dans l'URL de la liste de lecture .m3u8
, et que la vidéo devrait jouer.
Il s'agit d'un symptôme courant d'avoir appelé une méthode UIKIT ou AVFoundation unique uniquement à partir d'un fil non conçu. Les méthodes du délégué sur BCOVPlaybackControllerDelegate
sont toujours appelées sur le thread principal.
Ce message indique que la stratégie de sélection de source par défaut ne peut pas comprendre quelle source choisir. La stratégie par défaut sélectionne la première source dont deliveryMethod
est en train de kBCOVSourceDeliveryHLS
("HLS"). Si aucune source HLS n'est trouvée, son comportement de secours sélectionnera la première source dont deliveryMethod
est kBCOVSourceDeliveryMP4
("MP4"). Si aucune source avec une deliveryMethod
de "HLS" ou "MP4" n'existe sur la vidéo, la politique sélectionnera la première source de la vidéo (quelle que soit deliveryMethod
). Si vous n'êtes pas satisfait de sa sélection, vous pouvez utiliser -[BCOVPlayerSDKManager createBasicSessionProviderWithOptions:]
et passer dans un cas de BCOVBasicSessionProviderOptions
avec un ensemble de propriétés sourceSelectionPolicy
personnalisée. Lors de la création de vidéos et de sources manuellement, assurez-vous que les sources sont créées avec la deliveryMethod
appropriée.
L'API qui contrôle si une application émet l'audio dans les applications iOS est l'API Avaudiosession. Une session audio est globale d'une application, ce qui signifie que sa configuration affecte à la fois les sons émis par les AVPlayers créés par le SDK Player, ainsi que d'autres sons qu'une application peut produire. Étant donné que le SDK Player ne peut pas savoir comment l'application souhaite que la session audio soit configurée pour ces autres sons, cela n'affecte pas du tout la session audio. This means that unless you explicitly configure your app's audio session otherwise, you inherit the default behavior of suppressing any and all audio when the device is muted, including audio emitted by AVPlayers. To conform to Apple's recommendations regarding audio playback, you (the app developer) must configure the audio session according to your app's specific needs.
See our AVAudioSession Configuration section in this README for additional information.
If you have questions, need help or want to provide feedback, please use the Support Portal or contact your Account Manager. To receive notification of new SDK software releases, subscribe to the Brightcove Native Player SDKs Google Group.