WistiaKit
在 iPhone、iPad 和 Apple TV 上播放 Wistia 视频的最佳方式。使用 Swift 编写。
Swift 4.2 兼容性就在这里
5 分钟内将您的视频上传到 iOS!
免责声明 1:您需要安装Xcode 9(如果您还没有更新,需要大于 5 分钟)免责声明 2:您还需要安装RubyGems(这也可能需要一些时间)
好了,这些解决完之后。下面是更有趣且相当简单的一部分!
- 如果您还没有安装 Cocoapods,请安装它:
gem install cocoapods
pod try WistiaKit
会拉取这个 Pod 并在 Xcode 中打开- 选择播放图标旁边的“WistiaKit-Example”项目,然后按下播放按钮!
这个简单的应用允许您输入任何媒体的哈希 ID 并播放它。查看 WistiaKit/Example for Wistia Kit/ViewController.swift
中的代码,查看 WistiaKit/Example for Wistia Kit/Main.storyboard
中的基本界面。就是这样;两个界面输出,一个自定义实例变量和三行代码来播放视频。
在 tvOS(Apple TV)上传您的视频
只需将 WistiaKit
Pod 添加到任何 tvOS 项目即可。是的,就是这样。
有两个注意事项
- 尚无类似示例项目(如上所示)。因此,可能需要超过5分钟的时间。
- 在 tvOS 上不可用
WistiaPlayerViewController
。相反,创建一个WistiaPlayer
和一个AVPlayerViewController
,并通过avPlayerVC.player = wistiaPlayer.avPlayer
将它们结合起来。我们认为AVPlayerViewController
在电视上看起来很棒,很难做得更好。
您改善 WistiaKit
我们仍在开发这个项目的早期阶段。请与我们联系(创建问题、拉取请求、发送电子邮件或在 Twitter 上提及 Wistia 等),以告知我们您想在 WistiaKit
中看到什么。
需求
您需要在平台计划上的 Wistia 账户。您还需要在您的账户中添加一些视频。在此阶段,您还需要播放所需视频的哈希 ID。
安装
CocoaPods
WistiaKit 通过 CocoaPods 提供。
构建 WistiaKit 0.12+ 需要 CocoaPods 1.1.0+。
要安装,只需将以下行添加到您的 Podfile
pod "WistiaKit"
Carthage
从 0.30.2
版本开始,WistiaKit 应该能够与 Carthage 一起使用。不要忘记包括 Alamofire
和 AlamofireImage
,因为 WistiaKit 使用它们。示例 Cartfile
github "Wistia/WistiaKit" ~> 0.30.2
github "Alamofire/Alamofire" ~> 4.4
github "Alamofire/AlamofireImage" ~> 3.1
如用法部分所述,这创建了 2 个框架 WistiaKit
和 WistiaKitCore
。
只需记得像这样将必要的框架包含到您的 swift 代码中即可
import WistiaKit
import WistiaKitCore
使用
WistiaKit
从概念上分为两个部分;播放 和 核心。根据你的应用需求,你可以使用这两个组件——它们可以无缝协作——或者单独使用其中的任何一个。在深入细节之前,让我们了解一下它们。
播放 类似于网页内嵌。你可以通过 WistiaPlayerViewController
展示视频,只需使用它的 hashedID
即可播放你任何的视频。播放器的自定义设置和统计数据像正常一样跟踪;你无需做额外的事情。运行此 pod 中的示例项目以查看其效果(在 Xcode >= 8.0 中,执行 pod try WistiaKit
然后点击 ▶)。
如果你不想使用所有控件(比如播放器控件、滑块、时间、初始海报等),可以使用 WistiaPlayer
得到一个更底层的控制。你仍然只需要一个 hashedID
,但你只会得到一个 AVPlayerLayer
,你可以将其展示并按照你的意愿进行装饰。所有的 Wistia 统计数据都会被正常跟踪。偷偷告诉你:WistiaPlayerViewController
在底层使用了 WistiaPlayer
。
核心 通过 数据 API 提供。我们对 Swift 进行了重构,创建了一组结构体,并添加了一些语法糖。最终的结果——我们希望——无论是从其他代码级别的数据 API 接口还是从你用来管理账户的网页视图,都会感觉非常自然。使用你账户中的 API Token 初始化一个 WistiaAPI
对象,然后你就可以大步前进。查看账户详情、列出你的项目、深入研究你的媒体;你可以在这里完成所有从数据 API 可以做的事情。
将它们两个组合起来:创建一个 WistiaAPI
来浏览你的 WistiaProject
,选择一个 WistiaMedia
,使用该 WistiaMedia
对象初始化一个 WistiaPlayerViewController
,然后执行 self.presentViewController(_:animated:completion:)
!这很简单,我相信你可以在黑客马拉松中构建一个非常不错的 Apple TV 应用程序...
为什么我们将 API 接口和数据模型拉入 WistiaKitCore
? 因为有些时候你 不需要 播放。特别是当一些 WistiaKit
中使用的 API 不可用,但你仍然希望查看或操作账户数据时。例如:在实现 App 扩展(或将在 App 扩展中使用的框架)时,只包含 WistiaKitCore
。
视频上传 是一切的开始!在技术上属于 WistiaAPI
,但内容足够关键,值得单开一节。只需创建一个指向设备上电影或电影本身的 URL
,或 Data
,然后只需一行代码即可将其上传到你的账户。
核心
这里可能没什么可说的。主要就是参照 数据 API 文档。当然,你应该使用 WistiaAPI
的实例来与 API 交互。例如
import WistiaKitCore
let globalAPI = WistiaAPI(apiToken:"C4NTB3L13V3TH1S1SARAND0MT0K3N")
func printMediasByProject(){
globalAPI.listProjects { (projects, error) in
for project in projects {
print("\(project) medias:")
globalAPI.listMedias(limitedToProject: project, completionHandler: { (medias, error) in
for media in medias {
print(" \(media)")
}
})
}
}
}
注意事项:WistiaKitCore 还未完整实现 数据 API。但很快就会实现。如果您想要某个功能,但目前尚不可用,请通过提交 Pull Request ☺ 或创建问题来让我们知道。
关于结构体的说明
通过 Swift 学习 iOS 编程,可以更加广泛地使用值语义。我们将很快讨论这意味着什么。
在 Objective-C 的美好时代,你有对象。这些就是你的类和一切。当你将对象传递给方法或将它们存储在变量中时,你一直在谈论同一个对象。这是因为你的对象是 引用类型。你实际上在传递对象的 引用(即指针)。
即使如此,你也有 值类型。一个很好的例子是你的整数。如果你说
a = 4
和b = a
,你将a
和b
都设置为 4 的值。它们并没有指向一个对象。因此,b++
不会改变a
的值,它将保持 4。进入 Swift,许多更多的值类型!现在我们有 struct(结构体)、enum(枚举)和元组,它们可能会使我们想起引用类型,但实际上是值类型。在
WistiaKitCore
中,你的数据对象是 struct。因此,如果你let a = someMedia
和let b = a
,变量a
和b
将拥有该WistiaMedia
的独立副本。如果你改变了某个属性,比如a.name = " whatever "
,这不会影响b.name
。我们认为这使得
WistiaKitCore
漏洞减少,而且更容易推理你的代码。如果您想在这一点上花些专家冥想时间,您可以开始阅读 Swift 博客 和一个 WWDC 2015 演讲。
上传
无论你是通过相机拍摄视频、从网络上下载它还是从 iCloud 中拉取,上传到 Wistia 只需一行代码。最困难的部分应该是找到文件 URL
或 Data
。而这非常简单 ;-]
import WistiaKitCore
let api = WistiaAPI(apiToken: "C4NTB3L13V3TH1S1SARAND0MT0K3N")
let fileURL = Bundle.main.url(forResource: "hello", withExtension: "mov")
api.upload(fileURL: fileURL!, into: "ProjectHashedID", name: "Hello, World!",
progressHandler: { progress in
print("reticulating splines... \(progress)")
},
completionHandler: { media, error in
print("You've got media! \(media)")
})
可能不需要,但了解 Wistia 上传 API 文档也很有用。
播放
首先你需要决定你的视频播放器外观。如果你已经熟悉 iOS 上的视频播放,那么你所需要知道的就是:WistiaPlayerViewController ≈ AVPlayerViewController
和 WistiaPlayer ≈ AVPlayer
。如果你不熟悉 iOS 上的视频,或者只是需要复习,请继续阅读。
如果您喜欢我们的网页播放器的样式和(大多数)自定义,并且/或者不想做太多的 UI 构建,请使用 WistiaPlayerViewController
。您可以在全屏或自己的 ViewController
中的 ContainerView
内展示它。它带有标准的播放控件和一些您可以挂载的良好的委托方法。
对于那些希望完全控制系统的人来说,你需要使用 WistiaPlayer
。为了看视频,你需要展示由你的 WistiaPlayer
实例提供的 AVPlayerLayer
。你还需要自行通过编程来控制 WistiaPlayer
;AVPlayerLayer
仅渲染视频,不包含任何播放器控件或其他用户界面。正如你所见,强大的力量伴随着重大的责任。:-P
WistiaPlayerViewController
或 WistiaPlayer
初始化 referrer
- 我们建议使用指向视频的全局链接。这将在记录应用程序播放位置的同时,允许你从 Wistia 统计页面单击该链接。如果你使用 域名限制,则 referrer 应包含 http(s) 协议并匹配白名单中的域名,否则视频将无法加载。requireHLS
- 苹果对在应用程序中播放视频有 特定要求。总结如下:如果你想在蜂窝网络上播放超过 10 分钟的视频(即不强制使用 wifi),那么你必须使用 HLS。Wistia 完全支持并且已经对与苹果的 HLS 实现进行彻底测试。我们建议将其保留为默认的true
。
WistiaPlayerViewController
示例
假设我们正在开发一个包含介绍部分的应用程序。我们可以使用一个 WistiaPlayerViewController
来加载任意数量的介绍视频,并全屏播放,如下面的示例所示
import WistiaKit
class IntroductionViewController: UIViewController {
let wistiaPlayerVC = WistiaPlayerViewController(referrer: "https://wistia.tv/intro")
func loadVideoWithHashedID(hashedID: String) {
wistiaPlayerVC.replaceCurrentVideoWithVideoForHashedID(hashedID)
self.presentViewController(wistiaPlayerVC, animated: true, completion: nil)
}
}
这将加载视频,但是播放和与内容交互取决于用户。
WistiaPlayer
示例
如果我们想让介绍视频的表现略有不同,我们可以使用一个 WistiaPlayer
。在下面的示例中,我们不提供任何控制视频的方式,用户必须坐那里观看!<邪恶>
bwaa ha ha ha!
</邪恶>
当视频播放完成后,我们将自动进入下一个介绍屏幕。
以下展示使用WistiaFlatPlayerView
的视频,这是一个由AVPlayerLayer
支持的普通UIView。这个层被配置为当您将视图的wistiaPlayer
属性设置为WistiaPlayer
实例时显示视频内容。虽然它表现得像其他任何UIView
一样,允许您使用常见和熟悉的生命周期和布局机制,但你可能还需要更多的功能。
可以通过WistiaPlayer
的newPlayerLayer()
方法获取一个独立的AVPlayerLayer
。在请求这个层时,任何先前配置的层或视图将停止为该播放器渲染内容。新初始化的AVPlayerLayer
(类似于任何CALayer
)在被添加为子层之前应设置其框架。您还需要负责在层级别上维护布局,要么手动完成,要么使用CAConstraint
或其他基于层的机制。
import WistiaKitCore
import WistiaKit
class IntroductionViewController: UIViewController, WistiaPlayerDelegate {
let wistiaPlayer = WistiaPlayer(referrer: "https://wistia.tv/intro")
// In Interface Builder we set the view's class to WistiaFlatPlayerView.
// If we had a compelling reason, we could instead use an AVPlayerLayer directly via `newPlayerLayer()`.
// But a UIView is more familiar without sacrificing much flexibility.
@IBOutlet weak var playerContainer: WistiaFlatPlayerView!
override public func viewDidLoad() {
wistiaPlayer.delegate = self
playerContainer.wistiaPlayer = wistiaPlayer
wistiaPlayer.replaceCurrentVideoWithVideoForHashedID(IntroVideoHashedID)
}
//Mark: - WistiaPlayerDelegate
public func wistiaPlayer(player:WistiaPlayer, didChangeStateTo newState:WistiaPlayer.State) {
switch newState {
case .VideoReadyForPlayback:
wistiaPlayer.play()
default:
//ignoring, but probably shouldn't
}
}
public func wistiaPlayerDidPlayToEndTime(player: WistiaPlayer) {
self.showNextIntroScreen()
}
// ... rest of delegate methods ...
}
字幕
如果您使用的是WistiaPlayerViewController
,字幕支持是内置的。您无需做任何额外操作!
对于那些直接使用WistiaPlayer
的勤奋的代码发明者,我们使显示字幕变得相当简单。获取WistiaPlayer.captionsRenderer
—— 它是针对该播放器配置的WistiaCaptionsRenderer
的一个实例 —— 并将其captionsView
连接到UI中覆盖视频视图的一个视图。渲染器处理获取字幕、时间数据、更新UI内容和保持正确UI可见性的底层数据处理工作。在播放和寻求通过WistiaPlayer
加载的所有视频时,字幕保持最新。通过WistiaCaptionsRenderer
的enabled
和captionsLanguageCode
属性控制是否显示字幕。
音频播放
当用户将设备切换到振动模式时,启用音频播放必须由您在您的应用程序中完成
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
WistiaKit并不试图阅读思想 ;-]
播放器API
上面是一段文字,解释了如何构建WistiaKit
,如何接近它,以及一些如何使用它的例子。了解这个领域是件好事。但正如他们所说,地图不是地形。你准备好了,年轻的学徒,去读一读appledoc吧。
作者
d j spinosa, [email protected]
许可协议
WistiaKit 和 WistiaKitCore 在 MIT 许可协议下提供。更多信息请参阅 LICENSE 文件。