FireTVKit
发现您的 FireTV 并控制内置媒体播放器现在变得简单且响应式
Amazon Fling SDK 缺少一个用于发现 FireTV 并控制内置接收器应用(媒体播放器)的现成视图控制器。这就是我创建 FireTVKit 的原因。它提供了一个可定制的视图控制器来发现本地网络中的 FireTV。所有必要的魔法都在幕后发生。此外,FireTVKit 还提供了一个可定制的视图控制器来控制 FireTV 的内置媒体播放器。即使在这一点上,所有的魔法也都在幕后发生。感谢协议导向的方法,您可以轻松创建自己的发现和播放器视图。如果您希望完全自由,请使用 FireTVManager 进行发现并获取 FireTV 列表。然后按照您想要的方式向用户展示 FireTV。
FireTVPlayer
和 FireTVSelection
的实现遵循 VIPER
架构模式。如果您想实现自定义视图,请首先熟悉 VIPER
。
特色功能
特色 | |
---|---|
用于 FireTV 发现和选择的可定制的视图控制器(自定义无设备文本) | |
用于控制 FireTV 内置媒体播放器的可定制的视图控制器 | |
使用 FireTVManager 进行发现并获取可用的 FireTV 列表 | |
内置wifi连接验证(自定义警报标题和消息) | |
单元测试 | |
可扩展的 API | |
用 Swift 编写 |
示例
1. 暗色主题下的 FireTV 播放器选择
2. 无设备状态的 FireTV 播放器选择
3. 无WiFi状态下的FireTV播放器选择
4. 暗色调主题下的FireTV播放器
5. 亮色调主题下的FireTV播放器
要运行示例项目,请先克隆仓库,然后从示例目录运行pod install
。
如何使用
- 创建并展示
FireTVSelectionViewController
import AmazonFling
import FireTVKit
import UIKit
final class ViewController: UIViewController {
private lazy var SAMPLE_VIDEO_METADATA: Metadata = {
var metadata = Metadata(type: .video)
metadata.title = "Testvideo"
metadata.description = "A video for test purposes"
metadata.noreplay = true
return metadata
}()
private let SAMPLE_VIDEO_URL = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
private lazy var SAMPLE_VIDEO: URL? = {
guard let url = URL(string: SAMPLE_VIDEO_URL) else {
return nil
}
return url
}()
private var selectedPlayer: RemoteMediaPlayer?
override func viewDidLoad() {
super.viewDidLoad()
guard let url = SAMPLE_VIDEO else {
return
}
let media = FireTVMedia(metadata: SAMPLE_VIDEO_METADATA, url: url)
let theme = FireTVSelectionDarkTheme()
let playerId = "amzn.thin.pl"
let fireTVSelectionVC = try FireTVSelectionWireframe.makeViewController(theme: theme, playerId: playerId, media: media, delegate: self)
present(fireTVSelectionVC, animated: true)
}
}
extension ViewController: FireTVSelectionDelegateProtocol {
func didSelectPlayer(_ fireTVSelectionViewController: FireTVSelectionViewController, player: RemoteMediaPlayer) {
fireTVSelectionViewController.dismiss(animated: true, completion: nil)
selectedPlayer = player
}
func didPressCloseButton(_ fireTVSelectionViewController: FireTVSelectionViewController) {
fireTVSelectionViewController.dismiss(animated: true, completion: nil)
}
}
- 创建并展示
FireTVPlayerViewController
import AmazonFling
import FireTVKit
import UIKit
final class ViewController: UIViewController {
private var selectedPlayer: RemoteMediaPlayer?
override func viewDidLoad() {
super.viewDidLoad()
guard let selectedPlayer = selectedPlayer else {
return
}
let theme = FireTVPlayerDarkTheme()
let fireTVPlayerVC = try FireTVPlayerWireframe.makeViewController(forPlayer: player, theme: theme, delegate: self)
present(fireTVPlayerVC, animated: true)
}
}
extension ViewController: FireTVPlayerDelegateProtocol {
func didPressCloseButton(_ fireTVPlayerViewController: FireTVPlayerViewController) {
fireTVPlayerViewController.dismiss(animated: true, completion: nil)
}
}
FireTVManager
在以下代码示例中,您将了解如何使用FireTVManager
实例来发现和获取可用的FireTV。您可以使用PlayerService
实例来控制FireTV的内置媒体播放器。
import AmazonFling
import FireTVKit
import RxSwift
import UIKit
final class FireTVManagerExampleViewController: UIViewController {
private var fireTVManager: FireTVManager?
private var disposeBag: DisposeBag?
@IBOutlet private weak var firstPlayerLabel: UILabel!
deinit {
print("FireTVManagerExampleViewController deinit")
}
override func viewDidLoad() {
super.viewDidLoad()
let disposeBag = DisposeBag()
self.disposeBag = disposeBag
do {
fireTVManager = try FireTVManager()
try fireTVManager?.startDiscovery(forPlayerID: "amzn.thin.pl")
fireTVManager?.devicesObservable
.subscribe(onNext: { [weak self] player in
if !player.isEmpty {
self?.firstPlayerLabel?.text = player.first?.name()
} else {
self?.firstPlayerLabel.text = "No player found"
}
}, onError: { error in
print(error)
}).disposed(by: disposeBag)
} catch {
print(error)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
fireTVManager?.stopDiscovery()
}
@IBAction private func didPressCloseButton(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
自定义
在开始创建您自己的选择或播放器视图之前,请熟悉一下《VIPER》架构模式。这是一篇很好的起点:比较MVVM和VIPER架构。
- 您可以使用
FireTVSelectionViewProtocol
来创建自己的FireTV选择视图。 - 使用
FireTVPlayerViewProtocol
来创建您自定义的播放器视图。 - 通过使用
FireTVSelectionThemeProtocol
和FireTVPlayerThemeProtocol
,您可以为可定制的选择和播放器视图控制器构建自定义主题。
日志记录
要启用日志记录,请在UserDefaults
中使用键FireTVKitUserDefaultsKeys.fireTVKitLogging.rawValue
存储一个布尔值。
如果您只想记录特定的事件,请将LogEvent
枚举案例作为原始值存储在UserDefaults
中的键FireTVKitUserDefaultsKeys.fireTVKitLogEvent.rawValue
中。
文档
需求
- 目前只提供了响应式实现。这就是为什么你需要
RxSwift
的原因。 - 您的 App 的部署目标为 >= iOS 9.0。
- 目前不支持 Bitcode。我希望将来会有所进展。
- 为了消除 Cocoapods 警告
递归依赖
,请在您的Podfile
中使用以下内容(来源:AmazonFling 依赖项包含静态框架)
pre_install do |installer|
# workaround for https://github.com/CocoaPods/CocoaPods/issues/3289
Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {}
end
安装
FireTVKit 可通过 CocoaPods 获得。要安装它,只需在您的 Podfile 中添加以下行
pod 'FireTVKit'
作者
Christian Elies,[email protected]
许可协议
FireTVKit 在 MIT 许可下提供。有关更多信息,请参阅 LICENSE 文件。