├── .gitignore ├── DAI ├── BasicDAIPlayer-iOS │ ├── BasicDAIPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicDAIPlayer │ │ ├── AppDelegate.swift │ │ ├── AssetKeyViewController.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── BaseViewController.swift │ │ ├── Info.plist │ │ └── VideoPropertiesViewController.swift │ └── Podfile ├── BasicDAIPlayer-tvOS │ ├── BasicDAIPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicDAIPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile └── README.md ├── FairPlay └── BasicFairPlayPlayer-iOS │ ├── BasicFairPlayPlayer.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── BasicFairPlayPlayer.xcscheme │ ├── BasicFairPlayPlayer │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── Brightcove.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── iOS │ │ │ ├── BrightcoveLogo.imageset │ │ │ │ ├── BrightcoveLogo.png │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── arrow.down.circle.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── arrow.down.circle.svg │ │ │ ├── arrow.down.left.and.arrow.up.right.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── arrow.down.left.and.arrow.up.right.svg │ │ │ ├── arrow.triangle.circlepath.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── arrow.triangle.2.circlepath.svg │ │ │ ├── arrow.up.right.and.arrow.down.left.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── arrow.up.right.and.arrow.down.left.svg │ │ │ ├── captions.bubble.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── captions.bubble.svg │ │ │ ├── checkmark.circle.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── checkmark.circle.svg │ │ │ ├── exclamationmark.circle.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── exclamationmark.circle.svg │ │ │ ├── gear.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── gear.svg │ │ │ ├── multiply.circle.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── multiply.circle.svg │ │ │ ├── pause.circle.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── pause.circle.svg │ │ │ ├── pause.fill.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── pause.fill.svg │ │ │ ├── play.fill.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── play.fill.svg │ │ │ ├── play.square.stack.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── play.square.stack.svg │ │ │ └── square.and.arrow.down.symbolset │ │ │ │ ├── Contents.json │ │ │ │ └── square.and.arrow.down.svg │ │ └── tvOS.brandassets │ │ │ ├── App Icon - App Store.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ ├── Background.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ ├── BrightcoveLogo.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── App Icon.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ ├── Background@1x.png │ │ │ │ │ ├── Background@2x.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ ├── BrightcoveLogo@1x.png │ │ │ │ │ ├── BrightcoveLogo@2x.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Top Shelf Image Wide.imageset │ │ │ ├── Contents.json │ │ │ ├── TopShelfImageWide@1x.png │ │ │ └── TopShelfImageWide@2x.png │ │ │ └── Top Shelf Image.imageset │ │ │ ├── Contents.json │ │ │ ├── TopShelfImage@1x.png │ │ │ └── TopShelfImage@2x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ └── Podfile ├── Freewheel ├── BasicFreeWheelPlayer-iOS │ ├── BasicFreeWheelPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicFreeWheelPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile └── README.md ├── GoogleCast ├── BasicCastPlayer │ ├── BasicCastPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicCastPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── BasicCastPlayer.entitlements │ │ ├── GCKUICastContainerViewController+extensions.swift │ │ ├── GoogleCastManager.swift │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── Podfile │ └── README.md └── BrightcoveCastReceiver │ ├── BrightcoveCastReceiver.xcodeproj │ └── project.pbxproj │ ├── BrightcoveCastReceiver │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── GCKUICastContainerViewController+extensions.swift │ ├── Info.plist │ └── ViewController.swift │ ├── Podfile │ └── README.md ├── IMA ├── BasicIMAPlayer-iOS │ ├── BasicIMAPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicIMAPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── BCOVVideo+Helpers.swift │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── BaseViewController.swift │ │ ├── Info.plist │ │ ├── VASTOMViewController.swift │ │ ├── VASTViewController.swift │ │ ├── VMAPViewController.swift │ │ ├── ar.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── de.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── es.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── fr.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── ja.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── ko.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── zh-Hans.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ └── zh-Hant.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ └── Podfile ├── NativeControlsIMAPlayer-tvOS │ ├── NativeControlsIMAPlayer.xcodeproj │ │ └── project.pbxproj │ ├── NativeControlsIMAPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile └── README.md ├── Offline ├── OfflinePlayer │ ├── OfflinePlayer.xcodeproj │ │ └── project.pbxproj │ ├── OfflinePlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── BCOVOfflineVideoStatus+Extensions.swift │ │ ├── BCOVVideo+Extensions.swift │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── DownloadManager.swift │ │ ├── DownloadsViewController.swift │ │ ├── Info.plist │ │ ├── Notifications.swift │ │ ├── SettingsViewController.swift │ │ ├── UIAlertController+Extensions.swift │ │ ├── UIDevice+Extensions.swift │ │ ├── UITabBarController+Extensions.swift │ │ ├── UITableViewCell+Extensions.swift │ │ ├── VideoManager.swift │ │ ├── VideoTableViewCell.swift │ │ └── VideosViewController.swift │ └── Podfile └── README.md ├── Omniture ├── BasicOmniturePlayer │ ├── BasicOmniturePlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicOmniturePlayer │ │ ├── ADBMobileConfig.json │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── BasicOmniturePlayer-Bridging-Header.h │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile └── README.md ├── Player ├── AppleTV │ ├── AppleTV.xcodeproj │ │ └── project.pbxproj │ ├── AppleTV │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SampleInfoViewController.swift │ │ ├── ViewController.swift │ │ ├── ar.lproj │ │ │ └── Main.strings │ │ ├── de.lproj │ │ │ └── Main.strings │ │ ├── es.lproj │ │ │ └── Main.strings │ │ ├── fr.lproj │ │ │ └── Main.strings │ │ ├── ja.lproj │ │ │ └── Main.strings │ │ ├── ko.lproj │ │ │ └── Main.strings │ │ ├── zh-Hans.lproj │ │ │ └── Main.strings │ │ └── zh-Hant.lproj │ │ │ └── Main.strings │ └── Podfile ├── CustomControls │ ├── CustomControls.xcodeproj │ │ └── project.pbxproj │ ├── CustomControls │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── ClosedCaptionMenuController.swift │ │ ├── ControlsViewController.swift │ │ ├── ControlsViewController.xib │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── Podfile │ └── README.md ├── DVRLive │ ├── DVRLive.xcodeproj │ │ └── project.pbxproj │ ├── DVRLive │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── Podfile │ └── README.md ├── NativeControls │ ├── NativeControls.xcodeproj │ │ └── project.pbxproj │ ├── NativeControls │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── Podfile │ └── README.md ├── SubtitleRendering │ ├── Podfile │ ├── SubtitleRendering.xcodeproj │ │ └── project.pbxproj │ └── SubtitleRendering │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── SubtitleManager.swift │ │ └── ViewController.swift ├── TableViewPlayer │ ├── Podfile │ ├── TableViewPlayer.xcodeproj │ │ └── project.pbxproj │ └── TableViewPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── VideoTableViewCell.swift │ │ └── ViewController.swift ├── VerticalPlayer │ ├── VerticalPlayer.xcodeproj │ │ └── project.pbxproj │ └── VerticalPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── BCOVPageViewController.swift │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── VideoViewController.swift ├── Video360 │ ├── Podfile │ ├── README.md │ ├── Video360Player.xcodeproj │ │ └── project.pbxproj │ └── Video360Player │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift ├── VideoCloudBasicPlayer │ ├── Podfile │ ├── README.md │ ├── VideoCloudBasicPlayer.xcodeproj │ │ └── project.pbxproj │ └── VideoCloudBasicPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── NowPlayingHandler.swift │ │ ├── ViewController.swift │ │ ├── ar.lproj │ │ └── Main.strings │ │ ├── de.lproj │ │ └── Main.strings │ │ ├── es.lproj │ │ └── Main.strings │ │ ├── fr.lproj │ │ └── Main.strings │ │ ├── ja.lproj │ │ └── Main.strings │ │ ├── ko.lproj │ │ └── Main.strings │ │ ├── zh-Hans.lproj │ │ └── Main.strings │ │ └── zh-Hant.lproj │ │ └── Main.strings └── VideoPreloading │ ├── Podfile │ ├── VideoPreloading.xcodeproj │ └── project.pbxproj │ └── VideoPreloading │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── VideoPreloadManager.swift │ └── ViewController.swift ├── PlayerUI ├── Flutter │ ├── FlutterPlayer.xcodeproj │ │ └── project.pbxproj │ ├── FlutterPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── BCOVFlutterPlugin.swift │ │ ├── BCOVThumbnailManager.swift │ │ ├── BCOVVideoPlayer.swift │ │ ├── BCOVVideoPlayerFactory.swift │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Podfile │ ├── README.md │ └── flutter_bcov │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── lib │ │ ├── main.dart │ │ └── src │ │ │ ├── controls_widget.dart │ │ │ ├── player_controller.dart │ │ │ ├── player_view_widget.dart │ │ │ └── viewmodel.dart │ │ └── pubspec.yaml ├── PlayerUICustomization │ ├── PlayerUICustomization.xcodeproj │ │ └── project.pbxproj │ ├── PlayerUICustomization │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── ControlViewStyles.swift │ │ ├── CustomLayouts.swift │ │ ├── Info.plist │ │ ├── ViewController.swift │ │ └── fontello.ttf │ └── Podfile ├── ReactNative │ ├── .eslintrc.js │ ├── .nvmrc │ ├── .prettierrc.js │ ├── App.tsx │ ├── README.md │ ├── app.json │ ├── babel.config.js │ ├── index.js │ ├── ios │ │ ├── Podfile │ │ ├── ReactNativePlayer.xcodeproj │ │ │ ├── project.pbxproj │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── ReactNativePlayer.xcscheme │ │ └── ReactNativePlayer │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ ├── BCOVThumbnailManager.swift │ │ │ ├── BCOVVideoPlayer.swift │ │ │ ├── BCOVVideoPlayerManager.h │ │ │ ├── BCOVVideoPlayerManager.m │ │ │ ├── BCOVVideoPlayerManager.swift │ │ │ ├── Base.lproj │ │ │ └── LaunchScreen.storyboard │ │ │ ├── Info.plist │ │ │ └── ReactNativePlayer-Bridging-Header.h │ ├── metro.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── BCOVVideoPlayer.tsx │ │ ├── Controls.tsx │ │ └── VideoPlayer.tsx │ └── tsconfig.json └── ViewStrategy │ ├── Podfile │ ├── README.md │ ├── ViewStrategy.xcodeproj │ └── project.pbxproj │ └── ViewStrategy │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.swift │ └── ViewStrategyCustomControls.swift ├── Pulse ├── BasicPulsePlayer-iOS │ ├── BasicPulsePlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicPulsePlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── BCOVPulseVideoItem.swift │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── Library.json │ │ └── ViewController.swift │ └── Podfile ├── BasicPulsePlayer-tvOS │ ├── BasicPulsePlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicPulsePlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── BasicPulsePlayer-Bridging-Header.h │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile └── README.md ├── README.md ├── SSAI ├── BasicSSAIPlayer-iOS │ ├── BasicSSAIPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicSSAIPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ ├── ViewController.swift │ │ ├── ar.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── de.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── es.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── fr.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── ja.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── ko.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ ├── zh-Hans.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ │ └── zh-Hant.lproj │ │ │ ├── LaunchScreen.strings │ │ │ └── Main.strings │ ├── Podfile │ └── README.md ├── BasicSSAIPlayer-tvOS │ ├── BasicSSAIPlayer.xcodeproj │ │ └── project.pbxproj │ ├── BasicSSAIPlayer │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift │ └── Podfile ├── SLS+IMA-iOS │ ├── Podfile │ ├── SLS_IMA-Player.xcodeproj │ │ └── project.pbxproj │ └── SLS_IMA-Player │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── ViewController.swift └── SLS+IMA-tvOS │ ├── Podfile │ ├── SLS_IMA-Player.xcodeproj │ └── project.pbxproj │ └── SLS_IMA-Player │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── SharePlay ├── Podfile ├── SharePlayPlayer.xcodeproj │ └── project.pbxproj └── SharePlayPlayer │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SharePlayPlayer.entitlements │ ├── ViewController.swift │ ├── WatchTogether.swift │ └── WatchTogetherWrapper.swift ├── SidecarSubtitles └── BasicSidecarSubtitlesPlayer-iOS │ ├── BasicSidecarSubtitlesPlayer.xcodeproj │ └── project.pbxproj │ ├── BasicSidecarSubtitlesPlayer │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ └── Podfile └── SwiftUI ├── CustomControls-iOS ├── CustomControls.xcodeproj │ └── project.pbxproj ├── CustomControls │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── CustomControls.swift │ ├── Double+Extensions.swift │ ├── Info.plist │ ├── Models │ │ ├── PlayerModel.swift │ │ ├── ThumbnailManager.swift │ │ ├── ThumbnailModel.swift │ │ └── VideoModel.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── TimeInterval+Extensions.swift │ ├── UISlider+Extensions.swift │ └── Views │ │ ├── ContentView.swift │ │ ├── CustomControlsView.swift │ │ ├── CustomSliderView.swift │ │ ├── PlayerUIView.swift │ │ ├── ThumbnailView.swift │ │ └── VideoContainerView.swift └── README.md └── SwiftUIPlayer-iOS ├── SwiftUIPlayer.xcodeproj └── project.pbxproj └── SwiftUIPlayer ├── AppDelegate.swift ├── Assets.xcassets ├── Base.lproj └── LaunchScreen.storyboard ├── ImageLoader.swift ├── Info.plist ├── Models ├── PlayerModel.swift ├── PlaylistModel.swift └── VideoListItem.swift ├── Preview Content └── Preview Assets.xcassets │ └── Contents.json ├── SwiftUIPlayer.swift ├── TimeInterval+Extensions.swift └── Views ├── ApplePlayerUIView.swift ├── BCOVPlayerUIView.swift ├── ContentView.swift ├── ThumbnailView.swift ├── VideoDetailView.swift ├── VideoListRowView.swift └── VideoListView.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | .DS_Store 3 | 4 | # Xcode 5 | # 6 | build/ 7 | derivedData/ 8 | clonedSourcePackages/ 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | *.xccheckout 19 | *.moved-aside 20 | DerivedData 21 | *.hmap 22 | *.ipa 23 | *.xcuserstate 24 | 25 | *.xcframework 26 | *.framework 27 | 28 | # CocoaPods 29 | # 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | **/Pods/ 35 | Podfile.lock 36 | *.xcworkspace 37 | 38 | # Flutter 39 | .dart_tool/ 40 | .packages 41 | .metadata 42 | .pub/ 43 | .idea/ 44 | .vagrant/ 45 | .sconsign.dblite 46 | .svn/ 47 | build/ 48 | .android/ 49 | .ios/ 50 | .flutter-plugins 51 | .flutter-plugins-dependencies 52 | app.*.symbols 53 | app.*.map.json 54 | pubspec.lock 55 | 56 | # React Native 57 | node_modules/ 58 | yarn.lock 59 | .yarn 60 | .xcode* 61 | *.xcprivacy 62 | 63 | # Yarn 64 | .yarn/* 65 | !.yarn/patches 66 | !.yarn/plugins 67 | !.yarn/releases 68 | !.yarn/sdks 69 | !.yarn/versions 70 | -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-iOS/BasicDAIPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicDAIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-iOS/BasicDAIPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-iOS/BasicDAIPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | NSUserTrackingUsageDescription 50 | This identifier will be used to deliver personalized ads to you. 51 | 52 | -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | # source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | source 'git@tcmac04.vidmark.local:preflight/BrightcoveSpecs.git' 4 | 5 | platform :ios, '14.0' 6 | 7 | use_frameworks! 8 | 9 | target 'BasicDAIPlayer' do 10 | pod 'Brightcove-Player-DAI/XCFramework' 11 | end -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-tvOS/BasicDAIPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicDAIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-tvOS/BasicDAIPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-tvOS/BasicDAIPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | NSUserTrackingUsageDescription 41 | This identifier will be used to deliver personalized ads to you. 42 | 43 | 44 | -------------------------------------------------------------------------------- /DAI/BasicDAIPlayer-tvOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicDAIPlayer' do 9 | pod 'Brightcove-Player-DAI/XCFramework' 10 | end -------------------------------------------------------------------------------- /DAI/README.md: -------------------------------------------------------------------------------- 1 | DAI 2 | -------------- 3 | 4 | The Brightcove DAI plugin integrates the Brightcove player with Google's Interactive Media Ads (IMA). This allows you to make a stream request for ad and content video—either VOD or live content. 5 | 6 | The Brightcove DAI plugin supports Google Ads IMA SDK 3.23.0 for iOS and 4.13.0 for tvOS. 7 | 8 | ### Requirements: 9 | 10 | - Xcode 13+ 11 | - iOS 14.0+ 12 | - tvOS 14.0+ 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicFairPlayPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemBlueColor" 7 | }, 8 | "idiom" : "universal" 9 | }, 10 | { 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "color" : { 18 | "color-space" : "srgb", 19 | "components" : { 20 | "alpha" : "1.000", 21 | "blue" : "1.000", 22 | "green" : "1.000", 23 | "red" : "1.000" 24 | } 25 | }, 26 | "idiom" : "universal" 27 | } 28 | ], 29 | "info" : { 30 | "author" : "xcode", 31 | "version" : 1 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/AppIcon.appiconset/Brightcove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/AppIcon.appiconset/Brightcove.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Brightcove.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/BrightcoveLogo.imageset/BrightcoveLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/BrightcoveLogo.imageset/BrightcoveLogo.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/BrightcoveLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "BrightcoveLogo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/arrow.down.circle.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "arrow.down.circle.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/arrow.down.left.and.arrow.up.right.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "arrow.down.left.and.arrow.up.right.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/arrow.triangle.circlepath.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "arrow.triangle.2.circlepath.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/arrow.up.right.and.arrow.down.left.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "arrow.up.right.and.arrow.down.left.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/captions.bubble.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "captions.bubble.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/checkmark.circle.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "checkmark.circle.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/exclamationmark.circle.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "exclamationmark.circle.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/gear.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "gear.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/multiply.circle.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "multiply.circle.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/pause.circle.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "pause.circle.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/pause.fill.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "pause.fill.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/play.fill.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "play.fill.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/play.square.stack.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "play.square.stack.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/iOS/square.and.arrow.down.symbolset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "symbols" : [ 7 | { 8 | "filename" : "square.and.arrow.down.svg", 9 | "idiom" : "universal" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Background.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Background.png", 5 | "idiom" : "tv" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "layers" : [ 7 | { 8 | "filename" : "Front.imagestacklayer" 9 | }, 10 | { 11 | "filename" : "Middle.imagestacklayer" 12 | }, 13 | { 14 | "filename" : "Back.imagestacklayer" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "BrightcoveLogo.png", 5 | "idiom" : "tv" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Background@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Background@1x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Background@2x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Background@1x.png", 5 | "idiom" : "tv", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "Background@2x.png", 10 | "idiom" : "tv", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | }, 6 | "layers" : [ 7 | { 8 | "filename" : "Front.imagestacklayer" 9 | }, 10 | { 11 | "filename" : "Middle.imagestacklayer" 12 | }, 13 | { 14 | "filename" : "Back.imagestacklayer" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo@1x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/BrightcoveLogo@2x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "BrightcoveLogo@1x.png", 5 | "idiom" : "tv", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "BrightcoveLogo@2x.png", 10 | "idiom" : "tv", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "tv", 9 | "scale" : "2x" 10 | } 11 | ], 12 | "info" : { 13 | "author" : "xcode", 14 | "version" : 1 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "filename" : "App Icon - App Store.imagestack", 5 | "idiom" : "tv", 6 | "role" : "primary-app-icon", 7 | "size" : "1280x768" 8 | }, 9 | { 10 | "filename" : "App Icon.imagestack", 11 | "idiom" : "tv", 12 | "role" : "primary-app-icon", 13 | "size" : "400x240" 14 | }, 15 | { 16 | "filename" : "Top Shelf Image Wide.imageset", 17 | "idiom" : "tv", 18 | "role" : "top-shelf-image-wide", 19 | "size" : "2320x720" 20 | }, 21 | { 22 | "filename" : "Top Shelf Image.imageset", 23 | "idiom" : "tv", 24 | "role" : "top-shelf-image", 25 | "size" : "1920x720" 26 | } 27 | ], 28 | "info" : { 29 | "author" : "xcode", 30 | "version" : 1 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TopShelfImageWide@1x.png", 5 | "idiom" : "tv", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "TopShelfImageWide@2x.png", 10 | "idiom" : "tv", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image Wide.imageset/TopShelfImageWide@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image Wide.imageset/TopShelfImageWide@1x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image Wide.imageset/TopShelfImageWide@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image Wide.imageset/TopShelfImageWide@2x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "TopShelfImage@1x.png", 5 | "idiom" : "tv", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "TopShelfImage@2x.png", 10 | "idiom" : "tv", 11 | "scale" : "2x" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image.imageset/TopShelfImage@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image.imageset/TopShelfImage@1x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image.imageset/TopShelfImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/FairPlay/BasicFairPlayPlayer-iOS/BasicFairPlayPlayer/Assets.xcassets/tvOS.brandassets/Top Shelf Image.imageset/TopShelfImage@2x.png -------------------------------------------------------------------------------- /FairPlay/BasicFairPlayPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicFairPlayPlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Freewheel/BasicFreeWheelPlayer-iOS/BasicFreeWheelPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicFreeWheelPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Freewheel/BasicFreeWheelPlayer-iOS/BasicFreeWheelPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Freewheel/BasicFreeWheelPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicFreeWheelPlayer' do 9 | pod 'Brightcove-Player-FreeWheel/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Freewheel/README.md: -------------------------------------------------------------------------------- 1 | # Basic FreeWheel Player 2 | 3 | The FreeWheel AdManager SDK is not installed by CocoaPods; You must manually add it to the application target of your project. It can be downloaded from the [FreeWheel website](https://hub.freewheel.tv/display/techdocs/AdManager+SDK+Integration+Downloads). 4 | 5 | _Ensure that you are using the "AdManager Dynamic Build" version of AdManager._ 6 | 7 | To add the AdManager xcframework to the BasicFreeWheelPlayer sample project 8 | 9 | 1. cd to `ios-player-samples/FreeWheel/BasicFreeWheelPlayer-iOS` and install the Brightcove Player CocoaPods by running the following from the command line. 10 | 11 | ```sh 12 | pod install 13 | ``` 14 | 15 | 1. Open the BasicFreeWheelPlayer.xcworkspace document. 16 | 17 | 1. In the Project Navigator, expand the BasicFreeWheelPlayer project. 18 | 19 | 1. In Finder, select your `AdManager.xcframework` and drag it to the Frameworks group in the Xcode Project Navigator. When prompted, ensure that the AdManager.xcframework is being added to the BasicFreeWheelPlayer target. 20 | 21 | 1. In Xcode under "Frameworks, Libraries and Dmbedded Content" set AdManager.xcframework to "Embed & Sign". 22 | 23 | 1. In the Project Navigator, select the BasicFreeWheelPlayer project. At the top of the Xcode Editor Area, choose Build Settings. Search for "Framework Search Paths". Add a framework search path that is the parent folder of your AdManager.framework (probably `iOS_AdManagerDistribution`). 24 | -------------------------------------------------------------------------------- /GoogleCast/BasicCastPlayer/BasicCastPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /GoogleCast/BasicCastPlayer/BasicCastPlayer/BasicCastPlayer.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.networking.wifi-info 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GoogleCast/BasicCastPlayer/BasicCastPlayer/GCKUICastContainerViewController+extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCKUICastContainerViewController+extensions.swift 3 | // BasicCastPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import GoogleCast 9 | 10 | 11 | extension GCKUICastContainerViewController { 12 | 13 | open override var prefersStatusBarHidden: Bool { 14 | 15 | guard let navigationController = contentViewController as? UINavigationController, 16 | let viewController = navigationController.viewControllers.first else { 17 | return false 18 | } 19 | 20 | return viewController.prefersStatusBarHidden 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /GoogleCast/BasicCastPlayer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicCastPlayer' do 9 | pod 'Brightcove-Player-GoogleCast/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /GoogleCast/BasicCastPlayer/README.md: -------------------------------------------------------------------------------- 1 | # Basic Cast Player 2 | 3 | At this time Brightcove GoogleCast plugin does **not** support DRM or ads and only supports `HLSv3`, `DASH` and `MP4` source types. If you need to support any additional features, source types or want to customize anything else related to casting with Google's SDK you can use the `GoogleCastManager` class included in the `BasicCastPlayer` sample app. 4 | -------------------------------------------------------------------------------- /GoogleCast/BrightcoveCastReceiver/BrightcoveCastReceiver/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /GoogleCast/BrightcoveCastReceiver/BrightcoveCastReceiver/GCKUICastContainerViewController+extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GCKUICastContainerViewController+extensions.swift 3 | // BrightcoveCastReceiver 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import GoogleCast 9 | 10 | 11 | extension GCKUICastContainerViewController { 12 | 13 | open override var prefersStatusBarHidden: Bool { 14 | 15 | guard let navigationController = contentViewController as? UINavigationController, 16 | let viewController = navigationController.viewControllers.first else { 17 | return false 18 | } 19 | 20 | return viewController.prefersStatusBarHidden 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /GoogleCast/BrightcoveCastReceiver/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BrightcoveCastReceiver' do 9 | pod 'Brightcove-Player-GoogleCast/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /GoogleCast/BrightcoveCastReceiver/README.md: -------------------------------------------------------------------------------- 1 | # Brightcove Cast Receiver 2 | 3 | The Brightcove Cast Receiver uses the new Cast Application Framework (CAF) SDK. The Brightcove Cast Receiver supports DRM protected videos, SSAI and `HLSv3` or superior. 4 | 5 | The application ID for the Brightcove CAF Receiver is `341387A3` and is assigned to the constant `kBCOVCAFReceiverApplicationID`. You can verify the application ID by checking the [CAF Receiver config.json](https://players.brightcove.net/videojs-chromecast-receiver/2/config.json). 6 | 7 | **NOTE: When using the Brightcove Cast Receiver app with the Brightcove Native SDKs, you must send the `catalogParams` object via the `customData` interface. A static URL is not supported. If you are correctly utilizing the `BCOVReceiverAppConfig` class this is handled for you.** 8 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicIMAPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | NSUserTrackingUsageDescription 50 | This identifier will be used to deliver personalized ads to you. 51 | 52 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ar.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ar.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/de.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/de.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/es.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/es.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/fr.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/fr.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ja.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ko.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/ko.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/zh-Hant.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicIMAPlayer"; ObjectID = "4aF-Lm-psZ"; */ 3 | "4aF-Lm-psZ.text" = "BasicIMAPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2020, Brightcove, Inc. All rights reserved."; ObjectID = "Fhi-95-o93"; */ 6 | "Fhi-95-o93.text" = "Copyright © 2020, Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/BasicIMAPlayer/zh-Hant.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "VMAP (Ad Rules) Configuration"; ObjectID = "276-Sq-GCW"; */ 3 | "276-Sq-GCW.normalTitle" = "VMAP (Ad Rules) Configuration"; 4 | 5 | /* Class = "UIButton"; normalTitle = "VAST Configuration"; ObjectID = "dNk-00-Kst"; */ 6 | "dNk-00-Kst.normalTitle" = "VAST Configuration"; 7 | -------------------------------------------------------------------------------- /IMA/BasicIMAPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicIMAPlayer' do 9 | pod 'Brightcove-Player-IMA/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /IMA/NativeControlsIMAPlayer-tvOS/NativeControlsIMAPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NativeControlsIMAPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /IMA/NativeControlsIMAPlayer-tvOS/NativeControlsIMAPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /IMA/NativeControlsIMAPlayer-tvOS/NativeControlsIMAPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | NSUserTrackingUsageDescription 41 | This identifier will be used to deliver personalized ads to you. 42 | 43 | 44 | -------------------------------------------------------------------------------- /IMA/NativeControlsIMAPlayer-tvOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'NativeControlsIMAPlayer' do 9 | pod 'Brightcove-Player-IMA/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /IMA/README.md: -------------------------------------------------------------------------------- 1 | IMA 2 | -------------- 3 | 4 | The Brightcove IMA plugin integrates the Brightcove player with Google's Interactive Media Ads (IMA). This allows you to request and track VAST and VMAP ads for your player. 5 | 6 | The Brightcove IMA plugin supports Google Ads IMA SDK 3.23.0 for iOS and 4.13.0 for tvOS. 7 | 8 | ### Requirements: 9 | 10 | - Xcode 13+ 11 | - iOS 14.0+ 12 | - tvOS 14.0+ 13 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // OfflinePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/Notifications.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Notifications.swift 3 | // OfflinePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | struct OfflinePlayerNotifications { 12 | 13 | static let UpdateStatus = Notification.Name(rawValue: "UpdateStatus") 14 | } 15 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/UIAlertController+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIAlertController+Extensions.swift 3 | // OfflinePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension UIAlertController { 12 | 13 | class func showWith(title: String, 14 | message: String) { 15 | UIAlertController.showWith(title: title, 16 | message: message, 17 | actionTitle: "OK", 18 | cancelTitle: nil, 19 | completion: nil) 20 | } 21 | 22 | class func showWith(title: String, 23 | message: String, 24 | actionTitle: String, 25 | cancelTitle: String?, 26 | completion: (() -> Void)?) { 27 | 28 | let alert = UIAlertController(title: title, 29 | message: message, 30 | preferredStyle: .alert) 31 | 32 | alert.addAction(UIAlertAction(title: actionTitle, 33 | style: .default) { (action: UIAlertAction) in 34 | if let completion { 35 | completion() 36 | } 37 | }) 38 | 39 | if let cancelTitle { 40 | alert.addAction(UIAlertAction(title: cancelTitle, 41 | style: .cancel, 42 | handler: nil)) 43 | } 44 | 45 | guard let window = UIApplication.shared.keyWindow, 46 | let rootViewController = window.rootViewController else { 47 | return 48 | } 49 | 50 | rootViewController.present(alert, animated: true) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/OfflinePlayer/UITableViewCell+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+Extensions.swift 3 | // OfflinePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension UITableViewCell { 12 | 13 | var parentViewController: UIViewController? { 14 | 15 | var parentResponder: UIResponder? = self 16 | 17 | while parentResponder != nil { 18 | parentResponder = parentResponder!.next 19 | if let viewController = parentResponder as? UIViewController { 20 | return viewController 21 | } 22 | } 23 | 24 | return nil 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Offline/OfflinePlayer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'OfflinePlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Offline/README.md: -------------------------------------------------------------------------------- 1 | Offline Player 2 | -------------- 3 | 4 | The Brightcove Native Player SDK allows you to download and play back HLS videos, including those protected with FairPlay encryption. Downloaded videos can be played back with or without a network connection. 5 | 6 | ### Requirements: 7 | 8 | - iOS 12.0+ 9 | - Brightcove Native Player SDK v6.7.6+ 10 | - Brightcove Account with Dynamic Delivery 11 | 12 | iOS does **not** allow FairPlay-protected video to display in a simulator, nor does it allow video downloads to a simulator, so it's important to develop on an actual device. 13 | 14 | ### Reference: 15 | 16 | See ["iOS App Developer's Guide to Video Downloading and Offline Playback with HLS in the Brightcove Player SDK for iOS"](https://github.com/brightcove/brightcove-player-sdk-ios/blob/master/OfflinePlayback.md) for details. 17 | -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/BasicOmniturePlayer/ADBMobileConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "version" : "1.0", 3 | "analytics" : { 4 | "rsids" : "", 5 | "server" : "", 6 | "charset" : "UTF-8", 7 | "ssl" : true, 8 | "offlineEnabled" : false, 9 | "lifecycleTimeout" : 300, 10 | "referrerTimeout" : 0, 11 | "batchLimit" : 0, 12 | "privacyDefault" : "optedin", 13 | "backdateSessionInfo" : false, 14 | "poi" : [] 15 | }, 16 | "target" : { 17 | "clientCode" : "", 18 | "timeout" : 5 19 | }, 20 | "audienceManager" : { 21 | "server" : "", 22 | "analyticsForwardingEnabled": false 23 | }, 24 | "acquisition" : { 25 | "server" : "", 26 | "appid" : "" 27 | } 28 | } -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/BasicOmniturePlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicOmniturePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/BasicOmniturePlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/BasicOmniturePlayer/BasicOmniturePlayer-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "ADBMobile.h" 6 | #import "ADBMediaHeartbeat.h" 7 | #import "ADBMediaHeartbeatConfig.h" 8 | -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/BasicOmniturePlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Omniture/BasicOmniturePlayer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicOmniturePlayer' do 9 | pod 'Brightcove-Player-Omniture/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Omniture/README.md: -------------------------------------------------------------------------------- 1 | # Basic Omniture Player 2 | 3 | ### ADBMobileConfig.json 4 | 5 | Use of this player sample requires an Adobe Analytics account and the custom ADBMobileConfig.json file associated with that account. For this player sample to run correctly, you must replace the included sample ADBMobileConfig.json file with your own. 6 | 7 | ### Adobe SDKs 8 | 9 | The Adobe Analytics SDKs are **not** included in this sample project. To fetch the Adobe Marketing Cloud libraries, download the following archives, unzip them and add them to your project directory: 10 | 11 | ``` 12 | https://github.com/Adobe-Marketing-Cloud/media-sdks/archive/refs/tags/ios-v2.3.0.zip 13 | https://github.com/Adobe-Marketing-Cloud/mobile-services/archive/refs/tags/v4.21.2-iOS.zip 14 | ``` 15 | 16 | ### Brightcove SDKs 17 | 18 | Next, install the CocoaPods. 19 | 20 | ``` 21 | pod install 22 | ``` 23 | 24 | Open, build and run `BasicOmniturePlayer.xcworkspace`. 25 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AppleTV 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/ar.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/de.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/es.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/fr.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/ko.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/AppleTV/zh-Hant.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/AppleTV/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'AppleTV' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/CustomControls/CustomControls/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/CustomControls/CustomControls/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/CustomControls/CustomControls/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Player/CustomControls/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'CustomControls' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/CustomControls/README.md: -------------------------------------------------------------------------------- 1 | # Custom Controls App 2 | 3 | This sample is intended to show you how to use your own custom playback controls with the Brightcove-Player-SDK. One advantage to using Brightcove's `BCOVPUIPlayerView` is that you get VoiceOver support out of the box. If you implement your own custom controls you will be responsible for providing accessiblity support. 4 | 5 | This sample also demonstrates how to set up a custom Audio & Subtitles menu to allow users to select alternate audio and text tracks for a video. When the current `BCOVPlaybackSession` is set on `ClosedCaptionMenuController` the `closedCaptionButton` on `ControlsViewController` will be enabled or disabled depending on the availability of text and/or audio tracks. 6 | 7 | You may wish to add `accessibilityLabel` values to each of your buttons in addition to preventing playback controls from auto-hiding when VoiceOver is active, in addition to implementing the `func accessibilityActivate() -> Bool` in your custom control's view so that you can hide or show controls when a user double taps with VoiceOver enabled. 8 | 9 | For more information about implementing accessibility and VoiceOver support for your project see Apple's [Supporting VoiceOver in Your App](https://developer.apple.com/documentation/uikit/accessibility_for_ios_and_tvos/supporting_voiceover_in_your_app). 10 | -------------------------------------------------------------------------------- /Player/DVRLive/DVRLive/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DVRLive 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/DVRLive/DVRLive/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/DVRLive/DVRLive/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Player/DVRLive/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'DVRLive' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/DVRLive/README.md: -------------------------------------------------------------------------------- 1 | DVR Live Sample 2 | ==================== 3 | 4 | ##Purpose 5 | This sample is intended to show how to quickly integrate the Brightcove Native Player SDK into an iOS app with live HLS. 6 | 7 | ### How to Run 8 | To run the app, run `pod install` from the root directory. This will install all the required Cocoapods for the project. When finished, open `DVRLive.xcworkspace`. 9 | 10 | This sample doesn't include a live HLS demo URL. You will need to add one to the project manually. 11 | -------------------------------------------------------------------------------- /Player/NativeControls/NativeControls/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NativeControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/NativeControls/NativeControls/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/NativeControls/NativeControls/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Player/NativeControls/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'NativeControls' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/NativeControls/README.md: -------------------------------------------------------------------------------- 1 | Native Controls Sample 2 | ===================================== 3 | 4 | This sample demonstrates the use of Apple's AVPlayerViewController in place of the Player UI controls provided by the _Brightcove Native Player SDK for iOS_. 5 | -------------------------------------------------------------------------------- /Player/SubtitleRendering/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'SubtitleRendering' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/SubtitleRendering/SubtitleRendering/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SubtitleRendering 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/SubtitleRendering/SubtitleRendering/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/SubtitleRendering/SubtitleRendering/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Player/TableViewPlayer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'TableViewPlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/TableViewPlayer/TableViewPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TableViewPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/TableViewPlayer/TableViewPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/TableViewPlayer/TableViewPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Player/VerticalPlayer/VerticalPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VerticalPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/VerticalPlayer/VerticalPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/VerticalPlayer/VerticalPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Player/Video360/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'Video360Player' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/Video360/README.md: -------------------------------------------------------------------------------- 1 | #Video 360 Player Sample App 2 | ##Purpose 3 | 4 | This sample app shows how to retrieve and play a 360 video. 5 | 6 | The code for retrieving and playing the video is the same as any other code that retrieves and plays a video from Video Cloud. 7 | 8 | What makes this code different is the use of the `BCOVPUIPlayerViewDelegate` delegate method `func didSetVideo360NavigationMethod(_ navigationMethod: BCOVPUIVideo360NavigationMethod,projectionStyle: BCOVVideo360ProjectionStyle)` This method is called when the Video 360 button is tapped, and indicates that you probably want to set the device orientation to landscape if the projection method has changed to VR Goggles mode. 9 | 10 | The sample code shows how to handle changing the device orientation when that delegate is called. 11 | -------------------------------------------------------------------------------- /Player/Video360/Video360Player/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Video360Player 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/Video360/Video360Player/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/Video360/Video360Player/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'VideoCloudBasicPlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/README.md: -------------------------------------------------------------------------------- 1 | # Basic Video Playback App 2 | 3 | This sample is intended to show how to quickly integrate the Brightcove Player SDK into an iOS app. It will cover: 4 | 5 | * Creating a playback controller 6 | * Requesting a playlist from the Video Cloud Playback API 7 | * Getting new-session and progress notifications through delegate methods 8 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VideoCloudBasicPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | @UIApplicationMain 12 | final class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, 17 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | return true 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/ar.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/de.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/es.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/fr.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/ko.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoCloudBasicPlayer/VideoCloudBasicPlayer/zh-Hant.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Player/VideoPreloading/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'VideoPreloading' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Player/VideoPreloading/VideoPreloading/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VideoPreloading 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Player/VideoPreloading/VideoPreloading/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Player/VideoPreloading/VideoPreloading/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/FlutterPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /PlayerUI/Flutter/FlutterPlayer/BCOVFlutterPlugin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVFlutterPlugin.swift 3 | // FlutterPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import Flutter 10 | 11 | 12 | final class BCOVFlutterPlugin: NSObject, FlutterPlugin { 13 | 14 | static func register(with registrar: FlutterPluginRegistrar) { 15 | registrar.register(BCOVVideoPlayerFactory(), withId: "bcov.flutter/player_view") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/FlutterPlayer/BCOVVideoPlayerFactory.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVVideoPlayerFactory.swift 3 | // FlutterPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import Flutter 10 | import BrightcovePlayerSDK 11 | 12 | 13 | final class BCOVVideoPlayerFactory: NSObject, FlutterPlatformViewFactory { 14 | 15 | func create(withFrame frame: CGRect, 16 | viewIdentifier viewId: Int64, 17 | arguments args: Any?) -> FlutterPlatformView { 18 | return BCOVVideoPlayer(frame: frame, 19 | viewId: viewId, 20 | args: args) 21 | } 22 | 23 | func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { 24 | return FlutterStandardMessageCodec.sharedInstance() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '14.0' 5 | 6 | use_frameworks! 7 | 8 | flutter_application_path = './flutter_bcov' 9 | load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') 10 | 11 | target 'FlutterPlayer' do 12 | 13 | install_all_flutter_pods(flutter_application_path) 14 | pod 'Brightcove-Player-IMA/XCFramework' 15 | 16 | post_install do |installer| 17 | flutter_post_install(installer) 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/flutter_bcov/README.md: -------------------------------------------------------------------------------- 1 | # flutter_bcov 2 | 3 | The *flutter_bcov* package contains two auxiliar classes and one widget to [display video](https://docs.flutter.dev/development/platform-integration/platform-views). 4 | 5 | ## How to use flutter_bcov 6 | 7 | ### PlaybackController 8 | 9 | The *PlaybackController* class determines the behavior of your playback controller for autoAdvance and autoPlay. The default values for both is false. 10 | 11 | ```dart 12 | PlaybackController( 13 | autoPlay: true, 14 | autoAdvance: true, 15 | ); 16 | ``` 17 | 18 | ### PlaybackService 19 | 20 | The *PlaybackService* class is used to retrieve the video to be shown in your playback controller. The *accountId* and *videoId* are the only required values. The *policyKey*, *authToken* and *parameters* are optional values. 21 | 22 | ```dart 23 | PlaybackService( 24 | accountId: '5434391461001', 25 | policyKey: 'BCpkADawqM0T8lW3nMChuAbrcunBBHmh4YkNl5e6ZrKQwPiK_Y83RAOF4DP5tyBF_ONBVgrEjqW6fbV0nKRuHvjRU3E8jdT9WMTOXfJODoPML6NUDCYTwTHxtNlr5YdyGYaCPLhMUZ3Xu61L', 26 | videoId: '6140448705001', 27 | ); 28 | ``` 29 | 30 | ### BCOVVideoPlayer 31 | 32 | The *BCOVVideoPlayer* class is the widget to be used to show the video. The class receives two paramters, *playbackController* and *playbackService*. 33 | 34 | ```dart 35 | BCOVVideoPlayer( 36 | playbackController: PlaybackController( 37 | autoPlay: true, 38 | autoAdvance: true, 39 | ), 40 | playbackService: PlaybackService( 41 | accountId: '5434391461001', 42 | policyKey: 'BCpkADawqM0T8lW3nMChuAbrcunBBHmh4YkNl5e6ZrKQwPiK_Y83RAOF4DP5tyBF_ONBVgrEjqW6fbV0nKRuHvjRU3E8jdT9WMTOXfJODoPML6NUDCYTwTHxtNlr5YdyGYaCPLhMUZ3Xu61L', 43 | videoId: '6140448705001', 44 | ), 45 | ); 46 | ``` 47 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/flutter_bcov/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/flutter_bcov/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | 4 | import 'package:flutter_bcov/src/player_controller.dart'; 5 | import 'package:flutter_bcov/src/viewmodel.dart'; 6 | 7 | /// The entrypoint for the flutter module. 8 | void main() { 9 | // This call ensures the Flutter binding has been set up before creating the 10 | // MethodChannel-based model. 11 | WidgetsFlutterBinding.ensureInitialized(); 12 | 13 | runApp( 14 | ChangeNotifierProvider.value( 15 | value: BCOVViewModel(), 16 | child: const MyApp(), 17 | ), 18 | ); 19 | } 20 | 21 | /// The "app" displayed by this module. 22 | class MyApp extends StatelessWidget { 23 | const MyApp({super.key}); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return MaterialApp( 28 | debugShowCheckedModeBanner: false, 29 | themeMode: ThemeMode.system, 30 | theme: ThemeData(useMaterial3: true, brightness: Brightness.light), 31 | darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), 32 | home: const SafeArea(child: BCOVVideoPlayer())); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/flutter_bcov/lib/src/player_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:stacked/stacked.dart'; 3 | 4 | import 'package:flutter_bcov/src/player_view_widget.dart'; 5 | import 'package:flutter_bcov/src/viewmodel.dart'; 6 | 7 | class BCOVVideoPlayer extends StatelessWidget { 8 | const BCOVVideoPlayer({super.key}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return ViewModelBuilder.reactive( 13 | viewModelBuilder: () => BCOVViewModel(), 14 | onViewModelReady: (model) => model.loadData(), 15 | builder: (context, model, child) => PlayerView( 16 | isPlaying: model.isPlaying, 17 | thumbnailURL: model.thumbnailURL, 18 | totalTime: model.totalTime, 19 | currentTime: model.currentTime, 20 | inAdSequence: model.inAdSequence, 21 | onPlatformViewCreated: (viewId) => model.onPlatformViewCreated(viewId), 22 | onHandle: (args) => model.onHandle(args), 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /PlayerUI/Flutter/flutter_bcov/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_bcov 2 | description: An example Flutter module. 3 | version: 1.0.0+1 4 | 5 | publish_to: none 6 | 7 | environment: 8 | sdk: ^3.3.1 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | provider: ^6.1.2 14 | stacked: ^3.4.2 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | flutter_lints: ^3.0.2 20 | 21 | flutter: 22 | uses-material-design: true 23 | 24 | # This section identifies your Flutter project as a module meant for 25 | # embedding in a native host app. These identifiers should _not_ ordinarily 26 | # be changed after generation - they are used to ensure that the tooling can 27 | # maintain consistency when adding or modifying assets and plugins. 28 | # They also do not have any bearing on your native host application's 29 | # identifiers, which may be completely independent or the same as these. 30 | module: 31 | iosBundleIdentifier: com.yourcompany.FlutterPlayer -------------------------------------------------------------------------------- /PlayerUI/PlayerUICustomization/PlayerUICustomization/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PlayerUICustomization 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /PlayerUI/PlayerUICustomization/PlayerUICustomization/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /PlayerUI/PlayerUICustomization/PlayerUICustomization/fontello.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BrightcoveOS/ios-player-samples/1baeb2b68c1aed4bfabcc67b370ca9b61eea62c3/PlayerUI/PlayerUICustomization/PlayerUICustomization/fontello.ttf -------------------------------------------------------------------------------- /PlayerUI/PlayerUICustomization/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'PlayerUICustomization' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/.nvmrc: -------------------------------------------------------------------------------- 1 | 18 -------------------------------------------------------------------------------- /PlayerUI/ReactNative/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {SafeAreaView, StyleSheet} from 'react-native'; 3 | import {GestureHandlerRootView} from 'react-native-gesture-handler'; 4 | import VideoPlayer from './src/VideoPlayer'; 5 | 6 | const App = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | }; 15 | 16 | const styles = StyleSheet.create({ 17 | container: { 18 | flex: 1, 19 | }, 20 | videoContainer: { 21 | width: '100%', 22 | height: '100%', 23 | }, 24 | }); 25 | 26 | export default App; 27 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/README.md: -------------------------------------------------------------------------------- 1 | # React Native 2 | 3 | Learn more about [React Native](https://reactnative.dev/). 4 | 5 | This sample shows how to integrate React Native with the Brightcove Player SDKs for iOS. The reader is expected to be familiar with both React Native and the Brightcove SDK. This sample is not a React Native tutorial and Brightcove cannot provide support for React Native. To build the React Native Sample App, the [development environment](https://reactnative.dev/docs/environment-setup) need to be set. 6 | 7 | ## Prerequisites 8 | 9 | 1. yarn 10 | 1. CocoaPods 1.10+ 11 | 1. Xcode 13.0+ 12 | 1. iOS 13.4+ 13 | 14 | ## Running Sample App 15 | 16 | 1. Install node dependencies using `yarn install`. 17 | 1. Go to _ios_ project and run the command `pod install`. 18 | 1. Start the react native server with `yarn start` script from `package.json`. 19 | 1. Open `ReactNativePlayer.xcworkspace`. 20 | 1. Run the project using simulator or physical device. 21 | 22 | ### Using the Brightcove IMA Plugin 23 | 24 | The ReactNativePlayer sample project is configured to support the IMA Plugin for Brightcove Player SDK for iOS. By default the IMA related code is commented out so that you can build the project without the IMA SDK dependency. 25 | 26 | If you wish to enable the IMA functionality you will need to uncomment the IMA specific code. 27 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactNativePlayer", 3 | "displayName": "ReactNativePlayer" 4 | } 5 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | plugins: ['react-native-reanimated/plugin'], 4 | }; 5 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/ios/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | # Resolve react_native_pods.rb with node to allow for hoisting 5 | require Pod::Executable.execute_command('node', ['-p', 6 | 'require.resolve( 7 | "react-native/scripts/react_native_pods.rb", 8 | {paths: [process.argv[1]]}, 9 | )', __dir__]).strip 10 | 11 | platform :ios, '14.0' 12 | prepare_react_native_project! 13 | 14 | linkage = ENV['USE_FRAMEWORKS'] 15 | if linkage != nil 16 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 17 | use_frameworks! :linkage => linkage.to_sym 18 | end 19 | 20 | target 'ReactNativePlayer' do 21 | 22 | config = use_native_modules! 23 | use_react_native!(:path => config[:reactNativePath],:app_path => "#{Pod::Config.instance.installation_root}/..") 24 | 25 | pod 'Brightcove-Player-IMA/XCFramework' 26 | 27 | post_install do |installer| 28 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 29 | react_native_post_install( 30 | installer, 31 | config[:reactNativePath], 32 | :mac_catalyst_enabled => false 33 | ) 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/ios/ReactNativePlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /PlayerUI/ReactNative/ios/ReactNativePlayer/BCOVVideoPlayerManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVVideoPlayerManager.h 3 | // ReactNativePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface BCOVVideoPlayerManager : RCTViewManager 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/ios/ReactNativePlayer/BCOVVideoPlayerManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVVideoPlayerManager.swift 3 | // ReactNativePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import React 10 | 11 | @objc(BCOVVideoPlayerManager) 12 | final class BCOVVideoPlayerManager: RCTViewManager { 13 | 14 | @objc 15 | override func view() -> UIView { 16 | return BCOVVideoPlayer() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/ios/ReactNativePlayer/ReactNativePlayer-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import 6 | #import 7 | #import 8 | #import 9 | #import 10 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bcov-player-react-native", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "ios": "cd ios && pod install && cd .. && react-native run-ios", 7 | "start": "react-native start --reset-cache" 8 | }, 9 | "dependencies": { 10 | "@react-native-community/slider": "^4.5.2", 11 | "react": "18.3.1", 12 | "react-native": "0.75.2", 13 | "react-native-elements": "^3.4.3", 14 | "react-native-fast-image": "^8.6.3", 15 | "react-native-gesture-handler": "^2.18.1", 16 | "react-native-reanimated": "^3.15.0", 17 | "react-native-svgkit": "^0.2.2", 18 | "react-native-vector-icons": "^10.1.0" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.20.0", 22 | "@babel/preset-env": "^7.20.0", 23 | "@babel/runtime": "^7.20.0", 24 | "@react-native-community/cli": "^15.1.1", 25 | "@react-native-community/cli-platform-ios": "^15.1.1", 26 | "@react-native/babel-preset": "0.75.2", 27 | "@react-native/eslint-config": "0.75.2", 28 | "@react-native/metro-config": "0.75.2", 29 | "@react-native/typescript-config": "0.75.2", 30 | "@types/react": "^18.2.6", 31 | "@types/react-native-vector-icons": "^6.4.18", 32 | "@types/react-slider": "^1.3.6", 33 | "@types/react-test-renderer": "^18.0.0", 34 | "eslint": "^8.19.0", 35 | "prettier": "^2.8.8", 36 | "typescript": "5.0.4" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PlayerUI/ReactNative/src/BCOVVideoPlayer.tsx: -------------------------------------------------------------------------------- 1 | import {requireNativeComponent} from 'react-native'; 2 | 3 | const BCOVVideoPlayer = requireNativeComponent('BCOVVideoPlayer'); 4 | 5 | export default BCOVVideoPlayer; 6 | -------------------------------------------------------------------------------- /PlayerUI/ViewStrategy/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'ViewStrategy' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /PlayerUI/ViewStrategy/README.md: -------------------------------------------------------------------------------- 1 | View Strategy Sample 2 | ===================================== 3 | 4 | `BCOVPlaybackController` objects are constructed with a view strategy, which allows you, as the client of the SDK, to define the exact UIView object that is returned from the playback controller’s view property. 5 | 6 | ``` 7 | func createPlaybackController(){ 8 | let sdkManager = BCOVPlayerSDKManager.sharedManager() 9 | 10 | let viewStrategy = { (videoView: UIView? , playbackController: BCOVPlaybackController) in { 11 | let myControlsView = MyControlsView() 12 | let controlsAndVideoView = UIView() 13 | videoView.frame = controlsAndVideoView.bounds 14 | controlsAndVideoView.addSubview(videoView) 15 | controlsAndVideoView.addSubview(myControlsView) 16 | playbackController.addSessionConsumer(myControlsView) 17 | 18 | // This container view will become `playbackController.view`. 19 | return controlsAndVideoView 20 | } 21 | 22 | playbackController = sdkManager.createPlaybackController(withViewStrategy: viewStrategy) 23 | 24 | playbackController.delegate = self 25 | playbackController.autoPlay = true 26 | playbackController.autoAdvance = true 27 | 28 | playbackController.view.frame = videoContainerView.bounds 29 | playbackController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 30 | 31 | videoContainerView.addSubview(playbackController.view) 32 | } 33 | ``` 34 | 35 | The `BCOVPlaybackControllerViewStrategy` layers the controls view on top of the videoView. This composed view is then passed into the `BCOVPlayerSDKManager.sharedManager().createPlaybackController(withViewStrategy: viewStrategy)` 36 | -------------------------------------------------------------------------------- /PlayerUI/ViewStrategy/ViewStrategy/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ViewStrategy 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /PlayerUI/ViewStrategy/ViewStrategy/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /PlayerUI/ViewStrategy/ViewStrategy/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/BasicPulsePlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicPulsePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/BasicPulsePlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/BasicPulsePlayer/BCOVPulseVideoItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVPulseVideoItem.swift 3 | // BasicPulsePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | final class BCOVPulseVideoItem: NSObject { 12 | 13 | fileprivate(set) var title: String? 14 | fileprivate(set) var category: String? 15 | fileprivate(set) var tags: Array? 16 | fileprivate(set) var midrollPositions: Array? 17 | fileprivate(set) var extendSession: Bool? = false 18 | 19 | static func staticInit(dictionary: [String: Any]) -> BCOVPulseVideoItem { 20 | let videoItem = BCOVPulseVideoItem() 21 | 22 | videoItem.title = dictionary["content-title"] as? String ?? "" 23 | videoItem.category = dictionary["category"] as? String 24 | videoItem.tags = dictionary["tags"] as? Array 25 | videoItem.midrollPositions = dictionary["midroll-positions"] as? Array 26 | videoItem.extendSession = dictionary["extend-session"] as? Bool 27 | 28 | return videoItem 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/BasicPulsePlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UIBackgroundModes 41 | 42 | audio 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | NSUserTrackingUsageDescription 50 | This identifier will be used to deliver personalized ads to you. 51 | 52 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/BasicPulsePlayer/Library.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "content-title": "Preroll demo.", 3 | "tags": ["standard-prerolls"] 4 | },{ 5 | "content-title": "Midroll demo", 6 | "tags": ["standard-midrolls"], 7 | "midroll-positions": [20, 40] 8 | },{ 9 | "content-title": "Postroll demo.", 10 | "tags": ["standard-postrolls"] 11 | },{ 12 | "content-title": "Pre-/mid-/postroll demo.", 13 | "tags": ["standard-linears"], 14 | "midroll-positions": [20, 40] 15 | },{ 16 | "content-title": "Pre-/mid-/postroll skippable.", 17 | "category": "skip-always", 18 | "tags": ["standard-linears"], 19 | "midroll-positions": [20, 40] 20 | },{ 21 | "content-title": "Pre-/mid-/postroll skip after first.", 22 | "category": "skip-after-first", 23 | "tags": ["standard-linears"], 24 | "midroll-positions": [20, 40] 25 | },{ 26 | "content-title": "Frequency capping demo.", 27 | "category": "frequency-capped-1min", 28 | "tags": ["standard-linears"], 29 | "midroll-positions": [20, 40] 30 | },{ 31 | "content-title": "Pause ad demo.", 32 | "tags": ["pause"] 33 | },{ 34 | "content-title": "Extend Session with midroll ads at 30th second.", 35 | "extend-session": true 36 | },{ 37 | "content-title": "Preroll demo - Ad media file invalid.", 38 | "tags": ["preroll-media-invalid"] 39 | },{ 40 | "content-title": "Preroll demo - Ad media file timeout.", 41 | "tags": ["preroll-media-timeout"] 42 | },{ 43 | "content-title": "Preroll demo - Ad media file 404.", 44 | "tags": ["preroll-media-404"] 45 | }] 46 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicPulsePlayer' do 9 | pod 'Brightcove-Player-Pulse/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-tvOS/BasicPulsePlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicPulsePlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-tvOS/BasicPulsePlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-tvOS/BasicPulsePlayer/BasicPulsePlayer-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #ifndef BasicPulsePlayer_Bridging_Header_h 2 | #define BasicPulsePlayer_Bridging_Header_h 3 | 4 | #import 5 | 6 | #endif /* BasicPulsePlayer_Bridging_Header_h */ 7 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-tvOS/BasicPulsePlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | NSUserTrackingUsageDescription 41 | This identifier will be used to deliver personalized ads to you. 42 | 43 | 44 | -------------------------------------------------------------------------------- /Pulse/BasicPulsePlayer-tvOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicPulsePlayer' do 9 | pod 'Brightcove-Player-Pulse/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /Pulse/README.md: -------------------------------------------------------------------------------- 1 | # Pulse Sample Apps 2 | 3 | The BasicPulsePlayer-iOS sample project depends on the Ooyala Pulse and INVIDI Open Measurement (OM) SDKs. Those SDKs are **not** installed by CocoaPods and must be added manually to the application target of your project. 4 | 5 | The BasicPulsePlayer-tvOS sample project depends on the Ooyala Pulse SDK for tvOS. That SDK is **not** installed by CocoaPods and must be added manually to the application target of your project. 6 | 7 | You can aquire the iOS SDKs [here](https://service.videoplaza.tv/proxy/ios-sdk/2/latest) and tvOS SDK [here](https://service.videoplaza.tv/proxy/tvos-sdk/2/latest). 8 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicSSAIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ar.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ar.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/de.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/de.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/es.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/es.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/fr.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/fr.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ja.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ko.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/ko.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/zh-Hant.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "BasicSSAIPlayer"; ObjectID = "XoZ-ZE-Hoz"; */ 3 | "XoZ-ZE-Hoz.text" = "BasicSSAIPlayer"; 4 | 5 | /* Class = "UILabel"; text = "Copyright © 2024 Brightcove, Inc. All rights reserved."; ObjectID = "eQM-Z7-Fn1"; */ 6 | "eQM-Z7-Fn1.text" = "Copyright © 2024 Brightcove, Inc. All rights reserved."; 7 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/BasicSSAIPlayer/zh-Hant.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicSSAIPlayer' do 9 | pod 'Brightcove-Player-SSAI/XCFramework' 10 | 11 | # Open Measurement 12 | # pod 'Brightcove-Player-OpenMeasurement' 13 | end 14 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-iOS/README.md: -------------------------------------------------------------------------------- 1 | SSAI 2 | -------------- 3 | 4 | The [IAB Open Measurement SDK (OM SDK)](https://iabtechlab.com/standards/open-measurement-sdk/) is no longer installed along with the SSAI Plugin for Brightcove Player SDK for iOS since v6.10.3. 5 | The current version for Open Measurement is 1.4.13. 6 | 7 | To take advantage of IAB Open Measurement, keep the following points in mind: 8 | 9 | * Add `pod 'Brightcove-Player-OpenMeasurement'` in your Podfile to include it in your project. 10 | * Provide a valid OMID Partner name using the new signature, `[BCOVPlayerSDKManager createSSAISessionProviderWithUpstreamSessionProvider:omidPartner]`. 11 | * If using VAST 4.1+, ads must be configured under `` nodes in their VAST documents per the VAST 4.1 specification; otherwise, `` should be used. 12 | * Open Measurement is not supported by MacCatalyst. 13 | 14 | ```xml 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ``` 26 | 27 | See the *Open Measurement* section of [brightcove-player-sdk-ios-ssai](https://github.com/brightcove/brightcove-player-sdk-ios-ssai#OpenMeasurement) for more information. 28 | 29 | ## PAL SDK Integration 30 | 31 | The BasicSSAIPlayer-iOS project provides an example of how to integrate the Brightcove SSAI plugin with the PAL SDK. If you want to use this integration you'll need to download the [PAL SDK XCFramework](https://developers.google.com/ad-manager/pal/ios/download) and add it to the the project and then uncomment the sections of code related to the PAL SDK. There are comments throughout the code that will help you know which code to uncomment. 32 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-tvOS/BasicSSAIPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicSSAIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-tvOS/BasicSSAIPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-tvOS/BasicSSAIPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | NSUserTrackingUsageDescription 41 | This identifier will be used to deliver personalized ads to you. 42 | 43 | 44 | -------------------------------------------------------------------------------- /SSAI/BasicSSAIPlayer-tvOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicSSAIPlayer' do 9 | pod 'Brightcove-Player-SSAI/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'SLS_IMA-Player' do 9 | pod 'Brightcove-Player-SSAI/XCFramework' 10 | pod 'Brightcove-Player-IMA/XCFramework' 11 | end 12 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-iOS/SLS_IMA-Player/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SLS_IMA-Player 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-iOS/SLS_IMA-Player/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SSAI/SLS+IMA-tvOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :tvos, '14.0' 5 | 6 | use_frameworks! 7 | 8 | target 'SLS_IMA-Player' do 9 | pod 'Brightcove-Player-SSAI/XCFramework' 10 | pod 'Brightcove-Player-IMA/XCFramework' 11 | end 12 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-tvOS/SLS_IMA-Player/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SLS_IMA-Player 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-tvOS/SLS_IMA-Player/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SSAI/SLS+IMA-tvOS/SLS_IMA-Player/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SSAI/SLS+IMA-tvOS/SLS_IMA-Player/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIBackgroundModes 32 | 33 | audio 34 | 35 | NSAppTransportSecurity 36 | 37 | NSAllowsArbitraryLoads 38 | 39 | 40 | NSUserTrackingUsageDescription 41 | This identifier will be used to deliver personalized ads to you. 42 | 43 | 44 | -------------------------------------------------------------------------------- /SharePlay/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '15.0' 5 | 6 | use_frameworks! 7 | 8 | target 'SharePlayPlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /SharePlay/SharePlayPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SharePlayPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SharePlay/SharePlayPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SharePlay/SharePlayPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIBackgroundModes 45 | 46 | audio 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /SharePlay/SharePlayPlayer/SharePlayPlayer.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.group-session 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SharePlay/SharePlayPlayer/WatchTogether.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WatchTogether.swift 3 | // SharePlayPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import GroupActivities 9 | 10 | struct WatchTogether: GroupActivity { 11 | 12 | // Specify the activity type to the system. 13 | static let activityIdentifier = "com.companyname.SharePlayPlayer.watch-movie-together" 14 | 15 | var metadata: GroupActivityMetadata 16 | var sourceURL: String 17 | var keySystems: [String: [String: String]]? 18 | 19 | } 20 | -------------------------------------------------------------------------------- /SidecarSubtitles/BasicSidecarSubtitlesPlayer-iOS/BasicSidecarSubtitlesPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BasicSidecarSubtitlesPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | 12 | @UIApplicationMain 13 | final class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, 18 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | 20 | /* 21 | Set the AVAudioSession category to allow audio playback when: 22 | 23 | 1: Silent Mode is enabled, or 24 | 2: When the app is in the background, and 25 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 26 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 27 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 28 | 29 | Refer to the AVAudioSession Class Reference: 30 | https://developer.apple.com/documentation/avfoundation/avaudiosession 31 | */ 32 | 33 | do { 34 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 35 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 36 | try AVAudioSession.sharedInstance().setCategory(.playback, 37 | mode: .moviePlayback, 38 | options: .duckOthers) 39 | } catch { 40 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 41 | } 42 | 43 | return true 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /SidecarSubtitles/BasicSidecarSubtitlesPlayer-iOS/BasicSidecarSubtitlesPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SidecarSubtitles/BasicSidecarSubtitlesPlayer-iOS/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | source 'https://github.com/brightcove/BrightcoveSpecs.git' 3 | 4 | platform :ios, '12.0' 5 | 6 | use_frameworks! 7 | 8 | target 'BasicSidecarSubtitlesPlayer' do 9 | pod 'Brightcove-Player-Core/XCFramework' 10 | end 11 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import AVFoundation 10 | 11 | 12 | final class AppDelegate: NSObject, UIApplicationDelegate { 13 | 14 | func application(_ application: UIApplication, 15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | 17 | /* 18 | Set the AVAudioSession category to allow audio playback when: 19 | 20 | 1: Silent Mode is enabled, or 21 | 2: When the app is in the background, and 22 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 23 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 24 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 25 | 26 | Refer to the AVAudioSession Class Reference: 27 | https://developer.apple.com/documentation/avfoundation/avaudiosession 28 | */ 29 | 30 | do { 31 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 32 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 33 | try AVAudioSession.sharedInstance().setCategory(.playback, 34 | mode: .moviePlayback, 35 | options: .duckOthers) 36 | } catch { 37 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 38 | } 39 | 40 | return true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/CustomControls.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomControls.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | @main 12 | struct CustomControls: App { 13 | 14 | @UIApplicationDelegateAdaptor(AppDelegate.self) 15 | var appDelegate 16 | 17 | var body: some Scene { 18 | WindowGroup { 19 | ContentView() 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Double+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Double+Extensions.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import CoreMedia 9 | import UIKit 10 | 11 | 12 | extension Double { 13 | 14 | var asCMTime: CMTime { 15 | return CMTime(seconds: self, 16 | preferredTimescale: CMTimeScale(60)) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIBackgroundModes 43 | 44 | audio 45 | 46 | NSAppTransportSecurity 47 | 48 | NSAllowsArbitraryLoads 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Models/ThumbnailModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThumbnailModel.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import CoreMedia 9 | import UIKit 10 | 11 | 12 | final class ThumbnailModel { 13 | 14 | var startTime: CMTime? 15 | var endTime: CMTime? 16 | var url: URL? 17 | } 18 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/TimeInterval+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimeInterval+Extensions.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension TimeInterval { 12 | 13 | var stringFromTime: String { 14 | if isFinite { 15 | let hours = Int(truncatingRemainder(dividingBy: 86_400) / 3_600) 16 | let minutes = Int(truncatingRemainder(dividingBy: 3_600) / 60) 17 | let seconds = Int(truncatingRemainder(dividingBy: 60)) 18 | if hours > 0 { 19 | return String(format: "%i:%02i:%02i", hours, minutes, seconds) 20 | } else { 21 | return String(format: "%02i:%02i", minutes, seconds) 22 | } 23 | } else { 24 | return "" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/UISlider+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UISlider+Extensions.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension UISlider { 12 | 13 | var trackBounds: CGRect { 14 | return trackRect(forBounds: bounds) 15 | } 16 | 17 | var trackFrame: CGRect { 18 | guard let superview else { return .zero } 19 | return convert(trackBounds, 20 | to: superview) 21 | } 22 | 23 | var thumbBounds: CGRect { 24 | return thumbRect(forBounds: frame, 25 | trackRect: trackBounds, 26 | value: value) 27 | } 28 | 29 | var thumbFrame: CGRect { 30 | return thumbRect(forBounds: bounds, 31 | trackRect: trackFrame, 32 | value: value) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Views/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | struct ContentView: View { 12 | 13 | var body: some View { 14 | VStack { 15 | PlayerUIView() 16 | .padding(.top, 8) 17 | Spacer() 18 | } 19 | } 20 | } 21 | 22 | 23 | // MARK: - 24 | 25 | #if DEBUG 26 | struct ContentView_Previews: PreviewProvider { 27 | static var previews: some View { 28 | ContentView() 29 | } 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Views/ThumbnailView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThumbnailView.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | 12 | struct ThumbnailView: View { 13 | 14 | @EnvironmentObject 15 | var playerModel: PlayerModel 16 | 17 | var body: some View { 18 | if playerModel.isShowThumbnail { 19 | if let thumbnailManager = playerModel.thumbnailManager, 20 | let image = thumbnailManager.thumbnailAtTime(playerModel.progress.asCMTime) { 21 | Image(uiImage: image) 22 | .resizable() 23 | .scaledToFit() 24 | .aspectRatio(contentMode: .fit) 25 | } else { 26 | Color 27 | .gray 28 | .opacity(0.2) 29 | .overlay(ProgressView()) 30 | } 31 | } 32 | } 33 | } 34 | 35 | 36 | // MARK: - 37 | 38 | #if DEBUG 39 | struct ThumbnailView_Previews: PreviewProvider { 40 | static var previews: some View { 41 | ThumbnailView() 42 | .clipShape(RoundedRectangle(cornerRadius: 8)) 43 | .frame(width: 100, height: 60) 44 | .environmentObject(PlayerModel()) 45 | } 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/CustomControls/Views/VideoContainerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoContainerView.swift 3 | // CustomControls 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | struct VideoContainerView: UIViewRepresentable { 12 | typealias UIViewType = UIView 13 | 14 | let view: UIView? 15 | 16 | func makeUIView(context: Context) -> UIView { 17 | return view ?? UIView(frame: .zero) 18 | } 19 | 20 | func updateUIView(_ uiView: UIView, context: Context) {} 21 | } 22 | 23 | 24 | // MARK: - 25 | 26 | #if DEBUG 27 | struct VideoContainerView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | VideoContainerView(view: UIView(frame: .zero)) 30 | .background(Color.secondary) 31 | } 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /SwiftUI/CustomControls-iOS/README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI Custom Controls 2 | 3 | The CustomControls SwiftUI sample project is configured to support the IMA Plugin for Brightcove Player SDK for iOS. By default the IMA related code is commented out so that you can build the project without the IMA SDK dependency. 4 | 5 | If you wish to enable the IMA functionality you will need to download the [IMA SDK](https://developers.google.com/interactive-media-ads/docs/sdks/ios/download), add the XCFramework to the project and uncomment the IMA specific code. 6 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | import AVFoundation 10 | 11 | 12 | final class AppDelegate: NSObject, UIApplicationDelegate { 13 | 14 | func application(_ application: UIApplication, 15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | 17 | /* 18 | Set the AVAudioSession category to allow audio playback when: 19 | 20 | 1: Silent Mode is enabled, or 21 | 2: When the app is in the background, and 22 | 2a:`allowsBackgroundAudioPlayback` is enabled on the playback controller, and/or 23 | 2b:`allowsExternalPlayback` is enabled on the playback controller, and 24 | 2c: "Audio, AirPlay, and Picture in Picture" is enabled as a Background Mode capability. 25 | 26 | Refer to the AVAudioSession Class Reference: 27 | https://developer.apple.com/documentation/avfoundation/avaudiosession 28 | */ 29 | 30 | do { 31 | // see https://developer.apple.com/documentation/avfoundation/avaudiosessioncategoryplayback 32 | // and https://developer.apple.com/documentation/avfoundation/avaudiosessionmodemovieplayback 33 | try AVAudioSession.sharedInstance().setCategory(.playback, 34 | mode: .moviePlayback, 35 | options: .duckOthers) 36 | } catch { 37 | print("AppDelegate - Error setting AVAudioSession category. Because of this, there may be no sound. \(error)") 38 | } 39 | 40 | return true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Assets.xcassets: -------------------------------------------------------------------------------- 1 | ../../../FairPlay/BasicFairPlayPlayer-iOS/swift/BasicFairPlayPlayer/Assets.xcassets -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/ImageLoader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageLoader.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | final class ImageLoader: ObservableObject { 12 | 13 | @Published 14 | var data = Data() 15 | 16 | init(urlString: String) { 17 | 18 | guard let url = URL(string: urlString) else { return } 19 | 20 | let task = URLSession.shared.dataTask(with: url) { 21 | data, response, error in 22 | 23 | guard let data else { return } 24 | 25 | DispatchQueue.main.async { [weak self] in 26 | self?.data = data 27 | } 28 | } 29 | 30 | task.resume() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDisplayName 6 | $(INFOPLIST_KEY_CFBundleDisplayName) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleName 10 | $(PRODUCT_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | CFBundleDevelopmentRegion 18 | $(DEVELOPMENT_LANGUAGE) 19 | CFBundleInfoDictionaryVersion 20 | 6.0 21 | CFBundlePackageType 22 | APPL 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIBackgroundModes 43 | 44 | audio 45 | 46 | NSAppTransportSecurity 47 | 48 | NSAllowsArbitraryLoads 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Models/VideoListItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoListItem.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import BrightcovePlayerSDK 10 | 11 | 12 | struct VideoListItem: Identifiable { 13 | let id: String 14 | let name: String 15 | let video: BCOVVideo 16 | } 17 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/SwiftUIPlayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIPlayer.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | @main 12 | struct SwiftUIPlayer: App { 13 | 14 | @UIApplicationDelegateAdaptor(AppDelegate.self) 15 | var appDelegate 16 | 17 | var body: some Scene { 18 | WindowGroup { 19 | ContentView() 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/TimeInterval+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimeInterval+Extensions.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | 11 | extension TimeInterval { 12 | 13 | var stringFromTime: String { 14 | if self.isFinite { 15 | let hours = Int(self.truncatingRemainder(dividingBy: 86400) / 3600) 16 | let minutes = Int(self.truncatingRemainder(dividingBy: 3600) / 60) 17 | let seconds = Int(self.truncatingRemainder(dividingBy: 60)) 18 | if hours > 0 { 19 | return String(format: "%i:%02i:%02i", hours, minutes, seconds) 20 | } else { 21 | return String(format: "%02i:%02i", minutes, seconds) 22 | } 23 | } else { 24 | return "" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Views/ApplePlayerUIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApplePlayerUIView.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import AVKit 9 | import SwiftUI 10 | 11 | import BrightcovePlayerSDK 12 | 13 | 14 | struct ApplePlayerUIView: UIViewControllerRepresentable { 15 | typealias UIViewControllerType = AVPlayerViewController 16 | 17 | let playerModel: PlayerModel 18 | 19 | func makeUIViewController(context: Context) -> AVPlayerViewController { 20 | if let playbackController = playerModel.playbackController { 21 | playbackController.options = [kBCOVAVPlayerViewControllerCompatibilityKey: true] 22 | } 23 | 24 | return playerModel.avpvc 25 | } 26 | 27 | func updateUIViewController(_ avpvc: AVPlayerViewController, context: Context) {} 28 | 29 | } 30 | 31 | 32 | // MARK: - 33 | 34 | #if DEBUG 35 | struct ApplePlayerUIView_Previews: PreviewProvider { 36 | static var previews: some View { 37 | let playerModel = PlayerModel() 38 | ApplePlayerUIView(playerModel: playerModel) 39 | } 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Views/BCOVPlayerUIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BCOVPlayerUIView.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | import BrightcovePlayerSDK 11 | 12 | 13 | struct BCOVPlayerUIView: UIViewRepresentable { 14 | typealias UIViewType = BCOVPUIPlayerView 15 | 16 | let playerModel: PlayerModel 17 | 18 | func makeUIView(context: Context) -> BCOVPUIPlayerView { 19 | let options = BCOVPUIPlayerViewOptions() 20 | options.automaticControlTypeSelection = true 21 | options.showPictureInPictureButton = true 22 | 23 | guard let playbackController = playerModel.playbackController, 24 | let playerView = BCOVPUIPlayerView(playbackController: playbackController, 25 | options: options, 26 | controlsView: nil) else { 27 | return BCOVPUIPlayerView() 28 | } 29 | 30 | playbackController.options = [kBCOVAVPlayerViewControllerCompatibilityKey: false] 31 | 32 | playerView.delegate = playerModel 33 | 34 | return playerView 35 | } 36 | 37 | func updateUIView(_ playerView: BCOVPUIPlayerView, context: Context) {} 38 | 39 | } 40 | 41 | 42 | // MARK: - 43 | 44 | #if DEBUG 45 | struct BCOVPlayerUIView_Previews: PreviewProvider { 46 | static var previews: some View { 47 | let playerModel = PlayerModel() 48 | BCOVPlayerUIView(playerModel: playerModel) 49 | } 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Views/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | struct ContentView: View { 12 | 13 | @State 14 | fileprivate var selection = Tab.videos 15 | 16 | @StateObject 17 | fileprivate var playerModel = PlayerModel() 18 | 19 | enum Tab { 20 | case videos 21 | case other 22 | } 23 | 24 | var body: some View { 25 | TabView(selection: $selection) { 26 | VideoListView(playerModel: playerModel) 27 | .tabItem { 28 | Label("Videos", systemImage: "list.triangle") 29 | } 30 | .tag(Tab.videos) 31 | 32 | Text("Hello, world!") 33 | .tabItem { 34 | Label("Other", systemImage: "info") 35 | } 36 | .tag(Tab.other) 37 | } 38 | } 39 | } 40 | 41 | 42 | // MARK: - 43 | 44 | #if DEBUG 45 | struct ContentView_Previews: PreviewProvider { 46 | static var previews: some View { 47 | ContentView() 48 | } 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /SwiftUI/SwiftUIPlayer-iOS/SwiftUIPlayer/Views/ThumbnailView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThumbnailView.swift 3 | // SwiftUIPlayer 4 | // 5 | // Copyright © 2024 Brightcove, Inc. All rights reserved. 6 | // 7 | 8 | import SwiftUI 9 | import BrightcovePlayerSDK 10 | 11 | 12 | struct ThumbnailView: View { 13 | 14 | @ObservedObject 15 | var imageLoader:ImageLoader 16 | 17 | let urlStr: String? 18 | 19 | init(urlStr: String?) { 20 | self.urlStr = urlStr 21 | imageLoader = ImageLoader(urlString: urlStr ?? "") 22 | } 23 | 24 | var body: some View { 25 | Image(uiImage: UIImage(data: imageLoader.data) ?? UIImage()) 26 | .resizable() 27 | .aspectRatio(contentMode: .fit) 28 | .frame(width:50, height:50) 29 | } 30 | } 31 | 32 | 33 | // MARK: - 34 | 35 | #if DEBUG 36 | struct ThumbnailView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | let urlStr = "https://dp6mhagng1yw3.cloudfront.net/entries/15th/b2099e83-2214-43e0-93c0-0924d12d6cdc.jpeg" 39 | ThumbnailView(urlStr: urlStr) 40 | } 41 | } 42 | #endif 43 | --------------------------------------------------------------------------------