AVPlayerViewController stuck on first frame of local video - ios

In one of my ViewControllers, I have an AVPlayerViewController. In my viewDidLoad I have
self.videoPlayerController = [AVPlayerViewController new];
Then, I play a video using the following method
- (void)playVideo:(NSURL*)videoURL {
[self presentViewController:self.videoPlayerController animated:YES completion:^(){
AVPlayer *player = [[AVPlayer alloc] initWithURL:videoURL];
[self.videoPlayerController setVideoGravity:AVLayerVideoGravityResizeAspect];
[self.videoPlayerController setPlayer:player];
[self.videoPlayerController.player play];
}];
}
When playing a video for the first time, the AVPlayerViewController appears, but the video is stuck on the first frame, and will not play. No audio plays either.
In iOS 10.0, the seekbar in the on screen controls show that the video is playing (it will progress to the end). In iOS 10.2 however, the seekbar is stuck at 0:00 as well.
I am experiencing this problem on iPads with iOS versions 10.0 and 10.2, however, it works in the XCode simulator (both 10.0 and 10.2).
My problem is similar in nature to this.
Also, the video plays correctly if you close the ViewController containing the AVPlayerViewController, reopen it, and attempt to play the video again.

I guess that the problem is in your video file. Try to download another video mp4 video sample. Add it to your project and try.

Related

AVPlayer video preview issue iOS 14.0.1

I am trying to play local and remote videos using AVPlayer and AVPlayerViewController but I am facing an issue. The player is playing the audio for video but not showing the preview.
It is working fine on all the iOS versions less than iOS 14.0.1.
Please help me on this issue
Here is the sample code
movieUrl = [NSURL fileURLWithPath:filePath];
AVPlayer *player = [AVPlayer playerWithURL:movieUrl];
theMoviPlayer = [[AVPlayerViewController alloc] init];
theMoviPlayer.player = player;
[self addSubview:theMoviPlayer.view];
theMoviPlayer.view.frame = self.bounds;
[theMoviPlayer.player play];
Look at this image for better understanding
I have found the actual reason of this issue. It seems that for certain non-standard encoding or fps, AVPlayer is not able to play video. I have exported the same video in correct encoding using some tool i.e, QuickTimePayer, and the video is playable now.
This issue is only producing on iOS 14.0.1, may be it is a bug/feature in AVPlayer in this update.
Conclusion:
Always check your video encoding if your video is not playing or you are just hearing only audio without any video frames.

AVPlayer blank video: playing sound but no video

This question has the same problem, but the solutions didn't work.
The AVPlayer sometimes plays a blank video: there is sound but no video.
While blank videos were played, we printed the frame and status of the player. The frame was non-zero and was correctly set. The status was also readyToPlay. The play function is also invoked on the main thread.
In other words, the frame for the player layer is valid, and the player is also ready to play. Yet no video appears, even though sound does.
The issue seems to be a timing one. If we wait 5-10 seconds before playing the video, the video works fine each time.
This issue appears on iOS 10, not iOS 8 or 9.
This thread on the Apple forums suggests it might be a bug related to
AVVideoCompositionCoreAnimationTool, which we also use.
Any solutions?
This happens more often on iPhone 7 devices than iPhone 5s devices.
Code:
fileprivate func playVideo(_ videoURL: String, prompt: String) {
// Show <playerView>
playerView.isHidden = false
// Use new video in player
playerItem = AVPlayerItem(url: URL(fileURLWithPath: videoURL))
print("STATUS: \(player.status == AVPlayerStatus.readyToPlay). FRAME: \(playerLayer.frame). MAIN THREAD: \(Thread.isMainThread)")
player.replaceCurrentItem(with: playerItem)
// Start playing video
player.seek(to: kCMTimeZero)
player.actionAtItemEnd = .none
player.play()
}
I think you need to play with a AVPlayerViewController or AVPlayerLayer.
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
//set player layer frame and attach it to our view
playerLayer.frame = self.containerView.bounds;
[self.containerView.layer addSublayer:playerLayer];
//play the video
[player play];
From Apple doc:
AVPlayer and AVPlayerItem are nonvisual objects meaning that on their
own are unable to present an asset’s video on screen. You have two
primary approaches you can use to present your video content on
screen:
AVKit: The best way to present your video content is by using the
AVKit framework’s AVPlayerViewController class in iOS and tvOS or the
AVPlayerView class in macOS. These classes present the video content,
along with playback controls and other media features giving you a
full-featured playback experience.
AVPlayerLayer: If you are building a custom interface for your player,
you use a Core Animation CALayer subclass provided by AVFoundation
called AVPlayerLayer. The player layer can be set as a view’s backing
layer or can be added directly to the layer hierarchy. Unlike
AVPlayerView and AVPlayerViewController, a player layer doesn’t
present any playback controls, but simply presents the visual content
on screen. It is up to you to build the playback transport controls to
play, pause, and seek through the media.
In case anyone encounters this issue, the problem seems related to an iOS bug. The problem doesn't occur on iOS 8/9 devices, only on new iOS 10 devices. Starting with iOS 10.2, the problem vanishes.
Unfortunately, still no programmatic solution for 10.0.x or 10.1.x.

