AVPlayer seekToTime: Poor performance while looping short videos - objective-c

this is my first question, but I've readed StackOverflow for years.
Well the thing is that I must concatenate a set of videos (MP4) in a particular order, and the last one must loop continuously. Okay, let's try AVFoundation.
I've defined all the elements such as AVComposition, AVURLAsset and AVPlayerItem. Then I build the AVPlayer and the AVPlayerLayer. Everything is okay and the videos are played in the correct order but... (and here comes the problem)
I can note a tiny flick when the AVPlayer passes from one video to the next one. I can ignore that one, but when AVPlayer reaches AVPlayerItem's end, and the selector is called for AVPlayerItemDidPlayToEndTimeNotification, I use seekToTime to move the reading head to the correct and then play it again. Works fine, but a GREAT flick is repeated when using seekToTime and playing again. I cannot allow that.
Does anybody know how to repeat the last asset on AVPlayerItem continuously and without flicks?
Thank you all.

Absolutely stupid,
Friends, when making video manipulation apps be sure that the videos don't have annoying black frames. That was the root of all problems. [AVPlayer seekToTime:] works perfectly.
Thanks for your time and patience

Related

How to hear sound from mpmovieplayer at a specific time using UISlider?

I'm working on an iOS movie editor project. For this editor, i use MPMoviePlayer to show the video file selected by the user.
I use custom controls, and I have a UISlider that enables the user to move the player's currentTime position. When the user touches the slider, movie is paused and its currentTime changes along with the UISlider's value.
Everything works perfectly, but now i need to let the user hear the sound at this currentTime position.
For those who know iMovie, when you move your mouse over a movie event, you see the image and hear the sound at this position, and that's what i'd like in my editor.
I've tried to call player's play method with à NSTimer to stop after 0.2 seconds, but the result is kind of messy.
Has anyone already achieved to do something like this ?
Thanks !
Best regards.
Seeking takes time; that's why you've ended up using a timer. The real problem here is that MPMoviePlayerController, while convenient because it gives you controls, is a blunt instrument; it's just a massive simplified convenience built on top of AVFoundation. But you don't need the built-in controls, so I would suggest throwing away your entire implementation and getting down to the real stuff, using AVFoundation instead (AVPlayer etc). Now you have a coherent way to seek and get a notification when the seek has completed (seekToTime:completionHandler:), so you'll be able to start playing as soon as possible. Plus, AVFoundation is the level where you'll be doing all your "editing" anyway.

Assign fastforward MPMoviePlayerController

How can i assign whats going to happen when you press fastforward or rewind?
I have a couple of youtube videos that i want to play after eachother. Therefor i need to assign these 2 buttons in the MPMoviePlayerController. i've tried to search on this subject, but have not found anything yet.
The other thing is how can i check wether a song is done, cause i want it to automatic to go forward then.
How can i do this?

MPMoviePlayerController audio/video out of sync

In my iPad App, I create an MPMoviePlayerController that plays an MP4 off of a website. In the MP4 there are people talking. In the App, I have noticed that the audio and video are out of sync by half a second or a quarter-second, perhaps. (I can tell this because I view the video in a web browser and there is no lag.)
The only clue that I have to this is that when the MPMoviePlayerController first loads up, the audio starts playing, but the video doesn't--then the video starts playing and it seems to skip a couple of frames to "catch up" to the audio...but it doesn't quite sync.
Seeing as how this class is a "black box" per the Apple Documentation, and none of the existing methods or properties come across as helpful to this problem, I'm a bit stumped. I may have to leave it how it is with the slight lag, rather than face weird workarounds. I wanted to see if anyone has experienced this before or could suggest a solution.
I'm running on Mountain Lion, latest XCode, iPad 2 with iOS 6.
The code I use to generate the controller is:
-(void) startVideoPlaying {
if (!self.theMoviePlayer) {
self.theMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
[self.bgView addSubview: self.theMoviePlayer.view];
[self.theMoviePlayer.view setFrame: movieContainer.frame]; // player's frame must match parent's
} else {
[self.theMoviePlayer setContentURL:movieURL];
}
self.theMoviePlayer.shouldAutoplay = YES;
[self.theMoviePlayer play];
}
Thanks for any help.
After a variety of tests, I must conclude that there is something wrong with the encoding on the MP4s that I have been playing. I am not a video codec guru, but I made the following tests, which tell me this:
1) Downloading the MP4, placing it into the app and loading it into the MPMoviePlayerController via a file URL. Audio still out of sync, so not a connectivity issue.
2) Finding another MP4 on the web (something off Vimeo) and streaming it into the Player. Audio synced properly, potentially something wrong with the MP4s I was attempting to play.
3) Downloading the MP4, and using Handbrake to convert it into M4V with a variety of different settings (including the iPad preset). The Audio was synced fine.
Based on this, it seems to me like there's something wrong with the file I was attempting to play rather than the player (or the player can't handle it). Unfortunately, the files I am attempting to play cannot simply be converted, they are part of a large website system and many hundreds of files would have to change, and so on. So, while I have answered my own question, I haven't solved the problem.

Is it possible play multiple clips using presentMoviePlayerViewControllerAnimated?

I have a situation where I'd like to play 2 video clips back to back using an MPMoviePlayerViewController displayed using presentMoviePlayerViewControllerAnimated.
The problem is that the modal view automatically closes itself as soon as the first movie is complete.
Has anyone found a way to do this?
Three options:
You may use MPMoviePlayerController and start the playback of the 2nd (Nth) item after the previous is complete. This however will introduce a small gap between the videos cause by identification and pre buffering of the content.
You may use AVQueuePlayer; AVQueuePlayer is a subclass of AVPlayer you use to play a number of items in sequence. See its reference for more.
You may use AVComposition for at runtime composing one video out of the two (or N) you need to play back. Note, this works only on locally stored videos and not on remote (streaming or progressive download). Then use AVPlayer for the playback.
It's not possible. If the video assets are in local file system, consider AVComposition.

Directly Record Screen on Mac

OK so I want to record the screen of a Mac directly to a .mov or .m4v. I've taken a look at Son of Grab from Apple, but I would prefer not to deal with screenshots and individual images and just work with video.
I thought there should be something in QTKit but I can't find it. I know this can be done in OpenGL, but 1) I don't know how and 2) I'd like to avoid that if possible.
Just to elaborate, I am recording from iSight using QTCaptureDeviceInput and (obviously a QTDevice) because I need to solution to work on Snow Leopard.
It seems like there should be a way to just target the screen as the input device for QTMediaTypeVideo.
Any help would be greatly appreciated.
You can use AVFoundation to do screen recording on the Mac. It's only available on 10.7 though.
You can use CGDisplayCreateImage/CGDisplayCreateImageFromRect APIs (10.6+) to obtain still images of screen and then making a movie out of them.
I'm not sure how good will be the performance though.
I have found that when faced with the question, will it be fast enough or not, just give it a try. Do a quick test by gabbing frame after frame say 1000 times and time it. CGDisplayCreateImageFromRect is not that hard to call at all. I have called it for single screen shots of the whole screen when the mouse was clicked, and it hardly slowed my mac down (only a basic dual core machine).
Apple has two samples showing the main two ways this can be done: :-
ScreenSnapshot
SonOfGrab
It would be easy to modify these to do it say 1000 times in a loop!