Compare commits

..

60 Commits

Author SHA1 Message Date
Rogerio de Paula Assis 6e2e769739 --wip-- [skip ci] 2019-07-31 18:02:34 -04:00
Rogerio de Paula Assis f3d48a0a75 Merge pull request #76 from vimeo/master
Merge master into develop
2019-06-17 11:01:10 -04:00
Rogerio de Paula Assis 7bc6450535 Merge pull request #75 from vimeo/feature/VIM-7040_Swift5Migration
VIM-7040: Migrates to Swift 5, updates project to recommended settings
2019-06-13 09:21:43 -04:00
Rogerio de Paula Assis a4f697b067 Updates fastlane xcode version to 10.2.1 2019-06-05 16:52:18 -04:00
Rogerio de Paula Assis dbc6cb250c Updates Circle CI xcode configuration 2019-06-05 16:44:12 -04:00
Rogerio de Paula Assis 198197241b Migrates to Swift 5, updates project to recommended settings 2019-06-05 16:22:01 -04:00
Rogerio de Paula Assis 98c86c1852 Merge pull request #66 from vimeo/master
Merge master into develop
2019-05-07 10:31:09 -04:00
Mike Westendorf e08903c201 VIM-6715: Updates fastlane to the latest version (#53) 2019-04-26 21:00:09 -04:00
Vladimir Pavlov 89c4f4755d Add ability to force faster start of AVPlayer (#67) via automaticallyWaitsToMinimizeStalling 2019-04-26 17:50:16 -04:00
Rogerio de Paula Assis 0ca7258e9b VIM-6919: Release 2.0.0, Swift 4.2 migration (#65) 2019-04-25 17:15:30 -04:00
Rogerio de Paula Assis 87cdb24a24 VIM-6919: Migrates to Swift 4.2 (#61) 2019-04-25 16:51:12 -04:00
Rogerio de Paula Assis f400ad9883 Merge pull request #64 from vimeo/master
VIM-XXXX Merge master into develop
2019-04-25 16:13:36 -04:00
Rogerio de Paula Assis a53096df50 Merge pull request #63 from vimeo/release/1.4.0
VIM-6919: Release 1.4.0 prior to migration to Swift 4.2
2019-04-24 16:44:43 -04:00
Rogerio de Paula Assis 4720991d0f VIM-6919 Version bump 1.4.0, added version_bump lane to fastlane 2019-04-23 13:24:00 -04:00
Rogerio de Paula Assis ca661f1996 Merge pull request #62 from vimeo/master
VIM-XXXX: Merge master into develop
2019-04-23 13:16:50 -04:00
Jason Hawkins 5ba8f4db04 Merge pull request #52 from vimeo/tech/add-swiftlint-support
Adds initial SwiftLint rules to PlayerKit
2018-11-28 10:09:18 -05:00
Jason Hawkins 34c5cac889 Build with swiftlint for example project files 2018-11-15 12:38:29 -05:00
Jason Hawkins 3729921bed Add example project files to included file paths for linting 2018-11-15 12:38:15 -05:00
Jason Hawkins ce3a42f41a Build with swiftlint for source files 2018-11-15 12:33:51 -05:00
Jason Hawkins 92e00745d7 Run bundle exec pod install 2018-11-15 12:32:42 -05:00
Jason Hawkins c7ef4c2ebc Add new script phase to example project 2018-11-15 12:31:35 -05:00
Jason Hawkins 75b2a10881 Add .swiftlint.yml 2018-11-15 12:31:22 -05:00
Jason Hawkins e60bd3bd3b Add SwiftLint to podfile 2018-11-15 12:31:11 -05:00
Nicole Lehrer a95c54eb56 Merge pull request #51 from vimeo/nicolelehrer-patch-1
Update README
2018-11-12 13:56:14 -05:00
Nicole Lehrer af54544cbe Update README.md 2018-11-12 12:56:55 -05:00
Mike Westendorf 54003387d5 Merge pull request #50 from vimeo/vim-6695-update-nokogiri
VIM-6695: Update nokogiri to v1.8.5
2018-11-08 15:08:26 -05:00
Mike Westendorf f441a7a03e update Gem lock file 2018-11-07 16:08:06 -05:00
Mike Westendorf ad04383a32 Update nokogiri to v1.8.5 2018-11-07 16:04:44 -05:00
Jason Hawkins 46d34ae58f Merge pull request #48 from vimeo/circle-ci-upgrade
AF-311: Updates PlayerKit to support CircleCI 2.0
2018-10-19 11:58:54 -04:00
jasonhawkins 6dce0ee5b4 Fix Xcode version number 2018-10-11 16:50:52 -04:00
jasonhawkins a9a9627ce9 Run bundle exec pod install 2018-10-11 16:49:39 -04:00
jasonhawkins 70eb3f5039 Update README 2018-10-11 16:49:31 -04:00
jasonhawkins b3ec050d8f Udpate Fastfaline to run against Xcode 10 2018-10-11 16:49:18 -04:00
jasonhawkins bea45df706 Update Podfile to specify a platform for the example 2018-10-11 16:48:58 -04:00
jasonhawkins 03482bccda Update CircleCI to execute our custom scan lane 2018-10-11 16:48:19 -04:00
jasonhawkins 01f34b57e5 Update CircleCI to run against Xcode 10 2018-10-11 16:48:05 -04:00
jasonhawkins a83cf1fb3a Remove embed swift libraries override
CocoaPods will do this for us anyway.
2018-10-11 16:47:42 -04:00
jasonhawkins 1b09629f9d Remove _Pods alias 2018-08-27 16:34:21 -04:00
jasonhawkins 97f17e3362 Remove old CircleCi config 2018-08-27 16:22:46 -04:00
jasonhawkins 72aec6efa8 Add new CircleCi config 2018-08-27 16:22:36 -04:00
jasonhawkins 708c945840 Run bundle exec pod install 2018-08-27 16:22:25 -04:00
Frederick Kellison-Linn a60a1da448 Merge pull request #39 from vimeo/master
Update develop for 1.3.0 release
2018-07-18 16:24:41 -04:00
Frederick Kellison-Linn 90530c4961 Merge pull request #38 from vimeo/release/1.3.0
Release 1.3.0
2018-07-18 15:57:49 -04:00
Freddy Kellison-Linn 7f7f2157fd Release 1.3.0 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 2a11f34165 Add explanatory comment for SDH 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 0a28c0cc1b Use new matches(_:) method in select(_:) 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn a31eafca1f Fixup style 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 6e8446675e Change == operator to matches(_:) method 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn dd3f9937b2 Make TextTrackMetadata == global 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn fb7879346a Improve TextTrackMetadata and TextTrackCapable APIs 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 393e659cf0 Remove deprecated API in newer versions 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 17c04841dd Add selectedTrack requirement to TextTrackCapable 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 19328921bb Use Array.first instead of for-in loop 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn 14f1e26dfd Move TextTrackCapable conformance to extension 2018-07-18 15:42:21 -04:00
Freddy Kellison-Linn a031f37000 Make RegularPlayer conform to TextTrackCapable and AVMediaSelectionOption to TextTrackMetadata 2018-07-18 15:42:20 -04:00
Freddy Kellison-Linn ceeb22419f Add period 2018-07-18 15:42:20 -04:00
Freddy Kellison-Linn c02d5aba36 Add TextTrackMetadata and TextTrackCapable protocols to Player.swift 2018-07-18 15:42:20 -04:00
Mike Westendorf 9490ecc197 updates cocoapods to version 1.5.2, updates git ignore file 2018-07-18 15:42:20 -04:00
Gavin King d9fd6ec9e0 Merge pull request #24 from vimeo/develop
Merging master into develop
2017-12-07 16:27:04 -05:00
Gavin King bd27ed90de Merge pull request #22 from vimeo/develop
Merging develop into master
2017-12-07 16:02:01 -05:00
24 changed files with 409 additions and 356 deletions
+50
View File
@@ -0,0 +1,50 @@
version: 2
jobs:
build-and-test:
environment:
BUNDLE_PATH: vendor/bundle
FL_OUTPUT_DIR: output
macos:
xcode: "10.2.1"
working_directory: ~/PlayerKit
shell: /bin/bash --login -o pipefail
steps:
- checkout
- restore_cache:
key: v1-gems-{{ checksum "Gemfile.lock" }}
- run:
name: Set Ruby version
command: echo "ruby-2.4" > ~/.ruby-version
- run:
name: Install bundler dependencies
command: bundle install --path vendor/bundle
- run:
name: Build and run tests
command: bundle exec fastlane ios test
environment:
SCAN_DEVICE: iPhone 8
SCAN_SCHEME: PlayerKit-Example
- save_cache:
paths:
- vendor/bundle
key: v1-gems-{{ checksum "Gemfile.lock" }}
- store_artifacts:
path: output
- store_test_results:
path: output/scan
workflows:
version: 2
build:
jobs:
- build-and-test
-1
View File
@@ -1 +0,0 @@
4.0
+42
View File
@@ -0,0 +1,42 @@
# Copyright © 2018 Vimeo. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Run `swiftlint rules` for a list of available rules.
# Only the rules specified here will be enabled.
whitelist_rules:
- trailing_newline
- trailing_whitespace
- opening_brace
# Paths to include during linting.
included:
- ../PlayerKit/Classes
- ../Example
# Paths to exclude during linting.
excluded:
- Pods
# Configurable rules can be customized from this configuration file,
# binary rules can set their severity level.
trailing_whitespace:
ignores_empty_lines: true
+42 -15
View File
@@ -172,6 +172,7 @@
39DBB93200760D1BB486C4CC /* [CP] Check Pods Manifest.lock */,
607FACCC1AFB9204008FA782 /* Sources */,
607FACCD1AFB9204008FA782 /* Frameworks */,
0C1455B6219DDFB7006442F3 /* ShellScript */,
607FACCE1AFB9204008FA782 /* Resources */,
AEEB7FDEAB18BB5B2C3B7E51 /* [CP] Embed Pods Frameworks */,
);
@@ -210,18 +211,18 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = CocoaPods;
TargetAttributes = {
607FACCF1AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
DevelopmentTeam = 35R365FS4Q;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
};
607FACE41AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
DevelopmentTeam = 35R365FS4Q;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
TestTargetID = 607FACCF1AFB9204008FA782;
};
};
@@ -231,6 +232,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
@@ -267,6 +269,19 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0C1455B6219DDFB7006442F3 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "WORKSPACE_ROOT=$( cd \"$(dirname \"${SRCROOT[0]}\")\" ; pwd -P )\n\nif which \"$PODS_ROOT\"/SwiftLint/swiftlint > /dev/null; then\n \"$PODS_ROOT\"/SwiftLint/swiftlint autocorrect --config \"$WORKSPACE_ROOT\"/.swiftlint.yml\nelse\n echo \"Warning: SwiftLint is not installed. Make sure you've run `bundle exec pod install`.\"\nfi\n";
};
39DBB93200760D1BB486C4CC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -367,18 +382,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -407,7 +431,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -415,18 +439,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -447,7 +480,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -456,7 +489,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 9D69DB7C6B7F626E6391E3FA /* Pods-PlayerKit_Example.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 35R365FS4Q;
INFOPLIST_FILE = PlayerKit/Info.plist;
@@ -464,8 +496,7 @@
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -474,7 +505,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = CF08222175BD5B0E142D343A /* Pods-PlayerKit_Example.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = 35R365FS4Q;
INFOPLIST_FILE = PlayerKit/Info.plist;
@@ -482,8 +512,7 @@
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@@ -502,8 +531,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -517,8 +545,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -40,7 +40,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -70,7 +69,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+1 -2
View File
@@ -13,8 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = PlayerViewController()
self.window?.makeKeyAndVisible()
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>2.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+14 -28
View File
@@ -10,10 +10,8 @@ import UIKit
import PlayerKit
import AVFoundation
class PlayerViewController: UIViewController, PlayerDelegate
{
private struct Constants
{
class PlayerViewController: UIViewController, PlayerDelegate {
private struct Constants {
static let VideoURL = URL(string: "https://github.com/vimeo/PlayerKit/blob/master/Example/PlayerKit/video.mp4?raw=true")!
}
@@ -24,8 +22,7 @@ class PlayerViewController: UIViewController, PlayerDelegate
private let player = RegularPlayer()
override func viewDidLoad()
{
override func viewDidLoad() {
super.viewDidLoad()
player.delegate = self
@@ -37,8 +34,7 @@ class PlayerViewController: UIViewController, PlayerDelegate
// MARK: Setup
private func addPlayerToView()
{
private func addPlayerToView() {
player.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
player.view.frame = self.view.bounds
self.view.insertSubview(player.view, at: 0)
@@ -46,13 +42,11 @@ class PlayerViewController: UIViewController, PlayerDelegate
// MARK: Actions
@IBAction func didTapPlayButton()
{
@IBAction func didTapPlayButton() {
self.player.playing ? self.player.pause() : self.player.play()
}
@IBAction func didChangeSliderValue()
{
@IBAction func didChangeSliderValue() {
let value = Double(self.slider.value)
let time = value * self.player.duration
@@ -62,12 +56,10 @@ class PlayerViewController: UIViewController, PlayerDelegate
// MARK: VideoPlayerDelegate
func playerDidUpdateState(player: Player, previousState: PlayerState)
{
func playerDidUpdateState(player: Player, previousState: PlayerState) {
self.activityIndicator.isHidden = true
switch player.state
{
switch player.state {
case .loading:
self.activityIndicator.isHidden = false
@@ -82,30 +74,24 @@ class PlayerViewController: UIViewController, PlayerDelegate
}
}
func playerDidUpdatePlaying(player: Player)
{
func playerDidUpdatePlaying(player: Player) {
self.playButton.isSelected = player.playing
}
func playerDidUpdateTime(player: Player)
{
guard player.duration > 0 else
{
func playerDidUpdateTime(player: Player) {
guard player.duration > 0 else {
return
}
let ratio = player.time / player.duration
if self.slider.isHighlighted == false
{
if self.slider.isHighlighted == false {
self.slider.value = Float(ratio)
}
}
func playerDidUpdateBufferedTime(player: Player)
{
guard player.duration > 0 else
{
func playerDidUpdateBufferedTime(player: Player) {
guard player.duration > 0 else {
return
}
+8 -6
View File
@@ -1,10 +1,12 @@
use_frameworks!
platform :ios, '8.0'
target 'PlayerKit_Example' do
pod 'PlayerKit', :path => '../'
target 'PlayerKit_Tests' do
inherit! :search_paths
end
pod 'PlayerKit', :path => '../'
pod 'SwiftLint', '0.28.0'
target 'PlayerKit_Tests' do
inherit! :search_paths
end
end
+10 -3
View File
@@ -1,16 +1,23 @@
PODS:
- PlayerKit (1.2.0)
- PlayerKit (2.0.0)
- SwiftLint (0.28.0)
DEPENDENCIES:
- PlayerKit (from `../`)
- SwiftLint (= 0.28.0)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- SwiftLint
EXTERNAL SOURCES:
PlayerKit:
:path: "../"
SPEC CHECKSUMS:
PlayerKit: ff4e4cd4c216d60ebcfccf3a68772d6299373e5a
PlayerKit: 1830be30e87ca46708c93e7ef0a6cf6590936b14
SwiftLint: 088cfacb75b45970017e62b7524d506776d60148
PODFILE CHECKSUM: 071d8819500a822237123321021901352f4d91a4
PODFILE CHECKSUM: 90f31c00641fb4d5e9453ba687a3a06a32cca83f
COCOAPODS: 1.5.2
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>2.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+2 -2
View File
@@ -1,10 +1,10 @@
source 'https://rubygems.org'
gem 'fastlane', '2.42.0'
gem 'fastlane', '2.108.0'
gem 'cocoapods', '1.5.2'
gem 'danger', '4.0.4'
gem 'xcode-install', '2.1.0'
gem 'xcpretty-json-formatter', '0.1.0'
gem 'danger-xcode_summary', '0.1.0'
gem 'nokogiri', '1.6.0'
gem 'nokogiri', '1.8.5'
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval(File.read(plugins_path), binding) if File.exist?(plugins_path)
+63 -55
View File
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.6)
CFPropertyList (3.0.0)
activesupport (4.2.10)
i18n (~> 0.7)
minitest (~> 5.1)
@@ -9,7 +9,7 @@ GEM
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.2)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
claide-plugins (0.9.2)
@@ -40,12 +40,12 @@ GEM
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.2)
cocoapods-downloader (1.2.0)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.3.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
@@ -54,7 +54,7 @@ GEM
colorize (0.8.1)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
concurrent-ruby (1.0.5)
concurrent-ruby (1.1.3)
cork (0.3.0)
colored2 (~> 3.1)
danger (4.0.4)
@@ -76,10 +76,11 @@ GEM
declarative-option (0.1.0)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.4.0)
dotenv (2.5.0)
emoji_regex (0.1.1)
escape (0.0.4)
excon (0.62.0)
faraday (0.15.2)
faraday (0.15.3)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
@@ -88,22 +89,23 @@ GEM
faraday (~> 0.8)
faraday_middleware (0.12.2)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.3)
fastlane (2.42.0)
CFPropertyList (>= 2.3, < 3.0.0)
fastimage (2.1.4)
fastlane (2.108.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 2.0.0)
colored
commander-fastlane (>= 4.4.0, < 5.0.0)
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (~> 0.1)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 1.6)
gh_inspector (>= 1.0.1, < 2.0.0)
google-api-client (>= 0.12.0, < 0.13.0)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
mini_magick (~> 4.5.1)
@@ -111,15 +113,18 @@ GEM
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 1.1.0, < 2.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
security (= 0.1.3)
slack-notifier (>= 1.3, < 2.0.0)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 1.6.2, < 2.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (~> 0.5.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.4.4, < 2.0.0)
xcpretty (>= 0.2.4, < 1.0.0)
xcodeproj (>= 1.6.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fastlane-plugin-pretty_junit (0.1.1)
colorize
@@ -128,21 +133,21 @@ GEM
fourflusher (2.0.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
git (1.4.0)
google-api-client (0.12.0)
git (1.5.0)
google-api-client (0.23.9)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.5)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
googleauth (0.6.2)
signet (~> 0.9)
googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
logging (~> 2.0)
memoist (~> 0.12)
memoist (~> 0.16)
multi_json (~> 1.11)
os (~> 0.9)
os (>= 0.9, < 2.0)
signet (~> 0.7)
highline (1.7.10)
http-cookie (1.0.3)
@@ -152,74 +157,77 @@ GEM
concurrent-ruby (~> 1.0)
json (2.1.0)
jwt (2.1.0)
kramdown (1.16.2)
little-plugger (1.1.4)
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
kramdown (1.17.0)
memoist (0.16.0)
mime-types (3.1)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mime-types-data (3.2018.0812)
mini_magick (4.5.1)
mini_portile (0.5.3)
mini_portile2 (2.3.0)
minitest (5.11.3)
molinillo (0.6.5)
molinillo (0.6.6)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.5)
nanaimo (0.2.6)
nap (1.1.0)
naturally (2.2.0)
netrc (0.11.0)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
octokit (4.9.0)
nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
octokit (4.13.0)
sawyer (~> 0.8.0, >= 0.5.3)
open4 (1.3.4)
os (0.9.6)
os (1.0.0)
plist (3.4.0)
public_suffix (3.0.2)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.1)
retriable (3.1.2)
rouge (2.0.7)
ruby-macho (1.1.0)
rubyzip (1.2.1)
ruby-macho (1.3.1)
rubyzip (1.2.2)
sawyer (0.8.1)
addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0)
security (0.1.3)
signet (0.8.1)
signet (0.11.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
slack-notifier (1.5.1)
simctl (1.6.5)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (1.8.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-screen (0.5.1)
tty-cursor (0.6.0)
tty-screen (0.6.5)
tty-spinner (0.8.0)
tty-cursor (>= 0.5.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
unicode-display_width (1.3.2)
unicode-display_width (1.4.0)
word_wrap (1.0.0)
xcode-install (2.1.0)
claide (>= 0.9.1, < 1.1.0)
fastlane (>= 2.1.1, < 3.0.0)
xcodeproj (1.5.9)
xcodeproj (1.7.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.2)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.5)
xcpretty (0.2.8)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-json-formatter (0.1.0)
xcpretty (~> 0.2, >= 0.0.7)
@@ -233,11 +241,11 @@ DEPENDENCIES
cocoapods (= 1.5.2)
danger (= 4.0.4)
danger-xcode_summary (= 0.1.0)
fastlane (= 2.42.0)
fastlane (= 2.108.0)
fastlane-plugin-pretty_junit
nokogiri (= 1.6.0)
nokogiri (= 1.8.5)
xcode-install (= 2.1.0)
xcpretty-json-formatter (= 0.1.0)
BUNDLED WITH
1.15.3
1.17.1
+3 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'PlayerKit'
s.version = '1.3.0'
s.version = '2.0.0'
s.summary = 'A modular video player system.'
s.description = <<-DESC
@@ -15,6 +15,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '9.0'
s.swift_version = "4.2"
s.source_files = 'PlayerKit/Classes/**/*'
end
+6 -12
View File
@@ -9,30 +9,24 @@
import Foundation
import AVFoundation
extension AVPlayer
{
var errorForPlayerOrItem: NSError?
{
extension AVPlayer {
var errorForPlayerOrItem: NSError? {
// First try to return the current item's error
if let error = self.currentItem?.error
{
if let error = self.currentItem?.error {
// If current item's error has an underlying error, return that
if let underlyingError = (error as NSError).userInfo[NSUnderlyingErrorKey] as? NSError
{
if let underlyingError = (error as NSError).userInfo[NSUnderlyingErrorKey] as? NSError {
return underlyingError
}
else
{
else {
return error as NSError?
}
}
// Otherwise, try to return the player error
if let error = self.error
{
if let error = self.error {
return error as NSError?
}
+3 -6
View File
@@ -9,12 +9,9 @@
import Foundation
import AVFoundation
extension CMTime
{
var timeInterval: TimeInterval?
{
if CMTIME_IS_INVALID(self) || CMTIME_IS_INDEFINITE(self)
{
extension CMTime {
var timeInterval: TimeInterval? {
if CMTIME_IS_INVALID(self) || CMTIME_IS_INDEFINITE(self) {
return nil
}
+16 -32
View File
@@ -10,8 +10,7 @@ import UIKit
import AVKit
/// A player error
public enum PlayerError: Int
{
public enum PlayerError: Int {
case unknown
case loading
@@ -20,10 +19,8 @@ public enum PlayerError: Int
/// The associated error
///
/// - Returns: The error
public func error() -> NSError
{
switch self
{
public func error() -> NSError {
switch self {
case .unknown:
return NSError(domain: type(of: self).Domain, code: self.rawValue, userInfo: [NSLocalizedDescriptionKey: "An unknown error occurred."])
@@ -40,16 +37,14 @@ public enum PlayerError: Int
/// - loading: The player is loading or buffering
/// - ready: The player is ready for playback
/// - failed: The player has failed
@objc public enum PlayerState: Int
{
@objc public enum PlayerState: Int {
case loading
case ready
case failed
}
/// An object that adopts the PlayerDelegate protocol can receive updates from the player.
@objc public protocol PlayerDelegate: class
{
@objc public protocol PlayerDelegate: class {
func playerDidUpdateState(player: Player, previousState: PlayerState)
func playerDidUpdatePlaying(player: Player)
func playerDidUpdateTime(player: Player)
@@ -57,8 +52,7 @@ public enum PlayerError: Int
}
/// An object that adopts the Player protocol is responsible for implementing the API and calling PlayerDelegate methods where appropriate.
@objc public protocol Player: class
{
@objc public protocol Player: class {
weak var delegate: PlayerDelegate? { get set }
var state: PlayerState { get }
@@ -88,40 +82,34 @@ public enum PlayerError: Int
// MARK: Identity Protocols
/// A player that adopts the ProvidesView protocol is capable of providing a view to be added to a view hierarchy.
@objc public protocol ProvidesView
{
@objc public protocol ProvidesView {
var view: UIView { get }
}
// MARK: Capability Protocols
/// A player that adopts the ProvidesView protocol is capable of AirPlay playback.
@objc public protocol AirPlayCapable
{
@objc public protocol AirPlayCapable {
var isAirPlayEnabled: Bool { get set }
}
/// A player that adopts the ProvidesView protocol is capable of setting audio volume.
@objc public protocol VolumeCapable
{
@objc public protocol VolumeCapable {
var volume: Float { get set }
}
/// A player that adopts the ProvidesView protocol is capable of setting the video fill mode.
@objc public protocol FillModeCapable
{
@objc public protocol FillModeCapable {
var fillMode: FillMode { get set }
}
@objc public enum FillMode: Int
{
@objc public enum FillMode: Int {
case fit
case fill
}
/// The metadata that should be attached to any type of text track.
@objc public protocol TextTrackMetadata
{
@objc public protocol TextTrackMetadata {
var displayName: String { get }
var locale: Locale? { get }
// Indicates that the text track represents subtitles for the def and hard of hearing (SDH).
@@ -130,17 +118,14 @@ public enum PlayerError: Int
@objc(displayNameWithLocale:) func displayName(with locale: Locale) -> String
}
extension TextTrackMetadata
{
public func matches(_ other: TextTrackMetadata) -> Bool
{
extension TextTrackMetadata {
public func matches(_ other: TextTrackMetadata) -> Bool {
return (self.locale == other.locale && self.isSDHTrack == other.isSDHTrack)
}
}
/// A player that conforms to the TextTrackCapable protocol is capable of advertising and displaying text tracks.
@objc public protocol TextTrackCapable
{
@objc public protocol TextTrackCapable {
var selectedTextTrack: TextTrackMetadata? { get }
var availableTextTracks: [TextTrackMetadata] { get }
@@ -150,8 +135,7 @@ extension TextTrackMetadata
#if os(iOS)
/// A player that adopts the ProvidesView protocol is capable of Picture in Picture playback.
@objc public protocol PictureInPictureCapable
{
@objc public protocol PictureInPictureCapable {
@available(iOS 9.0, *)
var pictureInPictureController: AVPictureInPictureController? { get }
}
+92 -162
View File
@@ -11,19 +11,15 @@ import Foundation
import AVFoundation
import AVKit
extension AVMediaSelectionOption: TextTrackMetadata
{
public var isSDHTrack: Bool
{
extension AVMediaSelectionOption: TextTrackMetadata {
public var isSDHTrack: Bool {
return self.hasMediaCharacteristic(.describesMusicAndSoundForAccessibility) && self.hasMediaCharacteristic(.transcribesSpokenDialogForAccessibility)
}
}
/// A RegularPlayer is used to play regular videos.
@objc open class RegularPlayer: NSObject, Player, ProvidesView
{
public struct Constants
{
@objc open class RegularPlayer: NSObject, Player, ProvidesView {
public struct Constants {
public static let TimeUpdateInterval: TimeInterval = 0.1
}
@@ -36,12 +32,10 @@ extension AVMediaSelectionOption: TextTrackMetadata
/// Sets an AVAsset on the player.
///
/// - Parameter asset: The AVAsset
@objc open func set(_ asset: AVAsset)
{
@objc open func set(_ asset: AVAsset) {
// Prepare the old item for removal
if let currentItem = self.player.currentItem
{
if let currentItem = self.player.currentItem {
self.removePlayerItemObservers(fromPlayerItem: currentItem)
}
@@ -56,33 +50,27 @@ extension AVMediaSelectionOption: TextTrackMetadata
// MARK: ProvidesView
private class RegularPlayerView: UIView
{
var playerLayer: AVPlayerLayer
{
private class RegularPlayerView: UIView {
var playerLayer: AVPlayerLayer {
return self.layer as! AVPlayerLayer
}
override class var layerClass: AnyClass
{
override class var layerClass: AnyClass {
return AVPlayerLayer.self
}
func configureForPlayer(player: AVPlayer)
{
func configureForPlayer(player: AVPlayer) {
(self.layer as! AVPlayerLayer).player = player
}
}
public let view: UIView = RegularPlayerView(frame: .zero)
private var regularPlayerView: RegularPlayerView
{
private var regularPlayerView: RegularPlayerView {
return self.view as! RegularPlayerView
}
private var playerLayer: AVPlayerLayer
{
private var playerLayer: AVPlayerLayer {
return self.regularPlayerView.playerLayer
}
@@ -90,68 +78,55 @@ extension AVMediaSelectionOption: TextTrackMetadata
weak public var delegate: PlayerDelegate?
public private(set) var state: PlayerState = .ready
{
didSet
{
public private(set) var state: PlayerState = .ready {
didSet {
self.delegate?.playerDidUpdateState(player: self, previousState: oldValue)
}
}
public var duration: TimeInterval
{
public var duration: TimeInterval {
return self.player.currentItem?.duration.timeInterval ?? 0
}
public private(set) var time: TimeInterval = 0
{
didSet
{
public private(set) var time: TimeInterval = 0 {
didSet {
self.delegate?.playerDidUpdateTime(player: self)
}
}
public private(set) var bufferedTime: TimeInterval = 0
{
didSet
{
public private(set) var bufferedTime: TimeInterval = 0 {
didSet {
self.delegate?.playerDidUpdateBufferedTime(player: self)
}
}
public var playing: Bool
{
public var playing: Bool {
return self.player.rate > 0
}
public var error: NSError?
{
public var error: NSError? {
return self.player.errorForPlayerOrItem
}
public func seek(to time: TimeInterval)
{
let cmTime = CMTimeMakeWithSeconds(time, Int32(NSEC_PER_SEC))
public func seek(to time: TimeInterval) {
let cmTime = CMTimeMakeWithSeconds(time, preferredTimescale: Int32(NSEC_PER_SEC))
self.player.seek(to: cmTime)
self.time = time
}
public func play()
{
public func play() {
self.player.play()
}
public func pause()
{
public func pause() {
self.player.pause()
}
// MARK: Lifecycle
public override init()
{
public override init() {
super.init()
self.addPlayerObservers()
@@ -161,10 +136,8 @@ extension AVMediaSelectionOption: TextTrackMetadata
self.setupAirplay()
}
deinit
{
if let playerItem = self.player.currentItem
{
deinit {
if let playerItem = self.player.currentItem {
self.removePlayerItemObservers(fromPlayerItem: playerItem)
}
@@ -172,23 +145,29 @@ extension AVMediaSelectionOption: TextTrackMetadata
}
// MARK: Setup
@available(iOS 10.0, *)
public var automaticallyWaitsToMinimizeStalling: Bool {
get {
return self.player.automaticallyWaitsToMinimizeStalling
}
set {
self.player.automaticallyWaitsToMinimizeStalling = newValue
}
}
private func setupAirplay()
{
private func setupAirplay() {
self.player.usesExternalPlaybackWhileExternalScreenIsActive = true
}
// MARK: Observers
private struct KeyPath
{
struct Player
{
private struct KeyPath {
struct Player {
static let Rate = "rate"
}
struct PlayerItem
{
struct PlayerItem {
static let Status = "status"
static let PlaybackLikelyToKeepUp = "playbackLikelyToKeepUp"
static let LoadedTimeRanges = "loadedTimeRanges"
@@ -197,41 +176,35 @@ extension AVMediaSelectionOption: TextTrackMetadata
private var playerTimeObserver: Any?
private func addPlayerItemObservers(toPlayerItem playerItem: AVPlayerItem)
{
private func addPlayerItemObservers(toPlayerItem playerItem: AVPlayerItem) {
playerItem.addObserver(self, forKeyPath: KeyPath.PlayerItem.Status, options: [.initial, .new], context: nil)
playerItem.addObserver(self, forKeyPath: KeyPath.PlayerItem.PlaybackLikelyToKeepUp, options: [.initial, .new], context: nil)
playerItem.addObserver(self, forKeyPath: KeyPath.PlayerItem.LoadedTimeRanges, options: [.initial, .new], context: nil)
}
private func removePlayerItemObservers(fromPlayerItem playerItem: AVPlayerItem)
{
private func removePlayerItemObservers(fromPlayerItem playerItem: AVPlayerItem) {
playerItem.removeObserver(self, forKeyPath: KeyPath.PlayerItem.Status, context: nil)
playerItem.removeObserver(self, forKeyPath: KeyPath.PlayerItem.PlaybackLikelyToKeepUp, context: nil)
playerItem.removeObserver(self, forKeyPath: KeyPath.PlayerItem.LoadedTimeRanges, context: nil)
}
private func addPlayerObservers()
{
private func addPlayerObservers() {
self.player.addObserver(self, forKeyPath: KeyPath.Player.Rate, options: [.initial, .new], context: nil)
let interval = CMTimeMakeWithSeconds(Constants.TimeUpdateInterval, Int32(NSEC_PER_SEC))
let interval = CMTimeMakeWithSeconds(Constants.TimeUpdateInterval, preferredTimescale: Int32(NSEC_PER_SEC))
self.playerTimeObserver = self.player.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { [weak self] (cmTime) in
if let strongSelf = self, let time = cmTime.timeInterval
{
if let strongSelf = self, let time = cmTime.timeInterval {
strongSelf.time = time
}
})
}
private func removePlayerObservers()
{
private func removePlayerObservers() {
self.player.removeObserver(self, forKeyPath: KeyPath.Player.Rate, context: nil)
if let playerTimeObserver = self.playerTimeObserver
{
if let playerTimeObserver = self.playerTimeObserver {
self.player.removeTimeObserver(playerTimeObserver)
self.playerTimeObserver = nil
@@ -240,56 +213,44 @@ extension AVMediaSelectionOption: TextTrackMetadata
// MARK: Observation
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Player Item Observers
if keyPath == KeyPath.PlayerItem.Status
{
if let statusInt = change?[.newKey] as? Int, let status = AVPlayerItemStatus(rawValue: statusInt)
{
if keyPath == KeyPath.PlayerItem.Status {
if let statusInt = change?[.newKey] as? Int, let status = AVPlayerItem.Status(rawValue: statusInt) {
self.playerItemStatusDidChange(status: status)
}
}
else if keyPath == KeyPath.PlayerItem.PlaybackLikelyToKeepUp
{
if let playbackLikelyToKeepUp = change?[.newKey] as? Bool
{
else if keyPath == KeyPath.PlayerItem.PlaybackLikelyToKeepUp {
if let playbackLikelyToKeepUp = change?[.newKey] as? Bool {
self.playerItemPlaybackLikelyToKeepUpDidChange(playbackLikelyToKeepUp: playbackLikelyToKeepUp)
}
}
else if keyPath == KeyPath.PlayerItem.LoadedTimeRanges
{
if let loadedTimeRanges = change?[.newKey] as? [NSValue]
{
else if keyPath == KeyPath.PlayerItem.LoadedTimeRanges {
if let loadedTimeRanges = change?[.newKey] as? [NSValue] {
self.playerItemLoadedTimeRangesDidChange(loadedTimeRanges: loadedTimeRanges)
}
}
// Player Observers
else if keyPath == KeyPath.Player.Rate
{
if let rate = change?[.newKey] as? Float
{
else if keyPath == KeyPath.Player.Rate {
if let rate = change?[.newKey] as? Float {
self.playerRateDidChange(rate: rate)
}
}
// Fall Through Observers
else
{
else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
// MARK: Observation Helpers
private func playerItemStatusDidChange(status: AVPlayerItemStatus)
{
switch status
{
private func playerItemStatusDidChange(status: AVPlayerItem.Status) {
switch status {
case .unknown:
self.state = .loading
@@ -304,22 +265,18 @@ extension AVMediaSelectionOption: TextTrackMetadata
}
}
private func playerRateDidChange(rate: Float)
{
private func playerRateDidChange(rate: Float) {
self.delegate?.playerDidUpdatePlaying(player: self)
}
private func playerItemPlaybackLikelyToKeepUpDidChange(playbackLikelyToKeepUp: Bool)
{
private func playerItemPlaybackLikelyToKeepUpDidChange(playbackLikelyToKeepUp: Bool) {
let state: PlayerState = playbackLikelyToKeepUp ? .ready : .loading
self.state = state
}
private func playerItemLoadedTimeRangesDidChange(loadedTimeRanges: [NSValue])
{
guard let bufferedCMTime = loadedTimeRanges.first?.timeRangeValue.end, let bufferedTime = bufferedCMTime.timeInterval else
{
private func playerItemLoadedTimeRangesDidChange(loadedTimeRanges: [NSValue]) {
guard let bufferedCMTime = loadedTimeRanges.first?.timeRangeValue.end, let bufferedTime = bufferedCMTime.timeInterval else {
return
}
@@ -340,25 +297,20 @@ extension AVMediaSelectionOption: TextTrackMetadata
extension RegularPlayer: AirPlayCapable
{
public var isAirPlayEnabled: Bool
{
get
{
public var isAirPlayEnabled: Bool {
get {
return self.player.allowsExternalPlayback
}
set
{
set {
return self.player.allowsExternalPlayback = newValue
}
}
}
#if os(iOS)
extension RegularPlayer: PictureInPictureCapable
{
extension RegularPlayer: PictureInPictureCapable {
@available(iOS 9.0, *)
public var pictureInPictureController: AVPictureInPictureController?
{
public var pictureInPictureController: AVPictureInPictureController? {
return self._pictureInPictureController
}
}
@@ -366,35 +318,27 @@ extension RegularPlayer: PictureInPictureCapable
extension RegularPlayer: VolumeCapable
{
public var volume: Float
{
get
{
public var volume: Float {
get {
return self.player.volume
}
set
{
set {
self.player.volume = newValue
}
}
}
extension RegularPlayer: FillModeCapable
{
public var fillMode: FillMode
{
get
{
extension RegularPlayer: FillModeCapable {
public var fillMode: FillMode {
get {
let gravity = (self.view.layer as! AVPlayerLayer).videoGravity
return gravity == .resizeAspect ? .fit : .fill
}
set
{
set {
let gravity: AVLayerVideoGravity
switch newValue
{
switch newValue {
case .fit:
gravity = .resizeAspect
@@ -409,62 +353,48 @@ extension RegularPlayer: FillModeCapable
}
}
extension RegularPlayer: TextTrackCapable
{
public var selectedTextTrack: TextTrackMetadata?
{
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else
{
extension RegularPlayer: TextTrackCapable {
public var selectedTextTrack: TextTrackMetadata? {
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else {
return nil
}
if #available(iOS 9.0, *)
{
if #available(iOS 9.0, *) {
return self.player.currentItem?.currentMediaSelection.selectedMediaOption(in: group)
}
else
{
else {
return self.player.currentItem?.selectedMediaOption(in: group)
}
}
public var availableTextTracks: [TextTrackMetadata]
{
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else
{
public var availableTextTracks: [TextTrackMetadata] {
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else {
return []
}
return group.options
}
public func fetchTextTracks(completion: @escaping ([TextTrackMetadata], TextTrackMetadata?) -> Void)
{
public func fetchTextTracks(completion: @escaping ([TextTrackMetadata], TextTrackMetadata?) -> Void) {
self.player.currentItem?.asset.loadValuesAsynchronously(forKeys: [#keyPath(AVAsset.availableMediaCharacteristicsWithMediaSelectionOptions)]) { [weak self] in
guard let strongSelf = self, let group = strongSelf.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else
{
guard let strongSelf = self, let group = strongSelf.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else {
completion([], nil)
return
}
if #available(iOS 9.0, *)
{
if #available(iOS 9.0, *) {
completion(group.options, strongSelf.player.currentItem?.currentMediaSelection.selectedMediaOption(in: group))
}
else
{
else {
completion(group.options, strongSelf.player.currentItem?.selectedMediaOption(in: group))
}
}
}
public func select(_ textTrack: TextTrackMetadata?)
{
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else
{
public func select(_ textTrack: TextTrackMetadata?) {
guard let group = self.player.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .legible) else {
return
}
guard let track = textTrack else
{
guard let track = textTrack else {
self.player.currentItem?.select(nil, in: group)
return
}
+3 -3
View File
@@ -23,7 +23,7 @@ To run the example project, clone the repo, and run `pod install` from the Examp
## Minimum Requirements
- iOS 8.0 / tvOS 9.0
- Swift 3.2
- Swift 4.2
## Installation
@@ -62,9 +62,9 @@ player.delegate = delegate
You can create your own players by creating objects that conform to the Player protocol and call the delegate methods when appropriate.
## Author
## Questions?
Gavin King, gavin@vimeo.com
Post on [Stackoverflow](http://stackoverflow.com/questions/tagged/vimeo-ios) with the tag `vimeo-ios`. Get in touch [here](https://vimeo.com/help/contact). Interested in working at Vimeo? We're [hiring](https://vimeo.com/jobs)!
## License
-1
View File
@@ -1 +0,0 @@
Example/Pods/Pods.xcodeproj
-19
View File
@@ -1,19 +0,0 @@
general:
artifacts:
- "build/Logs"
- "PlayerKit_Example-PlayerKit-Example.log"
machine:
xcode:
version: 9.0
dependencies:
override:
- bundle install --deployment
cache_directories:
- "~/.cocoapods"
- "Example/Pods"
- "vendor/bundle"
test:
override:
- bundle exec fastlane test
+23 -2
View File
@@ -17,10 +17,10 @@ default_platform :ios
platform :ios do
before_all do
ensure_xcode_version(version: "9.0.1")
ensure_xcode_version(version: "10.2.1")
end
desc "run tests"
desc "Run tests"
lane :test do |options|
cocoapods(
@@ -43,6 +43,27 @@ platform :ios do
end
end
desc "bumps the project and podspec version"
lane :version_bump do |options|
bump_type = options[:bump_type]
version_number = options[:version_number]
if bump_type.nil? && version_number.nil?
UI.user_error!("version_bump requires you to provide a bump_type [patch|minor|major] or specific version_number. Please try again.")
end
increment_version_number(
bump_type: bump_type,
version_number: version_number,
xcodeproj: "Example/PlayerKit.xcodeproj"
)
version_bump_podspec(
bump_type: bump_type,
version_number: version_number
)
end
after_all do |lane|
end
+7 -1
View File
@@ -27,13 +27,19 @@ xcode-select --install
<td width="33%"><code>sudo gem install fastlane -NV</code></td>
</tr>
</table>
# Available Actions
## iOS
### ios test
```
fastlane ios test
```
run tests
Run tests
### ios version_bump
```
fastlane ios version_bump
```
bumps the project and podspec version
----
+21
View File
@@ -0,0 +1,21 @@
name: VimeoPlayerKit
targets:
PlayerKit:
type: framework
platform: iOS
settings:
PRODUCT_BUNDLE_IDENTIFIER: com.vimeo.playerkit
INFOPLIST_FILE: Example/PlayerKit/Info.plist
sources:
- path: PlayerKit
scheme:
testTargets:
- PlayerKitTests
PlayerKitTests:
dependencies:
- target: PlayerKit
type: bundle.unit-test
platform: iOS
sources:
- path: Example/Tests