1

I'm developing ebook reader based app with PDF book consists of multiple PDF pages. Each page have video icon to play video assets. I used AVPlayer to play video using AVPlayerItem and AVURLAsset(stream from URL). Its working fine for 10-15 times of playing the same or different video from the same page or different page. But after some time the video is not playing instead it show play icon with cross line.

I have used the below code.

  NSURL *videoUrl = [NSURL URLWithString:@"http://WWW.google.com/media/test_1.mp4"] 
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

NSDictionary *optionsDic = @{AVURLAssetHTTPCookiesKey : cookies};

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoUrl options:optionsDic];

AVPlayerItem *playeritem = [AVPlayerItem playerItemWithAsset:asset];

AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playeritem];

AVPlayerViewController *moviePlayerVC = [[AVPlayerViewController alloc]init];

moviePlayerVC.player = player;


dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    [self presentViewController:moviePlayerVC animated:NO completion:nil];

});
Sudheer Kolasani
  • 283
  • 5
  • 28
Anbu Mani
  • 81
  • 1
  • 4
  • why are you doing `dispatch_after`? – Rhythmic Fistman Oct 21 '16 at 01:07
  • I need some delay for presenting the video player. I have tried with out dispatch after and again also i'm facing the same issue. – Anbu Mani Oct 21 '16 at 06:58
  • Are you calling it form viewDidLoad? – Rhythmic Fistman Oct 21 '16 at 07:00
  • Add an observer for "status" and check the status you are getting while playback is failing. – abhimuralidharan Oct 24 '16 at 05:55
  • @abhi1992, Yes I added the observer for "status" and got the error message as AVFoundationErrorDomainCode=11839 "cannot decode". – Anbu Mani Oct 24 '16 at 06:54
  • Did you fix this issue? I dont have the solution for this issue.But its happening because there is a limit for the number of avplayer instances that we can use I guess. Either you are not properly destroying the player after use or it is not getting released . – abhimuralidharan Oct 24 '16 at 09:24
  • @abhi1992, I too think so but we can't get the call back action after click the done button in the AVPlayerViewController right, but in the parent view controller dealloc i released the player. – Anbu Mani Oct 25 '16 at 07:22

1 Answers1

2
Finally from the Apple AVPlayerDemo sample code I have found the code changes required. And replaced this code with the existing and its worked for me.


@interface VideoViewController : UIViewController {

    AVPlayerViewController *playerVC;
    AVPlayer* mPlayer;
    AVPlayerItem * mPlayerItem;
}
@property (strong) AVPlayerItem* mPlayerItem;
@property (readwrite, strong, setter=setPlayer:, getter=player) AVPlayer*   mPlayer;
@end

@implementation VideoViewController
@synthesize mPlayer,mPlayerItem;


-(void)viewDidLoad{
   playerVC = [[AVPlayerViewController alloc]init];
}


 - (void)presentVideoViewController:(NSURL*)linkUrl{


    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];

    NSDictionary *optionsDic = @{AVURLAssetHTTPCookiesKey : cookies};

    AVURLAsset * asset = [AVURLAsset URLAssetWithURL:linkUrl options:optionsDic];

    NSArray *requestedKeys = @[@"playable"];

    [asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
     ^{
         dispatch_async( dispatch_get_main_queue(),
                        ^{

                            for (NSString *thisKey in requestedKeys)
                            {
                                NSError *error = nil;
                                AVKeyValueStatus keyStatus = [asset statusOfValueForKey:thisKey error:&error];
                                if (keyStatus == AVKeyValueStatusFailed)
                                {
                                    //Show failed error message without presenting AVPlayerViewController//
                                    return;
                                }

                            }


                            if (!asset.playable)
                            {
                                //Show failed error message without presenting AVPlayerViewController//
                                return;
                            }
                            if (self.mPlayerItem)
                            {

                                [self.mPlayerItem removeObserver:self forKeyPath:@"status"];

                            }
                            [self.mPlayerItem addObserver:self
                                               forKeyPath:@"status"
                                                  options:0
                                                  context:nil];


                            if (!self.mPlayer)
                            {

                                [self setPlayer:[AVPlayer playerWithPlayerItem:self.mPlayerItem]];

                            }

                            if (self.player.currentItem != self.mPlayerItem)
                            {
                                [self.mPlayer replaceCurrentItemWithPlayerItem:self.mPlayerItem];

                            }


                            playerVC.player = self.mPlayer;
                            [self presentViewController:playerVC animated:NO completion:nil];
                        });
     }];


}

- (void)dealloc{

if (mPlayer) {
        [mPlayer.currentItem removeObserver:self forKeyPath:@"status"];
        [self.mPlayer pause];

        self.mPlayer = nil;
        self.mPlayerItem = nil;
        playerVC = nil;
    }


}  

Issue related reference links:

AVPlayerItem fails with AVStatusFailed and error code "Cannot Decode" Error Domain=AVFoundationErrorDomain Code=-11821 "Cannot Decode"

Community
  • 1
  • 1
Anbu Mani
  • 81
  • 1
  • 4