Brightcove proporciona soporte activo para el SDK de iOS más reciente en la última versión pública de las siguientes versiones de iOS:
Brightcove proporciona soporte pasivo para las siguientes versiones de iOS:
El Core SDK está traducido al árabe (ar), inglés (en), francés (fr), alemán (de), japonés (ja), coreano (ko), español (es), chino simplificado (zh-Hans) y tradicional. Chino (zh-Hant). Para obtener el beneficio de una localización, su aplicación también debe estar traducida al mismo idioma y configuración regional. Consulte la sección Localización personalizada para obtener información adicional.
Todos los componentes del SDK (los marcos principales y de complementos) se publican con el mismo número de versión. Al actualizar cualquier componente, actualice todos los componentes a la misma versión.
Para proyectos que utilizan Xcode 12 en Apple Silicon M1 y Universal Frameworks (.framework), se devuelve un error de compilación al compilar el proyecto para el simulador arm64.
*ld: building for iOS Simulator, but linking in dylib built for iOS, file for architecture arm64*
Para compilar para un simulador arm64, asegúrese de que arm64
se haya agregado a la configuración de compilación "Arquitecturas excluidas" para Any iOS Simulator SDK
en la pestaña "Configuración de compilación" del destino de su aplicación.
La versión 6.10.0 del SDK de Brightcove Player agrega subespecciones para el núcleo y cada complemento para admitir XCFrameworks. El valor predeterminado para cada subespección es /XCFramework
.
Nombre de especificación de módulo | Nombres de subespecciones |
---|---|
Brightcove-Player-Core | Brightcove-Player-Core/Marco 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 versión 6.12.0 de Brightcove Player SDK actualiza las especificaciones de pod Brightcove-Player-FreeWheel
y Brightcove-Player-Omniture
para instalar la versión dinámica de BrightcovePlayerSDK
.
Nombre de especificación de módulo | Tipo de marco | Dependencia |
---|---|---|
Brightcove-Player-Core | dinámica | - |
Brightcove-Player-DAI (disponible desde 6.12.7) | dinámica | Brightcove-Player-Core |
Brightcove-Player-FreeWheel | dinámica | Brightcove-Player-Core para iOS, Brightcove-Player-Core para tvOS |
Brightcove-Player-GoogleCast | estático | Brightcove-Player-Core |
Brightcove-Player-IMA | dinámica | Brightcove-Player-Core |
Brightcove-Player-Omniture | dinámica | Brightcove-Player-Core |
Brightcove-Player-Pulse | dinámica | Brightcove-Player-Core |
Brightcove-Player-SSAI | dinámica | Brightcove-Player-Core, Brightcove-Player-OpenMeasurement (solo para medición abierta) |
Brightcove-Player-OpenMeasurement (disponible desde 6.10.0) | dinámica | - |
La compatibilidad con vídeos protegidos por FairPlay está integrada en el marco central de BrightcovePlayerSDK . Consulte la guía de FairPlay para obtener detalles completos sobre el uso de FairPlay con el SDK de Brightcove Native Player.
La compatibilidad con subtítulos Sidecar está integrada en el marco central de BrightcovePlayerSDK . Para obtener detalles completos sobre el uso de subtítulos Sidecar con el SDK de Brightcove Native Player, consulte la guía de subtítulos Sidecar.
Desde la versión 6.0.0, el SDK de Brightcove Native Player le permite descargar vídeos HLS, incluidos aquellos protegidos con cifrado FairPlay, para reproducirlos más tarde, ya sea en línea o sin conexión. Consulte la guía del desarrollador de la aplicación para obtener todos los detalles:
Guía del desarrollador de aplicaciones iOS para la descarga y reproducción de vídeos sin conexión con FairPlay
El SDK de Brightcove Player proporciona paquetes de instalación para iOS y tvOS como bibliotecas dinámicas empaquetadas como Frameworks y XCFrameworks. La implementación es compatible con iOS 12.0 y superior.
Puede utilizar CocoaPods para agregar el SDK de Brightcove Player a su proyecto. Puede encontrar la última especificación de pod Brightcove-Player-Core
aquí. Podspec es compatible tanto con iOS como con tvOS.
Cuando utilice Brightcove CocoaPods en su proyecto, agregue source 'https://github.com/brightcove/BrightcoveSpecs.git'
al inicio de su Podfile.
nombre.
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
Framework se puede instalar agregando la subespecificación /Framework
al 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
Al actualizar su instalación, es una buena idea actualizar la copia local de su repositorio BrightcoveSpecs para tener las últimas especificaciones de pod localmente, tal como actualizaría su repositorio maestro CococaPods. Normalmente, si ejecuta pod update
en la Terminal, esto sucederá automáticamente o, alternativamente, puede actualizar explícitamente con pod repo update
.
Para agregar manualmente el SDK de Brightcove Player a su proyecto:
BrightcovePlayerSDK.framework
o BrightcovePlayerSDK.xcframework
a su proyecto. Asegúrate de utilizar la versión correspondiente a tu objetivo, iOS o tvOS.BrightcovePlayerSDK.framework
/ BrightcovePlayerSDK.xcframework
bash ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/BrightcovePlayerSDK.framework/strip-frameworks.sh
. Marque "Ejecutar script solo durante la instalación". Esto eliminará las arquitecturas innecesarias de la compilación, lo cual es importante para el envío a la App Store. Este paso ya no es necesario cuando se utiliza XCFramework.bash ${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/BrightcovePlayerSDK.framework/strip-frameworks.sh
. Marque "Ejecutar script solo durante la instalación". Esto eliminará las arquitecturas innecesarias de la compilación, lo cual es importante para el envío a la App Store.arm64
se haya agregado a su configuración de compilación "Arquitecturas excluidas" para Any iOS Simulator SDK
.Como referencia, aquí están todos los componentes del SDK y las URL correspondientes para ayudarle a localizar y descargar las últimas versiones:
Componente | 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 |
Para agregar el SDK de Brightcove Player a su proyecto con Swift Package Manager:
https://github.com/brightcove/brightcove-player-sdk-ios.git
Nota: Solo el XCFramework dinámico es compatible con Swift Package Manager.
El SDK de Brightcove Player para iOS se puede importar mediante:
import BrightcovePlayerSDK;
Reproducción de vídeo con Brightcove Player SDK para 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 ( )
}
}
Debe evitar que el controlador se libere automáticamente al final del método. Una forma común de hacer esto es almacenar una referencia al controlador en una variable de instancia segura.
Desde la versión 5.1.0, Brightcove PlayerUI está completamente integrado en el marco Core SDK. PlayerUI proporciona un conjunto completo de controles para reproducción y publicidad, listo para usar.
PlayerUI se configura rápidamente, muestra controles de anuncios para SSAI, Pulse y FreeWheel, y se puede personalizar creando sus propios diseños.
Siga las pautas a continuación para configurar los controles de PlayerUI.
Cree una propiedad en su UIViewController para realizar un seguimiento de BCOVPUIPlayerView. BCOVPUIPlayerView contendrá tanto la vista del controlador de reproducción como la vista de controles.
// PlayerUI's Player View
var playerView : BCOVPUIPlayerView ?
Cree BCOVPUIBasicControlView y luego BCOVPUIPlayerView. Aquí es donde asociamos el Controlador de reproducción (y por tanto todos los vídeos que reproduce) con los controles.
// 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 )
}
Necesitará configurar el diseño para la vista del reproductor; puede hacerlo con Auto Layout o el enfoque anterior de Springs & Struts.
Configure la vista del reproductor para que coincida con el contenedor de video de su diseño ( videoView
) cuando cambie de tamaño.
playerView . frame = videoView . bounds
playerView . autoresizingMask = [ . flexibleHeight , . flexibleWidth ]
Establezca translatesAutoresizingMaskIntoConstraints
en BCOVPUIPlayerView en false
.
playerView . translatesAutoresizingMaskIntoConstraints = false
Luego agregue las restricciones para el diseño; configurar los anclajes superior, derecho, izquierdo e inferior de su BCOVPUIPlayerView para que sean iguales a los 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 clase BCOVPUIPlayerViewOptions
le permite personalizar algunos comportamientos de BCOVPlayerUI en la inicialización. Puedes personalizar lo siguiente:
jumpBackInterval
El tiempo en segundos que el jugador buscará hacia atrás cuando se presione el botón de salto hacia atrás.
hideControlsInterval
El tiempo en segundos después del último evento táctil, antes de que se oculten los controles.
hideControlsAnimationDuration
El tiempo en segundos que tardan los controles en animarse a oculto.
showControlsAnimationDuration
El tiempo en segundos que tardan los controles en animarse y volverse visibles.
learnMoreButtonBrowserStyle
Configuración que determina si al tocar el botón "Más información" en un anuncio se mostrará el enlace de clic en un navegador externo (configuración predeterminada) o en un navegador interno.
presentingViewController
La subclase UIViewController que se utilizará para presentar otros controladores de vista (como el controlador de vista de selección de subtítulos).
automaticControlTypeSelection
Si desea o no que BCOVPUIPlayerView
elija un tipo BCOVPUIBasicControlView
automáticamente según el tipo de medio. Cuando este valor se establece en true
se ignorará la propiedad BCOVPUIBasicControlView
pasada al inicializador BCOVPUIPlayerView
.
Secuencias de vídeo y audio
basicControlViewWithVODLayout
basicControlViewWithLiveLayout
basicControlViewWithLiveDVRLayout
Transmisiones de solo audio
basicControlViewWithAODLayout
basicControlViewWithLiveAudioLayout
basicControlViewWithLiveDVRAudioLayout
NOTA: automaticControlTypeSelection
elige diseños entre los proporcionados por BCOVPlayerUI y, por lo tanto, se sobrescribirán los controles y diseños personalizados; automaticControlTypeSelection
y la personalización de la interfaz de usuario del reproductor son incompatibles.
Las opciones se pueden configurar usando el siguiente método:
let manager = BCOVPlayerSDKManager . sharedManager ( )
let playbackController = manager . createPlaybackController ( )
let options = BCOVPUIPlayerViewOptions ( )
options . jumpBackInterval = 5
let playerView = BCOVPUIPlayerView ( playbackController : playbackController ,
options : options )
Se proporcionan tres diseños para admitir diferentes tipos de vídeo:
BCOVPUIControlLayout basicVODControlLayout
es un diseño básico para transmisiones de vídeo bajo demanda generales.
BCOVPUIControlLayout basicLiveControlLayout
es un diseño para vídeo en vivo.
BCOVPUIControlLayout basicLiveDVRControlLayout
es un diseño para transmisiones de video en vivo con controles DVR.
Por lo general, configura un nuevo diseño inmediatamente después de crear BCOVPUIPlayerView
, pero también puede configurar un nuevo diseño en cualquier momento. Por ejemplo, puedes configurar un nuevo diseño de VOD como este:
playerView ? . controlsView . layout = BCOVPUIControlLayout . basicVOD ( )
Además de los diseños predeterminados, puede crear sus propios diseños altamente personalizados creando una instancia de un nuevo BCOVPUIControlLayout
con su propio diseño. Sin embargo, tenga en cuenta que automaticControlTypeSelection
elige diseños entre los proporcionados por BCOVPlayerUI y, por lo tanto, se sobrescribirán los controles y diseños personalizados; automaticControlTypeSelection
y la personalización de la interfaz de usuario del reproductor son incompatibles.
Primero, cree los controles que irán en su diseño usando BCOVPUIBasicControlView layoutViewWithControlFromTag:width:elasticity:
. Cada control está empaquetado en un BCOVPUILayoutView
que determina el espaciado de los controles.
Puede establecer el width
de cada vista de diseño en el ancho predeterminado (que se basa en el tipo de control), o puede especificar su propio ancho.
Utilice el argumento elasticity
para determinar en qué medida la vista de diseño que contiene el control redimensiona su ancho para llenar la barra de control.
A continuación se muestran ejemplos de cómo crear una variedad de controles básicos.
// 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 )
Tenga en cuenta que también puede crear una vista de diseño vacía, en la que puede colocar su propia vista (logotipo, control, nada, etc.). Este código muestra cómo colocar un logotipo UIImage
dentro de logoLayoutView1 que creamos anteriormente.
// 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 )
Ahora que hay varios controles empaquetados en vistas de diseño, están ordenados en matrices, cada una de las cuales representa una única línea de controles, es decir, una barra de controles. Tenga en cuenta que puede tener diferentes diseños para orientación vertical y horizontal, por lo que normalmente configurará dos conjuntos diferentes de barras de control.
En el diseño estándar para orientación horizontal, los controles se organizan en una única matriz y luego esa matriz se almacena en otra matriz que representa el conjunto completo de controles.
let standardLayoutLine1 = [
playbackLayoutView ,
jumpBackButtonLayoutView ,
currentTimeLayoutView ,
timeSeparatorLayoutView ,
durationLayoutView ,
progressLayoutView ,
spacerLayoutView1 ,
logoLayoutView1 ,
spacerLayoutView2 ,
closedCaptionLayoutView ,
screenModeLayoutView ,
externalRouteLayoutView
]
let standardLayoutLines = [ standardLayoutLine1 ]
En el diseño compacto para orientación vertical, se crean dos conjuntos de controles, uno para cada línea. Estas matrices están empaquetadas en otra matriz que representa el diseño compacto.
Tenga en cuenta que se utilizan exactamente los mismos objetos para la mayoría de los controles en cada diseño. Cuando haya terminado y cambie entre la orientación vertical y horizontal, el objeto se moverá a su nueva posición mediante una animación suave.
let compactLayoutLine1 = [
currentTimeLayoutView ,
progressLayoutView ,
durationLayoutView
]
let compactLayoutLine2 = [
playbackLayoutView ,
jumpBackButtonLayoutView ,
spacerLayoutView1 ,
closedCaptionLayoutView ,
screenModeLayoutView ,
externalRouteLayoutView ,
logoLayoutView2
]
let compactLayoutLines = [
compactLayoutLine1 ,
compactLayoutLine2
]
Finalmente, ahora que hay dos configuraciones de diseño (una para ancho completo y otra para ancho compacto), puede crear un nuevo objeto BCOVPUIControlLayout
y configurarlo en la vista de control del reproductor.
let customLayout = BCOVPUIControlLayout . init ( standardControls : standardLayoutLines ,
compactControls : compactLayoutLines )
playerView ? . controlsView . layout = customLayout
Si tiene controles que necesita mostrar u ocultar con frecuencia, puede configurar la propiedad removed
en la vista de diseño de ese control. Cuando haya cambiado sus controles, llame setNeedsLayout
en el controlView de playerView:
logoLayoutView1 ? . isRemoved = true
playerView ? . controlsView . setNeedsLayout ( )
También puede personalizar varias propiedades generales BCOVPUIControlLayout
:
controlBarHeight
establece el tamaño de cada fila de controles.horizontalItemSpacing
establece el espacio entre cada BCOVPUILayoutView
en cada barra de control.compactLayoutMaximumWidth
determina qué conjunto de controles se utiliza. Si la vista de control es más pequeña que compactLayoutMaximumWidth
, se utilizará el conjunto de controles compactos; de lo contrario, se utilizarán los controles estándar. Para cambiar el conjunto de controles que se muestran, debe crear e instalar un nuevo BCOVPUIControlLayout
. Se pueden instalar nuevos controles en cualquier momento.
Para obtener más ejemplos de personalización de PlayerUI, puede consultar el código de muestra en la carpeta PlayerUI del repositorio BrightcoveOS GitHub:
https://github.com/BrightcoveOS/ios-player-samples
El SDK de Brightcove Native Player incluye controles integrados para la reproducción en tvOS en Apple TV. Para obtener detalles completos sobre el uso de la interfaz de usuario del reproductor de TV integrada con el SDK de Brightcove Native Player, consulte nuestra guía del reproductor de TV.
Habilite la funcionalidad AirPlay configurando la propiedad setAllowsExternalPlayback
en su BCOVPlaybackController
en true
. El botón AirPlay se mostrará en los controles de reproducción si se encuentran dispositivos AirPlay en su red.
Actualmente, IMA es el único complemento publicitario que admite AirPlay y solo cuando se utilizan anuncios pre-roll y/o post-roll. El uso de AirPlay con los complementos publicitarios Pulse, SSAI o FreeWheel puede provocar un comportamiento inesperado.
Si también desea admitir AirPlay 2 y permitir que se seleccionen varios dispositivos para la salida de audio, tendrá que hacer algunas cosas adicionales. Primero, deberá configurar AVAudioSession para poder configurar routeSharingPolicy
. Por ejemplo:
do {
try AVAudioSession . sharedInstance ( ) . setCategory ( . playback , mode : . moviePlayback , policy : . longFormVideo )
} catch {
print ( " Error setting AVAudioSession category " )
}
También deberá configurar al menos un comando de reproducción a través de MPRemoteCommandCenter
. Como mínimo querrás configurar pauseCommand
y playCommand
. Por ejemplo:
let center = MPRemoteCommandCenter . shared ( )
center . pauseCommand . addTarget { _ in
playbackController . pause ( )
return . success
}
center . playCommand . addTarget { _ in
playbackController . play ( )
return . success
}
Los dispositivos aprovecharán AVRoutePickerView
, que tiene dos métodos de delegado. Estos métodos delegados se pasan a BCOVPUIPlayerViewDelegate
. Los métodos son:
func routePickerViewDidEndPresentingRoutes ( _ routePickerView : AVRoutePickerView )
func routePickerViewWillBeginPresentingRoutes ( _ routePickerView : AVRoutePickerView )
El AVRouteDetector
utilizado para descubrir rutas AirPlay está disponible en el objeto BCOVPUIBasicControlView
para que pueda habilitar o deshabilitar su propiedad routeDetectionEnabled
según sea necesario.
Según la documentación de Apple: " La detección de rutas aumenta significativamente el consumo de energía y debe desactivarse cuando ya no es necesaria".
playerView ? . controlsView . routeDetector . isRouteDetectionEnabled = false
Para obtener más información sobre cómo incorporar AirPlay 2 en su aplicación, consulte la documentación Cómo incorporar Airplay 2 a su aplicación.
El SDK de Native Player incluye soporte para mostrar interactivamente videos esféricos de 360 grados. Los vídeos 360 deben etiquetarse con una propiedad de campo "proyección" que contenga el valor "equirectangular". Estos videos se cargarán y reproducirán de la misma manera que otros videos, pero se mostrarán en CAMetalLayer en lugar de AVPlayerLayer.
Nota: "equirectangular" es el único formato de proyección admitido para vídeos de origen 360 en este momento.
PlayerUI también tiene soporte integrado para Video 360, lo que proporciona gestos de panorámica predeterminados, detección de movimiento giroscópico para la vista y un nuevo botón de Video 360 que aparece cuando se reproduce un recurso de Video 360. Este botón aparece solo en iPhone y le permite alternar entre la vista normal y una vista de "Gafas VR", donde la pantalla se divide en dos, con la misma escena representada para cada ojo para que el dispositivo se pueda usar en una cabeza. configuración montada. En iPads no se necesita ningún botón Video 360 porque solo hay un modo de operación: detección de movimiento con soporte de gestos de panorámica.
Admitir Video 360 es tan simple como reproducir un video. Cuando se detecta la propiedad del campo "proyección", el SDK de Native Player se encargará automáticamente de configurar y mostrar el video en Metal e instalar el botón Video 360 cuando sea apropiado.
Si reproduce vídeos 360 fuera de Video Cloud, asegúrese de agregar una propiedad de "proyección" al objeto BCOVVideo
con el valor "equirectangular".
Para brindar la mejor experiencia de usuario con el modo Gafas VR, debe usar un método BCOVPUIPlayerViewDelegate
para detectar cuándo este modo está habilitado. Esto le permite forzar la orientación horizontal del dispositivo (ya que esa es la única orientación que tiene sentido para una vista de gafas VR).
El siguiente código muestra cómo podría manejar un cambio de orientación forzado al alternar entre una vista normal de 360 grados y el modo Gafas VR.
// 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 ( )
}
PlayerUI instalará gestos para manejar la navegación por el video 360, pero si usa sus propios controles, puede configurar los parámetros de visualización de la cámara virtual usted mismo. La propiedad viewProjection
del protocolo BCOVPlaybackController
le permite establecer estos parámetros. La propiedad es una clase BCOVVideo360ViewProjection
con configuraciones básicas de cámara virtual como pan
, tilt
y zoom
. Para cambiar la configuración, haga una copia de la instancia actual, cambie la configuración en la nueva instancia y luego asígnela nuevamente a la propiedad viewProjection
.
El punto de entrada al SDK de Brightcove Player para iOS es el objeto singleton BCOVPlayerSDKManager
. Este Administrador maneja el registro de componentes de complementos y algunas otras tareas domésticas, pero sirve principalmente como una fábrica de objetos. El controlador de vista de su aplicación obtiene una referencia al Administrador y la usa para crear un BCOVPlaybackController
. La propiedad view
del controlador de reproducción expone una UIView que contiene el objeto AVPlayerLayer que finalmente presenta el contenido de su video en la pantalla. El controlador de reproducción también acepta BCOVPlaybackControllerDelegate
, que puede implementar para responder a varios eventos de reproducción de video.
El controlador de reproducción ofrece métodos y propiedades para afectar la reproducción del video actual. Sin embargo, internamente, el controlador de reproducción delega en un objeto BCOVPlaybackSession
. Las sesiones de reproducción realizan el trabajo real de preparar y reproducir contenido de video y contienen los metadatos del video y AVPlayer
. El controlador de reproducción tiene mecanismos para avanzar de la sesión de reproducción actual a la siguiente sesión de reproducción, ya sea automáticamente al final de un video o manualmente con una llamada a un método. Una vez que el controlador de reproducción ha avanzado a una nueva sesión, la sesión anterior se descarta y no se puede volver a utilizar.
Hay otros dos elementos del controlador de reproducción: un BCOVPlaybackSessionProvider
y una lista de BCOVPlaybackSessionConsumer
. Como sugiere el nombre, el proveedor de la sesión de reproducción es responsable de crear sesiones de reproducción y entregarlas al controlador de reproducción. A continuación, el controlador de reproducción entrega la sesión a cada uno de los consumidores de sesiones de reproducción de la lista. Tanto la API del proveedor de sesión como la del consumidor de sesión están diseñadas para que las utilicen los desarrolladores de complementos y no se detallan en este documento.
Además de la funcionalidad de reproducción proporcionada por las clases descritas anteriormente, existen varias clases de valores. Se utilizan para almacenar datos específicos del Player SDK para iOS. Cada uno de estos se describe con más detalle en su propia sección a continuación.
El SDK de Brightcove Player para iOS proporciona métodos de reproducción, pausa y búsqueda en BCOVPlaybackController
. Es importante utilizar estos métodos en lugar de utilizar el equivalente de AVPlayer. En sus implementaciones predeterminadas, estos objetos reenvían las llamadas directamente al método correspondiente en AVPlayer. Sin embargo, si utiliza complementos, es posible que anulen el comportamiento predeterminado para agregar funcionalidad. Por ejemplo, si utiliza un complemento publicitario, llamar a playbackController.play()
la primera vez puede hacer que se reproduzca el pre-roll antes de comenzar el contenido. Para obtener más información sobre cómo un complemento puede anular el comportamiento predeterminado, consulte cada complemento README.md o busque una extensión de categoría en BCOVSessionProviderExtension
que el complemento pueda agregar.
Llamar directamente a reproducción, pausa o búsqueda en AVPlayer puede causar un comportamiento indefinido.
Para establecer una velocidad de reproducción personalizada para AVPlayer, puede usar la propiedad playbackRate
en BCOVPlaybackController
. Es importante que configure la velocidad de reproducción usando esta propiedad en lugar de configurarla directamente en AVPlayer.
Si intenta establecer playbackRate
en un valor de 0 o menos, el valor se establecerá en 1,0. Si currentItem
de AVPlayer no admite canPlaySlowForward
(para valores inferiores a 1) o canPlayFastForward
(para valores superiores a 1), se utilizará la velocidad de reproducción predeterminada de 1,0. La reproducción de anuncios no se verá afectada.
Si se ha establecido un valor personalizado para playbackRate
el audioTimePitchAlgorithm
para cada AVPlayerItem
se establecerá en AVAudioTimePitchAlgorithmTimeDomain
. Alternativamente, puedes establecer tu propio valor para audioTimePitchAlgorithm
de esta manera:
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didReceive lifecycleEvent : BCOVPlaybackSessionLifecycleEvent ) {
if lifecycleEvent . eventType == kBCOVPlaybackSessionLifecycleEventReady {
session . player . currentItem ? . audioTimePitchAlgorithm = . varispeed
}
}
Puede leer más sobre audioTimePitchAlgorithm
aquí.
Desde la versión 6.12.0, el SDK de iOS ha utilizado AVQueuePlayer, que se encarga de precargar el siguiente vídeo de la cola.
Sin embargo, es posible que desees tener más control sobre la precarga de los próximos vídeos en una lista de reproducción. Un posible enfoque es almacenar en doble búfer una lista de vídeos utilizando dos controladores de reproducción, por ejemplo:
playbackController1.setVideos([videos.firstObject])
).playbackController:didProgressTo:
delegado del controlador de reproducción, determine si el video actual ha progresado lo suficiente hasta donde desea comenzar a precargar el siguiente video.Para ver un ejemplo práctico, puede descargar nuestra aplicación de muestra VideoPreloading desde nuestro repositorio de muestras de reproductores.
Nota: Es posible que desee tener en cuenta la cantidad de memoria disponible en el dispositivo del cliente y la velocidad de su conexión. Si no están conectados a Wifi, la precarga de un vídeo puede afectar los recursos de red del vídeo actual.
Brightcove Player SDK para iOS ofrece a los clientes la posibilidad de adjuntar múltiples URL y tipos de entrega ( BCOVSource
) a un solo vídeo ( BCOVVideo
). Por ejemplo, si el servicio de reproducción recupera sus videos, puede haber una combinación de representaciones HLS o MP4 para un solo video, junto con versiones HTTP y HTTPS. Cuál de estas fuentes se selecciona está determinada por un bloque de política de selección de fuente. La política de selección de fuente predeterminada seleccionará el primer HLS BCOVSource
en cada BCOVVideo
, prefiriéndose las fuentes HTTPS a HTTP.
La selección de fuente se puede anular creando un BCOVBasicSessionProviderOptions
y usándolo para crear un BCOVBasicSessionProvider
. Por ejemplo:
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 esta política de selección predeterminada no funciona para usted, existen algunas alternativas para seleccionar una fuente:
Si recupera vídeos de Video Cloud a través del servicio de reproducción, antes de llamar playbackController.setVideos()
, utilice el método de actualización en BCOVVideo
para contener solo la fuente que desee (consulte la sección "Valores" para obtener más información).
Puede utilizar el método auxiliar [BCOVBasicSourceSelectionPolicy sourceSelectionHLSWithScheme:scheme]
para crear una política que prefiera un esquema específico. Este es el método utilizado para crear la política de selección de fuente predeterminada que prefiere HTTPS.
De manera similar a actualizar el objeto de video, también puede implementar su propio bloque de selección de fuente.
options . sourceSelectionPolicy = { ( video : BCOVVideo ? ) -> BCOVSource ? in
< Check video . sources for source >
< Return source >
}
Tenga en cuenta que existen limitaciones en la App Store con respecto al uso de vídeos MP4. Consulte la información más reciente para desarrolladores de Apple para obtener más detalles.
El SDK de Brightcove Player para iOS proporciona una manera de establecer la tasa de bits preferida para un vídeo. Puede crear un objeto BCOVPreferredBitrateConfig que contenga las opciones de tasa de bits deseadas, junto con alguna configuración para el controlador de vista que se crea para mostrar las opciones.
El título del menú es opcional. Las opciones de velocidad de bits son una matriz de NSDictionary y cada diccionario tiene un par clave:valor. La clave se utilizará como nombre de la opción y el valor es un NSNumber con la tasa de bits para esa opción en bps (bits por segundo). Las velocidades de bits que ingresa son valores que se pueden asignar a velocidades de bits de las representaciones de sus recursos de video. Puede obtener más información sobre las representaciones en Mejores prácticas de perfiles de ingesta.
Aquí hay un ejemplo:
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 )
Cuando el usuario final selecciona una de las opciones, la propiedad preferidaPeakBitRate del AVPlayerItem actual se establecerá en el valor de la opción. Si el vídeo está en una lista de reproducción, el siguiente vídeo reproducido también tendrá establecido el valor de PeakBitRate preferido.
Después de establecer un valor distinto de cero para preferidoPeakBitRate, es posible que no note una diferencia en la calidad hasta que AVPlayer haya llegado al final de su caché actual.
Además, puede utilizar el inicializador configWithMenuTitle:bitrateOptions:andIndexofInitialSelection:
que proporciona la posibilidad de establecer el índice de su valor inicial preferido. El índice debe correlacionarse con el índice de la opción deseada en la matriz bitrateOptions
.
Además, puede utilizar el método setPreferredPeakBitRate:
en su objeto BCOVPlaybackController
para establecer mediante programación la tasa de bits preferida para las sesiones actuales y futuras.
NOTA: A los usuarios finales se les debe proporcionar una forma de volver al valor predeterminado (0) deferredPeakBitRate. Puede hacer esto proporcionando una opción con un valor de tasa de bits de 0. Si no proporciona una opción de tasa de bits de 0, se agregará una opción "Automática" a su lista de opciones para el usuario final.
Consulte la documentación de Apple sobre preferidoPeakBitRate para obtener más información.
Brightcove Player SDK para iOS proporciona dos mecanismos para obtener información de reproducción. El controlador de reproducción proporciona una propiedad delegada que implementa BCOVPlaybackControllerDelegate
. Un delegado puede implementar estos métodos opcionales para recibir notificaciones sobre los metadatos de reproducción, como el progreso, los cambios de duración y otros eventos. Si se instala un complemento de anuncios, también puede utilizar este delegado para proporcionar información sobre la reproducción de anuncios. El método de delegado de eventos del ciclo de vida proporciona eventos para señalar cambios en el estado de reproducción. Por ejemplo, cuando un reproductor pasa del estado de pausa al estado de reproducción, se llamará al método delegado del evento del ciclo de vida con el evento kBCOVPlaybackSessionLifecycleEventPlay
. Los eventos del ciclo de vida predeterminados se declaran en BCOVPlaybackSession
. Los complementos proporcionados por Brightcove agregan eventos de ciclo de vida adicionales que se definen en cada complemento.
El controlador de reproducción permite un solo delegado. En muchos casos, esto será suficiente para recuperar información; Las implementaciones delegadas pueden difundir valores y eventos a diferentes partes de la aplicación según sea necesario. En los casos en los que se requieran varios delegados, como es el caso al desarrollar un complemento, los delegados BCOVPlaybackSessionConsumer
proporcionan una funcionalidad equivalente a los métodos BCOVPlaybackControllerDelegate
, incluidos los datos publicitarios.
Aquí hay un ejemplo de cómo se podría usar BCOVPlaybackSessionConsumer
para crear un complemento de análisis:
class XYZAnalytics : NSObject , BCOVPlaybackSessionConsumer {
func playbackSession ( _ session : BCOVPlaybackSession , didProgressTo progress : TimeInterval ) {
//react to progress event
}
}
Para usar el complemento:
let sdkManager = BCOVPlayerSDKManager . sharedManager ( )
let controller = sdkManager . createPlaybackController ( )
let analytics = XYZAnalytics ( )
controller . add ( analytics )
Cuando la aplicación experimenta interrupciones de la red, el AVPlayer
utilizado por BCOVPlaybackController
puede dejar de intentar recuperarse si la interrupción dura demasiado tiempo. Si esto ocurre, se llamará al método de delegado de ciclo de vida con un evento kBCOVPlaybackSessionLifecycleEventFailedToPlayToEndTime
. Cuando ocurre este evento, la reproducción no se recuperará automáticamente. Para recuperarse de este evento, deberá detectar cuándo la red se recupera en el código de su cliente.
Una vez que haya determinado que la red se ha recuperado, puede usar playbackController.resumeVideo(at:withAutoPlay:)
para reinicializar el reproductor. Deberá realizar un seguimiento de dónde desea reanudar. El jugador hará su mejor esfuerzo para suprimir los eventos del ciclo de vida y los eventos de progreso, para evitar que los anuncios se repitan o se interfieran los análisis.
Al llamar playbackController.resumeVideo(at:withAutoPlay:)
, el jugador enviará un evento de ciclo de vida de tipo kBCOVPlaybackSessionLifecycleEventResumeBegin
. kBCOVPlaybackSessionLifecycleEventResumeComplete
se enviará si esta acción tiene éxito, de lo contrario se enviará kBCOVPlaybackSessionLifecycleEventResumeFail
.
Debe esperar antes de llamar playbackController.resumeVideo(at:withAutoPlay:)
una segunda vez hasta que haya recibido kBCOVPlaybackSessionLifecycleEventResumeComplete
o kBCOVPlaybackSessionLifecycleEventResumeFail
de la llamada anterior. Es posible que desee imponer un límite de reintento, antes de darle al usuario un mensaje de que su red es demasiado inestable.
Cuando el AVPlayer
aún puede acceder a la red, pero el video se detiene porque la red es demasiado lenta, el método delegado del ciclo de vida se llamará con un evento kBCOVPlaybackSessionLifecycleEventPlaybackStalled
. Cuando la reproducción puede reanudarse, el método de delegado del ciclo de vida se llamará con un evento kBCOVPlaybackSessionLifecycleEventPlaybackRecovered
. Estos eventos solo cubren el caso en el que la reproducción normal se detuvo y no cubre el búfer que ocurre durante una búsqueda o carga inicial del video.
Cuando el video se carga inicialmente, cuando ocurre una búsqueda, o cuando se detiene la reproducción debido a una red lenta, el método delegado del ciclo de vida se llamará con un evento kBCOVPlaybackSessionLifecycleEventPlaybackBufferEmpty
. Cuando la reproducción puede reanudarse, el método delegado del ciclo de vida se llamará con un evento kBCOVPlaybackSessionLifecycleEventPlaybackLikelyToKeepUp
.
Excepto cuando se documente explícitamente de lo contrario, ninguna de las clases en el SDK del jugador para iOS está diseñada para ser subclase. La creación de una subclase de cualquier clase SDK que no esté explícitamente diseñada para ser subclase, especialmente cualquiera de las clases de valor, podría dar lugar a un comportamiento impredecible.
También conocido como "objetos modelo", estas clases ( BCOVPlaylist
, BCOVVideo
, BCOVSource
, BCOVCuePoint
, BCOVCuePointCollection
) se utilizan para representar datos en el SDK del reproductor para iOS. Es crucial comprender que estos tipos de datos se tratan como valores , en lugar de identidades . Con esto, queremos decir que si tiene dos instancias de una clase de valor que tienen exactamente los mismos datos, representan la misma idea o valor, a pesar de que son técnicamente dos objetos diferentes en direcciones de memoria separadas. En otras palabras, ni el código SDK ni el código de su cliente deben usar comparaciones de identidad ("igualdad de puntero") con objetos de valor. En su lugar, cada clase de valor implementa -isEqual:
y proporciona una sobrecarga de método de igualdad específico de clase, cualquiera de los cuales debe usarse en su lugar.
Esto es malo:
if myVideo == session . video // Could lead to bugs!
Estos son buenos (y funcionalmente equivalentes):
if myVideo . isEqual ( session . video )
if myVideo . isEqual ( toVideo : session . video )
Las partes internas del jugador SDK para iOS pueden hacer cosas como los valores de memo o hacer copias defensivas, por lo que confiar en la dirección del puntero para verificar la igualdad terminará causando su dolor.
Otra calidad de clases de valor en el SDK del jugador para iOS es que son inmutables . Una vez que tenga una instancia de valor, no debe intentar subvertir esta inmutabilidad de ninguna manera, ya que puede conducir a un comportamiento impredecible. Si en su código desea "modificar" un valor de alguna manera, su único recurso es crear un nuevo valor. Como conveniencia para ayudar a los clientes a obtener valores "modificados", cada una de las clases de valor ofrece un método -update:
toma un bloque que le permite operar con una copia mutable del valor original.
Aquí hay un ejemplo de uso de este método para crear una versión "modificada" de un objeto de video existente, pero con diferentes propiedades:
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
Como puede ver en el ejemplo, video1
no ha sido cambiado por la llamada del método -update
. En cambio, este método devuelve una copia de video1
, excepto con las modificaciones realizadas en el cuerpo del bloque. Nunca debe permitir que la copia mutable escape del bloque (como asignarlo a una variable __block
), en su lugar, use el objeto inmutable devuelto por el método -update
después de haber realizado sus modificaciones.
La clase de servicio de reproducción, BCOVPlaybackService
, proporciona funcionalidad para recuperar sus activos de video Brightcove y listas de reproducción a través de la API de reproducción de BrightCove, incluidos metadatos ricos como pistas de texto, vistas previas y miniaturas. El siguiente ejemplo muestra cómo recuperar un video con una identificación de video. Los métodos para recuperar un video o lista de reproducción con la identificación de referencia de ese video también están 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 ( )
}
}
Nota: Si está utilizando el servicio de autorización de reproducción, revise la sección de este README relacionado con esa función.
Para los métodos BCOVPlaybackService
que devuelven una lista de reproducción, puede solicitar una lista de reproducción parcial o "páginas" de la lista de reproducción especificando un parámetro límite y compensación en el diccionario de parámetros. El límite especifica el número máximo de videos que se devolverán, y el desplazamiento especifica el índice en la lista de reproducción en la que se devolverán los videos.
Por ejemplo, si tiene una lista de reproducción con 100 videos, puede solicitar solo 6 videos a partir del video número 10 de la siguiente manera:
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 ( )
}
}
El objeto BCOVPlaybackController
se construye con una estrategia de vista, que le permite, como cliente del SDK, definir el objeto UIView exacto que se devuelve de la propiedad de vista del controlador de reproducción. Esto es importante al usar complementos que afectan la vista del controlador de reproducción, como un complemento publicitario que superpone la vista de video con una vista de anuncios. Muchas aplicaciones no tendrán necesidad de crear una estrategia de vista, y simplemente pueden pasar nil
al crear un nuevo controlador de reproducción. Esto creará una vista de video estándar en el controlador de reproducción.
BCOVPlaybackControllerViewStrategy
typedef aliases (y documentos) Esta firma de bloque más compleja:
UIView *(^)(UIView *videoView, id playbackController);
Esta firma describe un bloque Objective-C que devuelve un UIView y toma dos parámetros: un UIView y un controlador de reproducción. El valor de retorno es el objeto UIView que apuntará la propiedad de vista del controlador de reproducción. El primer parámetro es un UIView que contiene la capa de video, el UIView mostrará el video. El segundo parámetro es el objeto del controlador de reproducción al que se ha dado la estrategia de vista, el controlador de reproducción puede usarse para agregar a los consumidores de sesión necesarios, como controles de video o controles de anuncios.
Ejemplo de una implementación de la estrategia de vista:
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
}
Desglosando el código en pasos: [1] Cree una vista de controles personalizados que se ajuste al protocolo BCOVPlaybackSessionConsumer
. El protocolo BCOVPlaybackSessionConsumer
permite recibir información básica de reproducción para cada video además de la publicidad. [2] Cree una vista de contenedor para la vista de video y los controles personalizados. [3] Agregue como subvisión del contenedor de video y los controles personalizados. La jerarquía se compone en el mismo orden en que se agregan vistas. [4] Cree una vista de anuncios que se ajuste al protocolo BCOVPlaybackSessionConsumer
. [5] Cree una vista de contenedor para la vista y los controles de video, y la vista publicitaria. [6] Agregue como subvisión del contenedor de video y la vista de control de anuncios. [7] Registre la vista de controles personalizados y la vista de control de anuncios como consumidores de sesión utilizando el objeto del controlador de reproducción devuelto por el bloque.
Hay una advertencia para usar una estrategia de vista: no debe acceder a la propiedad view
del controlador de reproducción desde el bloque de estrategia de vista. Dado que se llama al bloque porque se accedió a la propiedad view
del controlador de reproducción por primera vez, acceder a la propiedad view
nuevamente dentro del bloque de estrategia View hará que su programa se bloquee.
Por defecto, cuando se envía una aplicación iOS al fondo o el dispositivo está bloqueado, iOS detendrá cualquier video que se esté reproduciendo. Para cambiar este comportamiento, establezca la propiedad de allowsBackgroundAudioPlayback
del objeto BCOVPlaybackController
a true
. (El valor predeterminado es false
, lo que indica que la reproducción se detendrá en segundo plano).
También debe seguir las pautas establecidas por Apple en QA1668 técnicas para establecer los modos de fondo adecuados y la categoría de sesión de audio para su aplicación.
Es importante que el AVPlayerLayer
se separe del AVPlayer
antes de que la aplicación se cambie al fondo (y vuelva a colocar cuando la aplicación vuelve al primer plano). El SDK de BrightCove Player manejará esto para usted cuando allowsBackgroundAudioPlayback
se establece en true
.
Finalmente, al reproducir videos de fondo (y particularmente cuando usa listas de reproducción), debe usar la API iOS MPRemoteCommandCenter
para dar al control de reproducción del usuario en la pantalla de bloqueo y en el centro de control.
Para habilitar la imagen en la imagen en su aplicación, establezca la propiedad showPictureInPictureButton
del objeto BCOVPUIPlayerViewOptions
en true
al instanciar su objeto BCOVPUIPlayerView
. El botón de imagen en imagen se mostrará en la barra de controles en cualquier dispositivo que lo admita.
Para que la imagen en la imagen funcione correctamente, deberá asegurarse de que el Audio, AirPlay, and Picture in Picture
se gire en la sección Background Modes
de la pestaña Capacidades de destino de su proyecto. También debe seguir las pautas establecidas por Apple en QA1668 técnicas para establecer los modos de fondo adecuados y la categoría de sesión de audio para su aplicación.
Los métodos AVPictureInPictureControllerDelegate
se pasan a través de BCOVPUIPlayerViewDelegate
. Estos métodos son:
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 )
Consulte la documentación AVPICTureInpictureControllerDelegate de Apple para obtener más información.
Para implementar su propio comportamiento de imagen en la imagen, deje la propiedad de allowsBackgroundAudioPlayback
de BCOVPlaybackController
establecida en false
, y mantenga la propiedad pictureInPictureActive
de BCOVPlaybackController
actualizada con el estado de imagen en el estado. Si está utilizando AVPictureInPictureController
, puede usar pictureInPictureControllerDidStartPicture(inPicture:)
y pictureInPictureControllerDidStopPicture(inPicture:)
Delegate Methods para actualizar esta propiedad.
Puede leer más sobre implementar la imagen en la imagen en la imagen de adopción de Apple en la imagen en una documentación de reproductor personalizado.
El uso de una lista de reproducción de videos con formatos mixtos con imagen en imagen dará como resultado que el cierre de la ventana de imagen en imagen entre cada video.
iOS y iPados 14 introdujo un comportamiento automático de imagen en imagen que se puede activar/desactivar en Settings > General > Picture in Picture
. Para que esta característica funcione como se esperaba, la vista del jugador debe ser igual al ancho de la pantalla y la altura debe tener una relación de al menos 0.57 al ancho (16: 9 o más). Si el ancho o la altura de la vista de su reproductor son más pequeñas que estos valores, la imagen en la imagen puede no activarse automáticamente cuando la aplicación ingresa al fondo.
Importante: los complementos IMA, Freewheel, Pulse y SSAI manejan la funcionalidad de imagen en imagen de manera diferente. Revise la sección Imagen en imagen en cada ReadMe de complemento para obtener información adicional.
La búsqueda en miniatura permite a los usuarios arrastrar la cabeza de juego a lo largo de la línea de tiempo y ver las miniaturas como una vista previa del contenido asociado. Esto brinda a los usuarios la capacidad de navegar rápidamente un archivo de video y encontrar el contenido que les interesa.
Apple también hace referencia a esta característica como un juego de trucos, y se hace referencia en su especificación de autor de HLS.
Esta función está habilitada de forma predeterminada. Si desea deshabilitar la búsqueda de miniatura, puede hacerlo estableciendo la propiedad thumbnailSeekingEnabled
en su BCOVPlaybackController
en false
.
playbackController . thumbnailSeekingEnabled = false
Puede personalizar el diseño de la vista previa de miniatura haciendo uso de un método delegado con su BCOVPUIPlayerView
o BCOVTVPlayerView
.
En iOS puedes ajustar la altura, el ancho y el desplazamiento 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 )
}
En TVOS puedes ajustar la altura y el ancho:
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 construye manualmente un objeto BCOVVideo
, puede establecer la URL para que se use para la fuente de la miniatura webvtt:
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 búsqueda en miniatura solo está disponible para videos en línea; Los videos descargados/fuera de línea no admiten esta función.
Puede insertar un bcovVideo adicional, después de otro bcovVideo que ya está en la cola, en su BCOVPlaybackController
llamando insertVideo:afterVideoAtIndex:
.
Por ejemplo:
// This will insert the new video after the first video in the queue
playbackController . insert ( videoToInsert , afterVideoAt : 0 )
Hay dos métodos delegados que puede utilizar para que se les alerte sobre el éxito o el fracaso de la solicitud.
func playbackController(_ controller: BCOVPlaybackController, didInsert video: BCOVVideo, at index: UInt)
func playbackController(_ controller: BCOVPlaybackController, failedToInsert video: BCOVVideo)
La concurrencia de transmisión genérica (GSC) es un servicio que determina si la reproducción está permitida en función de las sesiones de reproducción activa para el espectador y un límite de concurrencia preestablecido. El servicio se solicita a través del servicio de autorización de reproducción de borde (EPA). El mismo JWT utilizado para recuperar el video se usa aquí, y debe incluir un reclamo uid
, un reclamo climit
y, opcionalmente, un reclamo sid
. Esta característica debe estar habilitada en su ACCCount.
La concurrencia de flujo genérico no está habilitada en el SDK de forma predeterminada. Si desea habilitarlo, establezca la propiedad streamConcurrencyEnabled
de su BCOVPlaybackController
en true
.
playbackController . streamConcurrencyEnabled = true
El valor sid
se puede incluir en el JWT o enviado como una opción BCOVPlaybackController
, que son opcionales. El valor sid
en el JWT tiene precedencia sobre la opción BCOVPlaybackController
.
playbackController . options [ kBCOVAuthHeartbeatPropertyKeySessionId ] = " sessionId "
Se ha agregado un nuevo método de delegado a BCOVPlaybackControllerDelegate
para recuperar las sesiones activas cuando se ha alcanzado el límite de concurrencia.
func playbackController ( _ controller : BCOVPlaybackController ,
playbackSession session : BCOVPlaybackSession ,
didReachMaxConcurrency sessions : [ AnyHashable : Any ] ) {
print ( " ( sessions ) " )
}
Los errores de reproducción generalmente se manejan e informan a través de eventos de reproducción de video del controlador de reproducción. Si necesita profundizar y rastrear problemas con videos particulares o sesiones de aplicaciones, puede aprovechar la ID de sesión de SDK de BrightCove Player SDK. La identificación de la sesión es una propiedad del BCOVPlayerSDKManager
que puede recuperar así:
let sdkSessionID = BCOVPlayerSDKManager . sharedManager ( ) . sessionID
La ID de sesión es una cadena única que no cambia durante el ciclo de vida de la aplicación. Esta cadena se informa con varios otros datos de análisis a los servidores de métricas BrightCove. Si tiene problemas con una instancia de aplicación en particular, o video, puede grabar la ID de sesión y enviarla de nuevo a sus propios servidores de empresas. Luego puede enviar la ID de sesión, la ID de video y cualquier otro datos pertinentes a los ingenieros de servicios de BrightCove para ayudar a diagnosticar cualquier problema.
Si necesita combinar complementos SDK de reproductor, por ejemplo, para agregar subtítulos a un video protegido por DRM que reproduce anuncios administrados por Google IMA, BCOVSessionProviders
de cada complemento se crean y encadenan y la cadena se usa para construir el 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 )
Los desarrolladores tienen control sobre el tamaño del búfer de reproducción delantero utilizado por el AVPlayer
. Esto se hace estableciendo la propiedad preferredForwardBufferDuration
en la clase AVPlayerItem
.
De manera predeterminada, el SDK del jugador nativo de BrightCove establece la propiedad preferredForwardBufferDuration
de una manera que optimiza el ancho de banda general sin sacrificar la calidad de reproducción. Este comportamiento puede ser anulado con sus propios valores.
Todos pagan el ancho de banda, por lo que es importante reducir el consumo de ancho de banda sin afectar la calidad de la reproducción. Nuevo con la versión 5.2.0, el SDK del jugador nativo de BrightCove administra el tamaño del búfer para usted dinámicamente a medida que se reproduce el video.
Antes de iOS 10, el AVPlayer
amortiguó tantos datos de video como sea posible, hasta alrededor de 50 megabytes. Esto está bien para el modelo de visualización de videos donde un usuario selecciona un video y luego lo mira hasta el final, pero muchas aplicaciones modernas ahora se "burla" de los videos con Autoplay, con la esperanza de asegurar el compromiso después de unos segundos. Muchos usuarios simplemente pasan a diferentes videos. Con el búfer agresivo, puede terminar con varios minutos de video buffado que se tiran con cada impresión de video.
El SDK del reproductor nativo de BrightCove aborda este problema al comenzar el video con un pequeño búfer de línea de base, y luego aumentarlo a medida que el usuario ve más el video. Después de cierto punto, el tamaño del búfer está limitado ya que no es práctico o útil para hacerlo demasiado grande.
Si desea mantener el comportamiento predeterminado del SDK del jugador nativo de BrightCove, pero modifique los valores mínimos y máximos utilizados para los tamaños de búfer, puede hacer lo siguiente al configurar el 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
}
Estas opciones deben configurarse antes de llamar playbackController.setVideos()
.
Valores min
y max
:
AVPlayer
puede amortiguar los datos que nunca se ve.AVPlayerItem
que le dice al AVPlayer
que determine su propio tamaño de búfer.Si no desea que ninguna optimización de búfer activa en su sesión de reproducción actual, puede usar la misma técnica, pero establecer el método de optimización en "ninguno" de la siguiente manera:
// 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
}
Con el método establecido en .none
, iOS mantendrá el control total del tamaño del búfer hacia adelante.
Si desea establecer su propio tamaño de búfer para la reproducción, primero desactive la optimización del búfer como se describe en la sección anterior. Luego, puede implementar el siguiente método de delegado BCOVPlaybackController
:
func playbackController ( _ controller : BCOVPlaybackController , didAdvanceTo session : BCOVPlaybackSession ) {
if let currentItem = session . player . currentItem {
// Set your preferredForwardBufferDuration value here.
currentItem . preferredForwardBufferDuration = newPreferredForwardBufferDurationValue
}
}
Si desea cambiar dinámicamente el tamaño del búfer con el tiempo, puede configurar session.player.currentItem.preferredForwardBufferDuration
en el método de delegado de progreso de BCOVPlaybackController
de manera similar:
func playbackController ( _ controller : BCOVPlaybackController , playbackSession session : BCOVPlaybackSession , didProgressTo progress : TimeInterval ) {
if let currentItem = session . player . currentItem {
// Set your preferredForwardBufferDuration value here.
currentItem . preferredForwardBufferDuration = newPreferredForwardBufferDurationValue
}
}
Nota: Apple pone específicamente "preferido" en preferredForwardBufferDuration
porque puede establecer cualquier valor que desee, pero en general, el reproductor AVPlayer
lo usará solo como una guía. También tenga en cuenta que configurarlo en cero devuelve el control completo del tamaño del búfer al AVPlayer
.
Puede usar el avplayerviewController en lugar del avplayerlayer utilizado por la clase bcovplaybacksession. El uso del AvPlayViewController permite al reproductor usar los controles de reproductor iOS y TVOS nativos, pero hay limitaciones en este enfoque (ver más abajo).
Para usar el AVPlayViewController, puede establecer una propiedad del diccionario BcovPlayBackController llamada 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
}
El valor predeterminado de KbcovavplayViewControllerCompatibilityKey es false
, lo que significa que un BCovPlayBackController creado sin esta propiedad de diccionario establecida explícitamente utilizará el AVPlayerLayer de BcovplayBacksession de forma predeterminada.
Los complementos de AD de BrightCove IMA, Freewheel, Pulse y SSAI son compatibles cuando se usan AVPlayerviewController. Puede usar el contentOverlayView
de AvplayViewController para la vista en la que se muestra anuncios (no aplicables a SSAI).
Es posible que desee ocultar/mostrar los controles de reproducción de AvplayViewController antes y después de los anuncios que juegan:
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
}
Cuando use un AVPlayerviewController con el complemento y anuncios de BrightCove IMA con un botón "Obtenga más información", necesitará crear una UIView adicional para usar como Vista de contenedor AD. Esto se debe a que contentOverlayView
de AvplayerviewController no es interactivo, por lo que intentar tocar el botón "Aprender más" no tendrá efecto. Puede usar el playbackController:playbackSession:didEnterAdSequence:
y playbackController:playbackSession:didExitAdSequence:
Delegate Methods para mostrar y ocultar la vista de su contenedor de anuncios.
Si usa los complementos IMA, FreeWheel, Pulse o SSAI en TVOS, se creará una matriz de AVInterstitialTimeRange
para cada punto de señalización de anuncios y se establecerá en el interstitialTimeRanges
de AVPlayerItem
asociado. Para los complementos IMA, Freewheel y Pulse, querrá crear un gesto de reproducción/pausa para que cuando un anuncio esté activo pueda pausar y reanudar correctamente el anuncio y no afectar la reproducción del video en sí. Aquí hay un ejemplo:
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
}
Para mostrar una superposición de anuncios, como una cuenta regresiva, consulte la sección de soporte AVPlayerviewController del ReadMe de complemento AD que está utilizando para obtener alguna orientación.
Tenga en cuenta que la compatibilidad de AVPlayerViewController
de Ssai es específica para los TVOS debido a la disponibilidad de AVInterstitialTimeRange
. Todavía podrá reproducir en iOS, sin embargo, la duración del video incluirá la duración de todos los anuncios.
Tenemos proyectos de muestra que demuestran el uso de AvPlayViewController con el SDK de BrightCove IOS. Puede encontrar el proyecto de muestra de iOS aquí y el proyecto de muestra TVOS aquí.
Cuando se usa AvPlayViewController, los eventos de Video_Gagement enviados al servidor de Analytics BrightCove informarán 0 para Player_Width y Player_Height.
Si está utilizando el servicio de autorización de reproducción, deberá utilizar el servicio de reproducción BCOVPlaybackService.ConfigurationKeyAuthToken
Clave de configuración.
// 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
...
}
Nota: En el caso de las listas de reproducción, todos los videos de la lista de reproducción deben usar la misma token. En un lanzamiento posterior, será posible asignar un token diferente a cada video en una lista de reproducción. Usted será responsable de mantener el mapeo entre ID de video y token.
VoiceOver es compatible fuera de la caja para los controles de reproducción. De manera predeterminada, si la voz en off está habilitada, la vista de control BCOVPLAYERUI no oculta automáticamente. El uso del gesto de activación de voz en off de doble toque en la vista del controlador de reproducción alternará la visibilidad de la vista de control. Hay un accessibilityHint
asociado que se establece en la vista del controlador de reproducción. El accessibilityLabel
de cada control de Bcovplayerui se puede personalizar dentro de su aplicación.
Para cambiar los valores accessibilityLabel
de cualquiera de los botones en la vista de control, debe establecer un objeto para que sea un BCOVPUIButtonAccessibilityDelegate
así:
playerView . controlsView . setButtonsAccessibilityDelegate ( self )
Luego debe hacer que ese objeto se ajuste al protocolo BCOVPUIButtonAccessibilityDelegate
implementando el - (NSString *)accessibilityLabelForButton:(BCOVPUIButton *)button isPrimaryState:(BOOL)isPrimaryState
Method similar a este:
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 se devuelve un valor nil
, se utilizará el valor predeterminado.
Establecer el accessibilityHint
en el controlador de reproducción se puede hacer así:
playbackController . view . accessibilityHint = " Double tap to show or hide controls "
Del mismo modo, puede establecer el accessibilityLabel
en las etiquetas de tiempo y duración actuales, junto con el control deslizante de progreso, así:
playerView . controlsView . durationLabel . accessibilityLabelPrefix = " Total Time "
playerView . controlsView . currentTimeLabel . accessibilityLabelPrefix = " Current Time "
playerView . controlsView . progressSlider . accessibilityLabel = " Timeline "
Puede proporcionar localizaciones de idiomas adicionales que el SDK de BrightCove IOS no admite fuera de la caja.
+
debajo de la sección "Localizaciones". Para definir un dominio proxy para los servicios de reproducción, los servidores de métricas y análisis en China, establezca la propiedad chinaProxyDomain
de BCOVGlobalConfiguration
Singleton a un nombre de dominio totalmente calificado. Por ejemplo:
BCOVGlobalConfiguration . sharedConfig . chinaProxyDomain = " host.mydomain.com "
Asegúrese de establecer el nombre de dominio proxy antes de usar cualquier otro servicio del SDK del jugador nativo. Consulte la referencia de la clase BCovGlobalConfiguration para más detalles.
Dependiendo de cómo necesite su aplicación para realizar cuando se trata de reproducción de audio, puede configurar avaudiosession para satisfacer sus necesidades específicas. Por ejemplo, si desea admitir AirPlay 2 y varias rutas de audio, consulte la sección AirPlay de este ReadMe.
Se puede configurar una avaudiosión básica de esta manera:
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
}
Esta configuración generalmente se puede realizar en application:didFinishLaunchingWithOptions:
Method. Puede haber situaciones en las que necesite una configuración de avaudiosession más sofisticada, por ejemplo, si desea permitir que el audio de otras aplicaciones se escuche cuando el audio en su aplicación está silenciado. En esta situación, puede configurar la avaudiosession en el controlador de vista que tiene acceso a su AVPlayer actual. Por ejemplo:
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! ) " )
}
}
El código de muestra se puede encontrar en nuestro proyecto de muestra VideocloudBasicPlayer.
Puedes leer más sobre avaudiosession aquí.
El SDK de BrightCove Player admite transmisiones solo de audio e incluye algunas funciones de solo audio. Si ha configurado una imagen de póster para su video, esa imagen se mostrará en el contentOverlayView
de su BCOVPUIPlayerView
. Puede ajustar el UIViewContentMode
de la vista de imagen del póster utilizando la propiedad contentModeForPosterImage
en BCOVPUIPlayerViewOptions
, el valor predeterminado es UIViewContentModeScaleAspectFit
.
También es posible que desee mantener visibles los controles de reproductor en todo momento, en ese caso, puede habilitar keepControlsVisible
en BCOVPUIPlayerViewOptions
.
Si no desea mostrar la imagen del póster o simplemente desea una vista de reproducción más compacta, puede establecer la altura de su vista principal BCOVPUIPlayerView
a una altura de 88 PT para un diseño compacto (<450 pt) o una altura de 44 pt para un diseño estándar.
Hay tres diseños de BCOVPUIBasicControlView
de audio prefigurados que puede usar si no está utilizando automaticControlTypeSelection
:
basicControlViewWithAODLayout
basicControlViewWithLiveAudioLayout
basicControlViewWithLiveDVRAudioLayout
También puede ser notificado si una transmisión es solo de audio o video+audio con el Método de Delegado 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
}
}
Nuestro VideocloudBasicPlayer tiene soporte para mostrar la información de los medios en la pantalla de bloqueo, el centro de control y a través de AirPlay. Vea la clase NowPlayingHandler
para los detalles de implementación.
Un parachoques de video es un activo corto, generalmente 10 segundos o menos, que se reproduce antes de todos los demás medios y generalmente muestra la marca o empresa que representa su video. Un jugador solicitará un parachoques de la API de reproducción como cualquier otro video e lo insertará antes de los anuncios y el contenido.
Los parachoques son una característica a nivel de jugador, lo que significa que un jugador determinado solo puede estar asociado con un solo parachoques. Las listas de reproducción comparten el mismo video de parachoques. Hay dos formas de configurar un reproductor para reproducir un video de parachoques:
bumperID
. La identificación del video para encontrar. // 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
...
}
El campo bumper_id
se puede definir en campos personalizados en Videocloud/Studio. El bumper_id
se puede usar sin las firmas previamente definidas. El bumper_id
debe ser una ID de video válida.
Nota: el bumperid pasó a través de los campos personalizados (campo bumper_id
) tiene prioridad sobre cualquier identificación en el servicio de reproducción.
Los controles de reproducción se pueden ocultar mientras el parachoques está jugando.
let options = BCOVPUIPlayerViewOptions ( )
options . automaticControlTypeSelection = true
options . showBumperControls = false
let playerView = BCOVPUIPlayerView ( playbackController : nil , options : options , controlsView : nil )
Si la opción automaticControlTypeSelection
se establece en true
, el diseño para el parachoques se adaptará al contenido (solo video o audio). basicControlViewWithVODLayout
y basicControlViewWithAODLayout
Los diseños están diseñados para parachoques, los diseños Live
o LiveDVR
no están disponibles. Los controles de reproducción tienen una apariencia única cuando un parachoques activo:
El soporte para la interactividad se integra en el marco Core BrightCovePlayersDK . Para obtener detalles completos sobre el uso de la interactividad con el SDK de BrochCove Native Player, consulte la Guía de interactividad.
Si el contenido se empaqueta como MP4, puede pegar la URL directamente en la mayoría de los navegadores web, y el video debe reproducirse (o descargar en su sistema de archivos, donde puede reproducirla localmente). Si el contenido está empaquetado como HLS, puede usar el reproductor Quicktime para probarlo: seleccione File -> Open Location…
y pegue en la URL de lista de reproducción .m3u8
, y el video debe reproducirse.
Este es un síntoma común de haber llamado un método principal de UIKIT o Avfoundation de un hilo de un hilo no principal. Los métodos delegados en BCOVPlaybackControllerDelegate
siempre se llaman en el hilo principal.
Este mensaje indica que la política de selección de fuente predeterminada no puede figurar qué fuente elegir. La política predeterminada selecciona la primera fuente cuyo deliveryMethod
es kBCOVSourceDeliveryHLS
("HLS"). Si no se encuentra una fuente HLS, su comportamiento de retroceso seleccionará la primera fuente cuyo deliveryMethod
es kBCOVSourceDeliveryMP4
("MP4"). Si no existe ninguna fuente con un deliveryMethod
de "HLS" o "MP4" en el video, la política seleccionará la primera fuente del video (independientemente del deliveryMethod
). Si no está satisfecho con su selección, puede usar -[BCOVPlayerSDKManager createBasicSessionProviderWithOptions:]
y pasar en una instancia de BCOVBasicSessionProviderOptions
con un conjunto de propiedades sourceSelectionPolicy
personalizada. Al crear videos y fuentes manualmente, asegúrese de que las fuentes se creen con el deliveryMethod
apropiado.
La API que controla si una aplicación emite audio en las aplicaciones de iOS es la API de avaudiosession. Una sesión de audio es global para una aplicación, lo que significa que su configuración afecta tanto a los sonidos que emiten los AVPlayers creados por el SDK del reproductor, así como otros sonidos que una aplicación puede producir. Dado que el SDK del reproductor no puede saber cómo la aplicación quiere configurada la sesión de audio para esos otros sonidos, no afecta en absoluto la sesión de audio. Esto significa que, a menos que configure explícitamente la sesión de audio de su aplicación de lo contrario, herede el comportamiento predeterminado de suprimir todos y cada uno de los audio cuando el dispositivo está silenciado, incluido el audio emitido por 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.