How to play a video starting from specific point on iOS 9

I'm playing video using MPMoviePlayerController and I need to play it starting from a given point by this code:
MPMoviePlayerController *player;
[player setCurrentPlaybackTime:from];
[player setInitialPlaybackTime:from];
[player setEndPlaybackTime:to];
[player prepareToPlay];
[player play];
But it doesn't work, the video always plays from beginning.
I've seen on Apple Docs that initialPlaybackTime is deprecated in iOS 9 (as well as endPlaybackTime). Does it mean than it will not work on iOS 9? I tried to run this code on iOS 8.4, but the result is the same: the video always plays from the very beginning.
How to make it play from a given point?
Thank you!
Use AVPlayer instead of MPMoviePlayer. It will give you more control over Media playback.
See this (AVPlayer)

prevent MPMoviePlayerController from automatically playing in iOS 4.2.1

I have an MPMoviePlayerController where I load a video from a URL. In iOS 3.2.2 the video started downloading when I added it to a view, but it didn't play until I hit the play button (which is what I want). However, since iOS 4.2.1 came out, it started behaving differently; the video starts downloading and plays automatically.
Here's how I load my MPMoviePlayerController:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc]
initWithContentURL:[NSURL URLWithString:theVideo.fileUrl]];
player.view.frame = articleVideoFrame;
[mainView addSubview:player.view];
I even tried to perform a [player pause]; after the addSubview part, but it still plays automatically. Could you guys help me with this one?
Got it! I used player.shouldAutoplay = NO; and that did the trick. Documentation says it is by default YES, which explains it all. Probably in 3.2 default was NO, but has been switched in 4.2.
I have noticed some other behavior changes in video playback in 4.2.1...namely the video player does not become visible until it starts receiving the data for the movie...
In the previous versions it used to come up instantaneously with "Loading movie..." text on top.
Sometimes, the player gets stuck in when not in full screen mode, with no Done button available or not responding to touches on Pause and Zoom...
I am having other more subtle issues with the playback but I can't isolate the issue just yet...

MPMoviePlayerController: Removing ±1sec black screen, when changing contentURL?

I'm working on an iPad project where i have to play short video files one after another smoothly. For playing the videos i'm using MPMoviePlayerController. The problem i'm facing is that when i call
[self.moviePlayer setContentURL:videoURL]
it does start the next video, but there is ±1 sec delay of black screen before it starts to play the next video (the videos are read from the disk, not streamed). I need to avoid this black screen as well as the delay.
So maybe some of you also experienced this problem and have some solutions? Thanks.
Btw, for now, as to at least avoid the black screen, I capture the last frame of the ending video, show it in a UIImageView, and remove it after 1 sec delay. But i'm hoping to find a more elegant fix.
The effect you are talking about is actually a combination of two problems: a black blink when you change the video (which doesn't happen upon assigning the video for the first time) and the delay before the controller starts playing video.
I'm currently screwed with the second one and don't know how to solve yet. As for the first one, just try to use another instance of MPMoviePlayerController. I mean when a video finishes playing (you can subscribe to a corresponding notification) just remove the old player, create a new one and put video there. This way you will avoid blinking, but there will be a delay (not sure, because of loading the video or because of player creation) before the next video starts playing.
Hope this helps a bit.
Fond solution here
http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/
you need to use [self.moviePlayer prepareToPlay]; and catch MPMoviePlayerReadyForDisplayDidChangeNotification to use [self.moviePlayer play];
Old post but Googlers will still come. :)
Creating a new MPMoviePlayerController then assigning it back to my previous player worked for me, no more black screen!
...
[self playVideoWithFilename:#"video1.mp4"];
}
- (void)playVideoWithFilename:(NSString *)fileName
{
MPMoviePlayerController *player = [MPMoviePlayerController new];
_myVidPlayer = player;
player = nil;
NSURL *vidPath = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil];
[_myVidPlayer.view setBackgroundColor:[UIColor whiteColor]];
[_myVidPlayer.view setFrame:CGRectMake(0, 64, 320, 320)];
[_myVidPlayer setContentURL:vidPath];
[_myVidPlayer setControlStyle:MPMovieControlStyleNone];
[_myVidPlayer setRepeatMode:MPMovieRepeatModeOne];
[_myVidPlayer prepareToPlay];
[self.view addSubview: _myVidPlayer.view];
[_myVidPlayer play];
}
Note:
Available in iOS 2.0 and later
Deprecated in iOS 9.0
"Use AVPlayerViewController in AVKit."
I think that the problem is that the controller will fade out and back in between the movies.
You can control the background view color and contents, but I'm not sure that you can eliminate the fade in/out.

Resources