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
组件添加到任何 tvOS 项目中。是的,就这么简单。
注意两点
- 目前还没有示例项目(类似于上述内容)。因此,可能需要超过5分钟的时间。
- 在 tvOS 上没有
WistiaPlayerViewController
。相反,创建一个WistiaPlayer
和一个AVPlayerViewController
,并将它们结合起来,执行avPlayerVC.player = wistiaPlayer.avPlayer
。我们认为AVPlayerViewController
在电视上看起来很棒,难以做得更好。
改进 WistiaKit
我们仍在开发这个功能的初期阶段。请与我们联系(创建问题、分叉请求、发送电子邮件或在 Twitter 上关注 Wistia 等),告诉我们您希望在 WistiaKit
中看到什么。
要求
您需要账号在 Platform 计划中的 Wistia。您还需要在您的账号中添加一些视频。在这个阶段,您需要播放视频的哈希 ID。
安装
CocoaPods
WistiaKit 通过 CocoaPods 提供。
需要 CocoaPods 1.1.0+ 版本来构建 WistiaKit 0.12+。
安装时,只需在 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
如以下使用说明模块中所述,这创建了两个框架: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 进行了操作,创建了许多结构,并添加了一些语法糖。最终的结果——我们希望——即使是来自其他数据级接口或用于管理您账户的 Web视图的代码级别的接口,使用起来也感到很自然。使用您账户的 API 令牌初始化一个 WistiaAPI
对象,然后您就可以出发了。查看账户详细信息、列出您的项目、深入您的媒体;您可以在数据 API 中执行的任何操作,都可以在这里执行。
让它们两者结合在一起:创建一个 WistiaAPI
查看您的 WistiaProject
,选择一个 WistiaMedia
,使用该 WistiaMedia
对象初始化一个 WistiaPlayerViewController
,然后 self.presentViewController(_:animated:completion:)
!这太简单了,我相信您肯定可以在黑客马拉松中构建一个相当不错的 Apple TV 应用程序...
我们为什么把 API 接口和数据模型拉入到 WistiaKitCore
中呢?对于您不需要 回放 的时候。特别是当一些在 WistiaKit
中使用的 API 不可用,但您仍然希望查看或操作账户数据时。示例:在实现 App Extension(或将在 App Extension 中使用的 Framework)时仅包含 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带来了一大堆值类型!现在我们有结构体(以及枚举和元组)可能会让我们想起引用类型,但它们实际上是值类型。在
WistiaKitCore
中,你的数据对象是结构体。所以如果你let a = someMedia
和let b = a
,你的变量a
和b
都有独立的那WistiaMedia
的副本。如果你改变了某些东西,例如a.name = "whatever"
,这将不会影响到b.name
。我们认为这使得
WistiaKitCore
更不容易出错,并且让推理代码更容易。如果你想要在这个问题上花费一些大法师冥想时间,你不妨从Swift博客和2015年WWDC演讲开始。
上传
无论你是通过相机录制视频,从网站上下载视频,还是从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
仅渲染视频,不包含播放控件或其他UI。正如您所看到的,权力越大,责任越大。:-P
WistiaPlayerViewController
或 WistiaPlayer
初始化
referrer
- 建议使用指向视频的通用链接。这允许您从Wistia统计页面点击链接,同时记录应用的播放位置。如果您正在使用 域名限制,则引用应包括 http(s) 协议并与白名单中的某个域名匹配,否则视频将无法加载。requireHLS
- 苹果对应用内部播放视频有 特定要求。总结来说:如果您想要在蜂窝网络上播放超过10分钟的视频(即不强制使用Wi-Fi),则必须使用 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
。在下面的例子中,我们播放一个简介视频,不提供用户控制视频的任何方式。他们只能坐着看!<邪恶>
嘿嘿哈哈!</邪恶>
当视频播放结束后,我们会自动跳转到下一个简介界面。
下面,我们使用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可见性的工作。字幕在播放和定位过程中保持最新。通过WistiaCaptionsRenderer
的enabled
和captionsLanguageCode
属性控制要显示的字幕,如果有的话。
音频播放
在用户将设备切换到振动模式时启用音频播放必须由您在您的应用程序中完成。
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
WistiaKit并不假装能读懂你的想法 ;-]
播放器API
上方是一段介绍 WistiaKit
结构、如何使用以及一些示例的文字。了解基本情况是很有帮助的。但正如人们所说,地图不代表地形。年轻的学徒,你已经准备好了,去阅读appledoc吧。
作者
d j spinosa, [email protected]
许可协议
WistiaKit 和 WistiaKitCore 在 MIT 许可协议下可用。详细信息请参阅 LICENSE 文件。