From 26b48313574002f7722d03e13d713d4ca7b55aca Mon Sep 17 00:00:00 2001 From: Damiano Galassi Date: Thu, 19 May 2016 13:44:52 +0200 Subject: MacGui: fallback to QTKit if a preview is not playable with AVFoundation. --- macosx/HBAVPlayer.m | 21 ++++---------- macosx/HBPlayerHUDController.m | 4 ++- macosx/HBPreviewController.m | 65 ++++++++++++++++++++++++------------------ macosx/HBQTKitPlayer.m | 61 ++++++++++++++++++--------------------- 4 files changed, 74 insertions(+), 77 deletions(-) (limited to 'macosx') diff --git a/macosx/HBAVPlayer.m b/macosx/HBAVPlayer.m index 748aa39f1..892cf17f9 100644 --- a/macosx/HBAVPlayer.m +++ b/macosx/HBAVPlayer.m @@ -40,7 +40,8 @@ typedef void (^HBPlayableObverser)(void); @property (nonatomic, strong) NSMutableSet *rateObservers; @property (nonatomic, strong) NSMutableSet *playableObservers; -@property (nonatomic, readwrite) BOOL playable; +@property (nonatomic, readwrite, getter=isPlayable) BOOL playable; +@property (nonatomic, readwrite, getter=isLoaded) BOOL loaded; @end @@ -53,20 +54,9 @@ typedef void (^HBPlayableObverser)(void); if (self) { _movie = [AVAsset assetWithURL:url];; - - if (!_movie) - { - return nil; - } - _player = [[AVPlayer alloc] init]; _layer = [CALayer layer]; - if (!_layer || !_player) - { - return nil; - } - _rateObservers = [NSMutableSet set]; _playableObservers = [NSMutableSet set]; @@ -80,6 +70,7 @@ typedef void (^HBPlayableObverser)(void); // Because we want to access our AVPlayer in our ensuing set-up, we must dispatch our handler to the main queue. dispatch_async(dispatch_get_main_queue(), ^(void) { [self _setUpPlaybackOfAsset:_movie withKeys:assetKeysToLoadAndTest]; + self.loaded = YES; }); }]; @@ -128,9 +119,9 @@ typedef void (^HBPlayableObverser)(void); } } -- (void)setPlayable:(BOOL)playable +- (void)setLoaded:(BOOL)loaded { - _playable = playable; + _loaded = loaded; for (HBPlayableObverser block in self.playableObservers) { @@ -290,7 +281,7 @@ typedef void (^HBPlayableObverser)(void); - (void)loadPlayableValueAsynchronouslyWithCompletionHandler:(nullable void (^)(void))handler; { - if (self.playable) + if (self.isLoaded) { handler(); } diff --git a/macosx/HBPlayerHUDController.m b/macosx/HBPlayerHUDController.m index ebafc95c1..3524f79e3 100644 --- a/macosx/HBPlayerHUDController.m +++ b/macosx/HBPlayerHUDController.m @@ -95,7 +95,9 @@ [self.slider setMinValue:0.0]; [self.slider setMaxValue:self.player.duration]; [self.slider setDoubleValue:0.0]; - + + self.player.volume = self.volumeSlider.floatValue; + [self.player play]; } } diff --git a/macosx/HBPreviewController.m b/macosx/HBPreviewController.m index 1db48cdcd..9c8903b7e 100644 --- a/macosx/HBPreviewController.m +++ b/macosx/HBPreviewController.m @@ -163,14 +163,13 @@ // adjust the preview slider length self.pictureHUD.pictureCount = generator.imagesCount; - [self switchStateToHUD:self.pictureHUD]; } else { self.previewView.image = nil; - self.currentHUD.view.hidden = YES; self.window.title = NSLocalizedString(@"Preview", nil); } + [self switchStateToHUD:self.pictureHUD]; } - (void)reloadPreviews @@ -305,8 +304,11 @@ for (NSViewController *controller in huds) { controller.view.hidden = YES; } - hud.view.hidden = NO; - hud.view.layer.opacity = 1.0; + if (self.generator) + { + hud.view.hidden = NO; + hud.view.layer.opacity = 1.0; + }; [self.window makeFirstResponder:hud.view]; [self startHudTimer]; @@ -544,11 +546,39 @@ } } -- (void)setUpPlaybackOfURL:(NSURL *)fileURL; +- (void)setUpPlaybackOfURL:(NSURL *)fileURL playerClass:(Class)class; { - if (self.player.isPlayable && self.currentHUD == self.encodingHUD) + NSArray *availablePlayerClasses = @[[HBAVPlayer class], [HBQTKitPlayer class]]; + + self.player = [[class alloc] initWithURL:fileURL]; + + if (self.player) { - [self switchStateToHUD:self.playerHUD]; + [self.player loadPlayableValueAsynchronouslyWithCompletionHandler:^{ + + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.player.isPlayable && self.currentHUD == self.encodingHUD) + { + [self switchStateToHUD:self.playerHUD]; + } + else + { + // Try to open the preview with the next player class. + NSUInteger idx = [availablePlayerClasses indexOfObject:class]; + if (idx != NSNotFound && (idx + 1) < availablePlayerClasses.count) + { + Class nextPlayer = availablePlayerClasses[idx + 1]; + [self setUpPlaybackOfURL:fileURL playerClass:nextPlayer]; + } + else + { + [self showAlert:fileURL]; + [self switchStateToHUD:self.pictureHUD]; + } + } + }); + + }]; } else { @@ -559,26 +589,7 @@ - (void)didCreateMovieAtURL:(NSURL *)fileURL { - if (fileURL) - { - self.player = [[HBAVPlayer alloc] initWithURL:fileURL]; - - if (self.player) - { - [self.player loadPlayableValueAsynchronouslyWithCompletionHandler:^{ - - dispatch_async(dispatch_get_main_queue(), ^{ - [self setUpPlaybackOfURL:fileURL]; - }); - - }]; - } - else - { - [self showAlert:fileURL]; - [self switchStateToHUD:self.pictureHUD]; - } - } + [self setUpPlaybackOfURL:fileURL playerClass:[HBAVPlayer class]]; } #pragma mark - Player mode diff --git a/macosx/HBQTKitPlayer.m b/macosx/HBQTKitPlayer.m index b0b608e3a..e44413f55 100644 --- a/macosx/HBQTKitPlayer.m +++ b/macosx/HBQTKitPlayer.m @@ -57,6 +57,7 @@ typedef void (^HBPlayableObverser)(void); @property (nonatomic, strong) NSTimer *timer; @property (nonatomic, readwrite, getter=isPlayable) BOOL playable; +@property (nonatomic, readwrite, getter=isLoaded) BOOL loaded; @property (nonatomic, strong) NSMutableSet *periodicObservers; @property (nonatomic, strong) NSMutableSet *rateObservers; @@ -78,38 +79,41 @@ typedef void (^HBPlayableObverser)(void); QTMovieAskUnresolvedDataRefsAttribute: @NO, QTMovieOpenForPlaybackAttribute: @YES, QTMovieIsSteppableAttribute: @YES, - QTMovieOpenAsyncRequiredAttribute: @YES, + QTMovieOpenAsyncRequiredAttribute: @NO, + QTMovieOpenAsyncOKAttribute: @NO, QTMovieApertureModeAttribute: QTMovieApertureModeClean }; _movie = [[QTMovie alloc] initWithAttributes:attributes error:&outError]; - if (!_movie) + if (_movie) { - return nil; - } - - _movie.delegate = self; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_movieRateDidChange:) - name:QTMovieRateDidChangeNotification - object:_movie]; + _movie.delegate = self; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_loadStateChanged:) - name:QTMovieLoadStateDidChangeNotification - object:_movie]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_movieRateDidChange:) + name:QTMovieRateDidChangeNotification + object:_movie]; - _layer = [QTMovieLayer layerWithMovie:_movie]; - - if (!_layer) - { - return nil; + _layer = [QTMovieLayer layerWithMovie:_movie]; } _periodicObservers = [NSMutableSet set]; _rateObservers = [NSMutableSet set]; _playableObservers = [NSMutableSet set]; + + // Can't open things async + // because of 23414 QTKit bugs. + if (_movie && _layer) + { + self.playable = YES; + [self _enableSubtitles]; + } + else + { + self.playable = NO; + } + + self.loaded = YES; } return self; @@ -121,9 +125,9 @@ typedef void (^HBPlayableObverser)(void); [self _stopMovieTimer]; } -- (void)setPlayable:(BOOL)playable +- (void)setLoaded:(BOOL)loaded { - _playable = playable; + _loaded = loaded; for (HBPlayableObverser block in self.playableObservers) { @@ -132,17 +136,6 @@ typedef void (^HBPlayableObverser)(void); [self.playableObservers removeAllObjects]; } -- (void)_loadStateChanged:(NSNotification *)notification -{ - int loadState = [[self.movie attributeForKey:QTMovieLoadStateAttribute] intValue]; - - if (loadState >= QTMovieLoadStateLoaded) - { - [self _enableSubtitles]; - self.playable = YES; - } -} - - (void)_movieRateDidChange:(NSNotification *)notification { for (HBQTKitPlayerRateObserver *observer in self.rateObservers) @@ -325,7 +318,7 @@ typedef void (^HBPlayableObverser)(void); - (void)loadPlayableValueAsynchronouslyWithCompletionHandler:(nullable void (^)(void))handler; { - if (self.playable) + if (self.isLoaded) { handler(); } -- cgit v1.2.3