From 9ddc639079e313929252996ef589708652ca77c6 Mon Sep 17 00:00:00 2001 From: Sebastian Roth Date: Wed, 20 Jun 2018 11:57:20 +0800 Subject: [PATCH] Support seek operation while the playback is paused. --- DLGPlayer/DLGPlayer.h | 1 + DLGPlayer/DLGPlayer.m | 56 +++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/DLGPlayer/DLGPlayer.h b/DLGPlayer/DLGPlayer.h index d89d502..aa160cc 100644 --- a/DLGPlayer/DLGPlayer.h +++ b/DLGPlayer/DLGPlayer.h @@ -21,6 +21,7 @@ typedef void (^onPauseComplete)(void); @property (nonatomic) double duration; @property (nonatomic) BOOL opened; @property (nonatomic) BOOL playing; +@property (nonatomic) BOOL seeking; @property (nonatomic) BOOL buffering; @property (nonatomic, strong) NSDictionary *metadata; diff --git a/DLGPlayer/DLGPlayer.m b/DLGPlayer/DLGPlayer.m index 7a9ea5d..0e2e412 100644 --- a/DLGPlayer/DLGPlayer.m +++ b/DLGPlayer/DLGPlayer.m @@ -239,10 +239,11 @@ - (void)startFrameReaderThread { - (void)runFrameReader { @autoreleasepool { - while (self.playing) { + while (self.playing || self.seeking) { [self readFrame]; if (self.requestSeek) { [self seekPositionInFrameReader]; + self.seeking = YES; } else { [NSThread sleepForTimeInterval:1.5]; } @@ -259,7 +260,7 @@ - (void)readFrame { double tempDuration = 0; dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, 0.02 * NSEC_PER_SEC); - while (self.playing && !self.decoder.isEOF && !self.requestSeek + while ((self.playing || self.seeking) && !self.decoder.isEOF && !self.requestSeek && (self.bufferedDuration + tempDuration) < self.maxBufferDuration) { @autoreleasepool { NSArray *fs = [self.decoder readFrames]; @@ -271,6 +272,10 @@ - (void)readFrame { if (f.type == kDLGPlayerFrameTypeVideo) { [tempVFrames addObject:f]; tempDuration += f.duration; + + if (self.seeking) { + break; + } } } @@ -286,10 +291,12 @@ - (void)readFrame { } } { - for (DLGPlayerFrame *f in fs) { - if (f.type == kDLGPlayerFrameTypeAudio) { - [tempAFrames addObject:f]; - if (!self.decoder.hasVideo) tempDuration += f.duration; + if (!self.seeking) { + for (DLGPlayerFrame *f in fs) { + if (f.type == kDLGPlayerFrameTypeAudio) { + [tempAFrames addObject:f]; + if (!self.decoder.hasVideo) tempDuration += f.duration; + } } } @@ -361,7 +368,7 @@ - (void)seekPositionInFrameReader { } - (void)render { - if (!self.playing) return; + if (!(self.playing || self.seeking)) return; BOOL eof = self.decoder.isEOF; BOOL noframes = ((self.decoder.hasVideo && self.vframes.count <= 0) || @@ -374,14 +381,16 @@ - (void)render { return; } - if (noframes && !self.notifiedBufferStart) { - self.notifiedBufferStart = YES; - NSDictionary *userInfo = @{ DLGPlayerNotificationBufferStateKey : @(self.notifiedBufferStart) }; - [[NSNotificationCenter defaultCenter] postNotificationName:DLGPlayerNotificationBufferStateChanged object:self userInfo:userInfo]; - } else if (!noframes && self.notifiedBufferStart && self.bufferedDuration >= self.minBufferDuration) { - self.notifiedBufferStart = NO; - NSDictionary *userInfo = @{ DLGPlayerNotificationBufferStateKey : @(self.notifiedBufferStart) }; - [[NSNotificationCenter defaultCenter] postNotificationName:DLGPlayerNotificationBufferStateChanged object:self userInfo:userInfo]; + if (!self.seeking) { + if (noframes && !self.notifiedBufferStart) { + self.notifiedBufferStart = YES; + NSDictionary *userInfo = @{ DLGPlayerNotificationBufferStateKey : @(self.notifiedBufferStart) }; + [[NSNotificationCenter defaultCenter] postNotificationName:DLGPlayerNotificationBufferStateChanged object:self userInfo:userInfo]; + } else if (!noframes && self.notifiedBufferStart && self.bufferedDuration >= self.minBufferDuration) { + self.notifiedBufferStart = NO; + NSDictionary *userInfo = @{ DLGPlayerNotificationBufferStateKey : @(self.notifiedBufferStart) }; + [[NSNotificationCenter defaultCenter] postNotificationName:DLGPlayerNotificationBufferStateChanged object:self userInfo:userInfo]; + } } // Render if has picture @@ -414,6 +423,7 @@ - (void)render { } } [self.view render:frame]; + self.seeking = NO; // Sync audio with video double syncTime = [self syncTime]; @@ -524,6 +534,22 @@ - (UIView *)playerView { - (void)setPosition:(double)position { self.requestSeekPosition = position; self.requestSeek = YES; + + [self.vframes removeAllObjects]; + [self.aframes removeAllObjects]; + + self.seeking = YES; + + __weak typeof(self)weakSelf = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + __strong typeof(weakSelf)strongSelf = weakSelf; + if (!strongSelf) { + return; + } + + [strongSelf render]; + [strongSelf startFrameReaderThread]; + }); } - (double)position {