Skip to content

Commit 5c55872

Browse files
author
JmoVxia
committed
修复GCD定时器引起的bug
1 parent aba54dd commit 5c55872

File tree

21 files changed

+1120
-315
lines changed

21 files changed

+1120
-315
lines changed

CLCollectionViewController/CLCollectionViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class CLCollectionViewController: CLController {
2727
deinit {}
2828

2929
private lazy var collectionView: UICollectionView = {
30-
let width = (view.bounds.width - 30) * 0.5
30+
let width = (view.bounds.width - 20)
3131
let layout = UICollectionViewFlowLayout()
3232
layout.minimumLineSpacing = 10
3333
layout.minimumInteritemSpacing = 10

CLHomeController/Controller/CLHomeController.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Created by Chen JmoVxia on 2021/10/26.
66
//
77

8+
import AVFoundation
9+
import MobileCoreServices
810
import SnapKit
911
import UIKit
1012

@@ -58,6 +60,7 @@ extension CLHomeController {
5860
initUI()
5961
makeConstraints()
6062
initData()
63+
print("本框架基于AVPlayer封装,支持格式:\n\(getAllowedAVPlayerFileExtensions())")
6164
}
6265

6366
override func viewWillDisappear(_ animated: Bool) {
@@ -156,6 +159,13 @@ extension CLHomeController {}
156159
// MARK: - JmoVxia---私有方法
157160

158161
private extension CLHomeController {
162+
func getAllowedAVPlayerFileExtensions() -> [String] {
163+
let avTypes = AVURLAsset.audiovisualTypes()
164+
var avExtensions = avTypes.map { UTTypeCopyPreferredTagWithClass($0 as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() as String? ?? "" }
165+
avExtensions = avExtensions.filter { !$0.isEmpty }
166+
return avExtensions
167+
}
168+
159169
func pushToFrame() {
160170
navigationController?.pushViewController(CLFrameController(), animated: true)
161171
}

CLPlayer.xcodeproj/project.pbxproj

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@
483483
attributes = {
484484
BuildIndependentTargetsInParallel = 1;
485485
LastSwiftUpdateCheck = 1300;
486-
LastUpgradeCheck = 1500;
486+
LastUpgradeCheck = 1540;
487487
TargetAttributes = {
488488
5BA39B132727D147005059F5 = {
489489
CreatedOnToolsVersion = 13.0;
@@ -771,8 +771,7 @@
771771
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
772772
INFOPLIST_KEY_UIMainStoryboardFile = Main;
773773
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
774-
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
775-
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait;
774+
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
776775
LD_RUNPATH_SEARCH_PATHS = (
777776
"$(inherited)",
778777
"@executable_path/Frameworks",
@@ -801,8 +800,7 @@
801800
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
802801
INFOPLIST_KEY_UIMainStoryboardFile = Main;
803802
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
804-
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
805-
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait;
803+
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
806804
LD_RUNPATH_SEARCH_PATHS = (
807805
"$(inherited)",
808806
"@executable_path/Frameworks",

CLPlayer.xcodeproj/xcuserdata/jmovxia.xcuserdatad/xcschemes/xcschememanagement.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<key>CLPlayer.xcscheme_^#shared#^_</key>
88
<dict>
99
<key>orderHint</key>
10-
<integer>3</integer>
10+
<integer>4</integer>
1111
</dict>
1212
</dict>
1313
</dict>

CLPlayer/CLFullScreenController/CLAnimationTransitioning.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class CLAnimationTransitioning: NSObject {
5353

5454
extension CLAnimationTransitioning: UIViewControllerAnimatedTransitioning {
5555
func transitionDuration(using _: UIViewControllerContextTransitioning?) -> TimeInterval {
56-
return 0.25
56+
return 0.35
5757
}
5858

5959
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
@@ -106,7 +106,6 @@ extension CLAnimationTransitioning: UIViewControllerAnimatedTransitioning {
106106
playView.contentView.setNeedsLayout()
107107
playView.contentView.layoutIfNeeded()
108108
}) { _ in
109-
toView.transform = .identity
110109
transitionContext.completeTransition(true)
111110
UIViewController.attemptRotationToDeviceOrientation()
112111
}
@@ -122,15 +121,12 @@ extension CLAnimationTransitioning: UIViewControllerAnimatedTransitioning {
122121

123122
transitionContext.containerView.addSubview(toView)
124123
transitionContext.containerView.addSubview(fromView)
125-
fromView.addSubview(playView)
126124

127125
fromView.snp.remakeConstraints { make in
128126
make.center.equalTo(fromCenter)
129127
make.size.equalTo(fromSize)
130128
}
131-
playView.snp.remakeConstraints { make in
132-
make.edges.equalToSuperview()
133-
}
129+
134130
transitionContext.containerView.setNeedsLayout()
135131
transitionContext.containerView.layoutIfNeeded()
136132

@@ -150,8 +146,8 @@ extension CLAnimationTransitioning: UIViewControllerAnimatedTransitioning {
150146
playView.contentView.layoutIfNeeded()
151147
}) { _ in
152148
fromView.transform = .identity
153-
parentView.addArrangedSubview(playView)
154149
fromView.removeFromSuperview()
150+
parentView.addArrangedSubview(playView)
155151
transitionContext.completeTransition(true)
156152
UIViewController.attemptRotationToDeviceOrientation()
157153
}

CLPlayer/CLGCDTimer.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@
88
import UIKit
99

1010
class CLGCDTimer: NSObject {
11-
public enum State {
11+
public enum TimerState {
1212
case suspended
1313
case resumed
1414
}
1515

1616
/// 执行时间
1717
public private(set) var interval: TimeInterval!
18-
/// 延迟时间
19-
public private(set) var delaySecs: TimeInterval!
18+
/// 第一次执行延迟时间延迟时间
19+
public private(set) var initialDelay: TimeInterval!
2020
/// 队列
21-
public private(set) var serialQueue: DispatchQueue!
21+
public private(set) var queue: DispatchQueue!
2222
/// 定时器
2323
public private(set) var timer: DispatchSourceTimer!
24-
/// 是否正在运行
25-
public private(set) var state: State = .suspended
26-
/// 响应次数
27-
public private(set) var actionTimes = Int.zero
28-
/// 响应
24+
/// 运行状态
25+
public private(set) var state: TimerState = .suspended
26+
/// 执行次数
27+
public private(set) var numberOfActions = Int.zero
28+
/// 响应回调
2929
public private(set) var eventHandler: ((Int) -> Void)?
3030

3131
/// 创建定时器
@@ -37,19 +37,19 @@ class CLGCDTimer: NSObject {
3737
/// - repeats: 是否重复执行,默认true
3838
/// - action: 响应
3939
public init(interval: TimeInterval,
40-
delaySecs: TimeInterval = 0,
40+
initialDelay: TimeInterval = 0,
4141
queue: DispatchQueue = .main)
4242
{
4343
super.init()
4444
self.interval = interval
45-
self.delaySecs = delaySecs
46-
serialQueue = queue
47-
timer = DispatchSource.makeTimerSource(queue: serialQueue)
48-
timer.schedule(deadline: .now() + delaySecs, repeating: interval)
45+
self.initialDelay = initialDelay
46+
self.queue = queue
47+
timer = DispatchSource.makeTimerSource(queue: queue)
48+
timer.schedule(deadline: .now() + initialDelay, repeating: interval)
4949
timer.setEventHandler { [weak self] in
5050
guard let self = self else { return }
51-
self.actionTimes += 1
52-
self.eventHandler?(self.actionTimes)
51+
self.numberOfActions += 1
52+
self.eventHandler?(self.numberOfActions)
5353
}
5454
}
5555

@@ -63,13 +63,13 @@ class CLGCDTimer: NSObject {
6363

6464
extension CLGCDTimer {
6565
/// 开始
66-
public func start(_ handler: @escaping ((_ count: Int) -> Void)) {
66+
public func run(_ handler: @escaping ((_ numberOfActions: Int) -> Void)) {
6767
eventHandler = handler
6868
resume()
6969
}
7070

7171
/// 暂停
72-
public func suspend() {
72+
public func pause() {
7373
guard let timer = timer else { return }
7474
guard state != .suspended else { return }
7575
state = .suspended

CLPlayer/CLPlayerContentView/CLPlayerContentView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,8 @@ private extension CLPlayerContentView {
612612
}
613613

614614
func autoFadeOutTooView() {
615-
autoFadeOutTimer = CLGCDTimer(interval: 0, delaySecs: 0.25 + config.autoFadeOut)
616-
autoFadeOutTimer?.start { [weak self] _ in
615+
autoFadeOutTimer = CLGCDTimer(interval: 0, initialDelay: 0.25 + config.autoFadeOut)
616+
autoFadeOutTimer?.run { [weak self] _ in
617617
self?.hiddenToolView()
618618
}
619619
}

CLPlayer/CLPlayerView.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ private extension CLPlayerView {
224224
currentDuration = totalDuration
225225
playbackProgress = 1.0
226226
contentView.playState = .ended
227-
sliderTimer?.suspend()
227+
sliderTimer?.pause()
228228
DispatchQueue.main.async {
229229
self.playToEndHandler?()
230230
}
@@ -269,7 +269,7 @@ private extension CLPlayerView {
269269
totalDuration = TimeInterval(playerItem.duration.value) / TimeInterval(playerItem.duration.timescale)
270270

271271
sliderTimer = CLGCDTimer(interval: 0.1)
272-
sliderTimer?.start { [weak self] _ in
272+
sliderTimer?.run { [weak self] _ in
273273
self?.sliderTimerAction()
274274
}
275275

@@ -323,13 +323,13 @@ private extension CLPlayerView {
323323
guard contentView.playState != .failed else { return }
324324

325325
player?.pause()
326-
sliderTimer?.suspend()
327-
bufferTimer = nil
326+
sliderTimer?.pause()
328327

329328
contentView.playState = .buffering
330-
bufferTimer = CLGCDTimer(interval: 0, delaySecs: 3.0)
331-
bufferTimer?.start { [weak self] _ in
329+
bufferTimer = CLGCDTimer(interval: 3.0, initialDelay: 3.0)
330+
bufferTimer?.run { [weak self] _ in
332331
guard let playerItem = self?.playerItem else { return }
332+
self?.bufferTimer = nil
333333
if playerItem.isPlaybackLikelyToKeepUp {
334334
self?.play()
335335
} else {
@@ -351,17 +351,19 @@ private extension CLPlayerView {
351351

352352
private extension CLPlayerView {
353353
func dismiss() {
354+
guard Thread.isMainThread else { return DispatchQueue.main.async { self.dismiss() } }
354355
guard contentView.screenState == .fullScreen else { return }
355356
guard let controller = fullScreenController else { return }
356357
contentView.screenState = .animating
357358
controller.dismiss(animated: true, completion: {
358359
self.contentView.screenState = .small
360+
self.fullScreenController = nil
361+
UIViewController.attemptRotationToDeviceOrientation()
359362
})
360-
fullScreenController = nil
361-
UIViewController.attemptRotationToDeviceOrientation()
362363
}
363364

364365
func presentWithOrientation(_ orientation: CLAnimationTransitioning.CLAnimationOrientation) {
366+
guard Thread.isMainThread else { return DispatchQueue.main.async { self.presentWithOrientation(orientation) } }
365367
guard superview != nil else { return }
366368
guard fullScreenController == nil else { return }
367369
guard contentView.screenState == .small else { return }
@@ -404,6 +406,7 @@ extension CLPlayerView {
404406
player?.rate = rate
405407
sliderTimer?.resume()
406408
waitReadyToPlayState = .nomal
409+
bufferTimer = nil
407410
}
408411

409412
func pause() {
@@ -413,7 +416,7 @@ extension CLPlayerView {
413416
}
414417
contentView.playState = .pause
415418
player?.pause()
416-
sliderTimer?.suspend()
419+
sliderTimer?.pause()
417420
bufferTimer = nil
418421
waitReadyToPlayState = .nomal
419422
}

Podfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ target 'CLPlayer' do
99
inhibit_all_warnings!
1010
pod 'SnapKit'
1111
pod 'SwiftFormat/CLI'
12+
pod 'LookinServer', :subspecs => ['Swift'], :configurations => ['Debug']
1213
end
1314

1415
post_install do |installer|

Podfile.lock

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
PODS:
2+
- LookinServer/Core (1.2.4)
3+
- LookinServer/Swift (1.2.4):
4+
- LookinServer/Core
25
- SnapKit (5.6.0)
36
- SwiftFormat/CLI (0.52.8)
47

58
DEPENDENCIES:
9+
- LookinServer/Swift
610
- SnapKit
711
- SwiftFormat/CLI
812

913
SPEC REPOS:
1014
https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
15+
- LookinServer
1116
- SnapKit
1217
- SwiftFormat
1318

1419
SPEC CHECKSUMS:
20+
LookinServer: 00c7588043ed8e7ab64ce55b9fb747e51371ad06
1521
SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25
1622
SwiftFormat: e60dbe6a704faf75f3089744e5f508aae0be4ad5
1723

18-
PODFILE CHECKSUM: c0c00e0561d0fe1bf93e289b8b78eeeded153d95
24+
PODFILE CHECKSUM: ef8371675a67d45b1e997f6d8c113acea73d85d7
1925

20-
COCOAPODS: 1.13.0
26+
COCOAPODS: 1.15.2

0 commit comments

Comments
 (0)