-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathRemoteCommandExample.swift
176 lines (155 loc) · 6.82 KB
/
RemoteCommandExample.swift
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//
// RemoteCommandExample.swift
// ModernAVPlayer_Example
//
// Created by ankierman on 18/12/2018.
// Copyright © 2018 CocoaPods. All rights reserved.
//
import Foundation
import MediaPlayer
import ModernAVPlayer
public struct RemoteCommandFactoryExample {
// MARK: - Output
/// Return all factory commands
///
public var defaultCommands: [ModernAVPlayerRemoteCommand] {
return [playCommand(), pauseCommand(), stopCommand(), togglePlayPauseCommand(),
changePositionCommand(), skipBackwardCommand(), skipForwardCommand()
]
}
// MARK: - Inputs
private unowned let player: ModernAVPlayerExposable
private let commandCenter: MPRemoteCommandCenter
// MARK: - Init
public init(player: ModernAVPlayerExposable,
commandCenter: MPRemoteCommandCenter = MPRemoteCommandCenter.shared()) {
self.player = player
self.commandCenter = commandCenter
}
// MARK: - Playback Commands
/// Default play command
///
public func playCommand() -> ModernAVPlayerRemoteCommand {
let command = commandCenter.playCommand
let isEnabled: (MediaType) -> Bool = { _ in true }
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { _ in
guard let media = self.player.currentMedia
else { return .noSuchContent }
guard case let .stream(isLive) = media.type, isLive
else { self.player.play(); return .success }
self.player.load(media: media, autostart: true, position: nil)
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Play",
isEnabled: isEnabled)
}
/// Default toggle play pause command
///
public func togglePlayPauseCommand() -> ModernAVPlayerRemoteCommand {
let command = commandCenter.togglePlayPauseCommand
let isEnabled: (MediaType) -> Bool = { _ in true }
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { _ in
switch self.player.state {
case .buffering, .loading, .playing:
self.player.pause()
case .failed, .initialization, .waitingForNetwork:
return .noSuchContent
case .loaded, .paused, .stopped:
self.player.play()
}
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Toggle play/pause",
isEnabled: isEnabled)
}
/// Default pause command
///
public func pauseCommand() -> ModernAVPlayerRemoteCommand {
let command = commandCenter.pauseCommand
let isEnabled: (MediaType) -> Bool = {
guard case .stream(let isLive) = $0, isLive else { return true }
return false
}
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { _ in
self.player.pause()
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Pause",
isEnabled: isEnabled)
}
/// Default stop command
///
public func stopCommand() -> ModernAVPlayerRemoteCommand {
let command = commandCenter.stopCommand
let isEnabled: (MediaType) -> Bool = {
guard case .stream(let isLive) = $0, isLive else { return false }
return true
}
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { _ in
self.player.stop()
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Stop",
isEnabled: isEnabled)
}
// MARK: - Navigating a track's contents
/// Default change position command
///
public func changePositionCommand() -> ModernAVPlayerRemoteCommand {
let command = commandCenter.changePlaybackPositionCommand
let isEnabled: (MediaType) -> Bool = { $0 == .clip }
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { event in
guard let e = event as? MPChangePlaybackPositionCommandEvent
else { return .commandFailed }
let position = e.positionTime
self.player.seek(position: position)
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Change positions",
isEnabled: isEnabled)
}
public func skipBackwardCommand(preferredIntervals: [NSNumber] = [15]) -> ModernAVPlayerRemoteCommand {
let command = commandCenter.skipBackwardCommand
command.preferredIntervals = preferredIntervals
let isEnabled: (MediaType) -> Bool = { $0 == .clip }
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { event in
guard
let skipTime = (event as? MPSkipIntervalCommandEvent)?.interval
else { return .commandFailed }
let position = max(self.player.currentTime - skipTime, 0)
self.player.seek(position: position)
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Skip backward",
isEnabled: isEnabled)
}
public func skipForwardCommand(preferredIntervals: [NSNumber] = [30]) -> ModernAVPlayerRemoteCommand {
let command = commandCenter.skipForwardCommand
command.preferredIntervals = preferredIntervals
let isEnabled: (MediaType) -> Bool = { $0 == .clip }
let handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus = { event in
guard
let skipTime = (event as? MPSkipIntervalCommandEvent)?.interval
else { return .commandFailed }
let position = self.player.currentTime + skipTime
self.player.seek(position: position)
return .success
}
command.addTarget(handler: handler)
return ModernAVPlayerRemoteCommand(reference: command,
debugDescription: "Skip forward",
isEnabled: isEnabled)
}
}