1414#import " PlayerTypeDefines.h"
1515#import " UPlayer.h"
1616
17+ static void *AVPlayerDemoPlaybackViewControllerRateObservationContext = &AVPlayerDemoPlaybackViewControllerRateObservationContext;
18+
1719@interface PlayerEngine ()
1820{
1921 PlayState _state;
20- BOOL _playTimeEnded;
2122 dispatch_source_t _timer;
2223}
2324@property (atomic ,strong ) AVPlayer *player;
@@ -49,8 +50,6 @@ -(instancetype)init
4950 self = [super init ];
5051 if (self) {
5152
52- _playTimeEnded = TRUE ;
53-
5453 _state = playstate_stopped;
5554
5655 self.player = [[AVPlayer alloc ]init];
@@ -70,6 +69,12 @@ -(instancetype)init
7069 addObserverForEvent (self, @selector (actionPlayRandom ), EventID_to_play_random);
7170
7271
72+ /* Observe the AVPlayer "rate" property to update the scrubber control. */
73+ [self .player addObserver: self
74+ forKeyPath: @" rate"
75+ options: NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
76+ context: AVPlayerDemoPlaybackViewControllerRateObservationContext];
77+
7378
7479 NSNotificationCenter *d =[NSNotificationCenter defaultCenter ];
7580
@@ -105,8 +110,6 @@ -(instancetype)init
105110
106111-(void )DidPlayToEndTime : (NSNotification *)n
107112{
108- _playTimeEnded = TRUE ;
109-
110113 [self stopInner ];
111114
112115 postEvent (EventID_track_stopped_playnext, nil );
@@ -191,36 +194,28 @@ -(void)dealloc
191194
192195-(PlayState)getPlayState
193196{
194- if ( _playTimeEnded )
195- {
196- return playstate_stopped;
197- }
198- else
199- {
200- if (_player.rate == 0.0 )
201- {
202- return playstate_paused;
203- }
204- else
205- {
206- return playstate_playing;
207- }
208- }
197+ return _state;
209198}
210199
211200-(BOOL )isPlaying
212201{
213- return (_player.currentItem != nil ) && (_player.rate == 1.0 ) ;
202+ // NSLog(@"isPlaying");
203+ return _state == playstate_playing;
204+ // return (_player.currentItem != nil) && (_player.rate != 0.f ) ;
214205}
215206
216207-(bool )isPaused
217208{
218- return _player.rate == 0.0 ;
209+ // NSLog(@"isPaused");
210+ return _state == playstate_paused;
211+ // return _player.rate == 0.0;
219212}
220213
221214-(bool )isStopped
222215{
223- return _player.currentItem == nil ;
216+ // NSLog(@"isStopped");
217+ return _state == playstate_stopped;
218+ // return _player.currentItem == nil;
224219}
225220
226221-(bool )isPending
@@ -273,7 +268,6 @@ -(void)playPause
273268 {
274269 [_player play ];
275270 _state = playstate_playing ;
276- _playTimeEnded = FALSE ;
277271 postEvent (EventID_track_resumed, nil );
278272 }
279273
@@ -296,36 +290,53 @@ -(NSTimeInterval)currentTime
296290-(BOOL )playURL : (NSURL *)url pauseAfterInit : (BOOL )pfi
297291{
298292 AVURLAsset *asset = [AVURLAsset assetWithURL: url];
293+ AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset automaticallyLoadedAssetKeys: @[@" playable" ,@" duration" ]];
299294
300- Float64 duration = CMTimeGetSeconds (asset.duration );
301- AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset];
295+ @try {
296+ [_player replaceCurrentItemWithPlayerItem: item ];
297+ } @catch (NSException *exception) {
298+ NSLog (@" replaceCurrentItemWithPlayerItem: %@ " ,exception);
299+ } @finally {
300+ }
302301
303- NSArray *keys = @[@" playable" ];
302+ if (pfi == false )
303+ [_player play ];
304304
305- [item.asset loadValuesAsynchronouslyForKeys: keys completionHandler: ^{
306-
307- dispatch_async (dispatch_get_main_queue (), ^{
308- [_player replaceCurrentItemWithPlayerItem: item ];
309-
310- if (pfi == false )
311- [_player play ];
312-
313- _playTimeEnded = FALSE ;
314-
315- ProgressInfo *info = [[ProgressInfo alloc ]init];
316- info.total = duration;
317- postEvent (EventID_track_started, info);
318-
319- postEvent (EventID_track_state_changed, nil );
320- });
321-
322- }];
305+ ProgressInfo *info = [[ProgressInfo alloc ]init];
306+ info.total = CMTimeGetSeconds ( item.duration );
323307
308+ postEvent (EventID_track_started, info);
309+
310+ postEvent (EventID_track_state_changed, nil );
324311
325312 return 1 ;
326313}
327314
328315
316+ - (void )observeValueForKeyPath : (NSString *) path
317+ ofObject : (id )object
318+ change : (NSDictionary *)change
319+ context : (void *)context
320+ {
321+ /* AVPlayer "rate" property value observer. */
322+ if (context == AVPlayerDemoPlaybackViewControllerRateObservationContext)
323+ {
324+ [self syncPlayerRate ];
325+ }
326+ }
327+
328+ -(void )syncPlayerRate
329+ {
330+ float rate = _player.rate ;
331+ if (rate == 0 .f ) {
332+ _state = playstate_paused;
333+ }
334+ else
335+ {
336+ _state = playstate_playing;
337+ }
338+
339+ }
329340
330341-(BOOL )playURL : (NSURL *)url
331342{
@@ -337,6 +348,7 @@ -(void)stopInner
337348 [_player pause ];
338349 [_player replaceCurrentItemWithPlayerItem: nil ];
339350
351+ _state = playstate_stopped;
340352
341353 postEvent (EventID_track_stopped, nil );
342354 postEvent (EventID_track_state_changed, nil );
0 commit comments