buffer video before playing it on iphone - ios

I'm doing some testing which during I would like to:
- Take a video that is in the app folder
- load that video to memory (buffer it)
- play the bufferd frames from the memory
All made on iPhone
Actually,
I would like to play a video from memory.
(I also want to load the video to memory by frames).
I hope it clear enough.
How can I accomplish this?
Tnx
EDIT:
Maybe I can point my question a little more..
I have a server that streams video via UDP (let's say that for the simuloation I'm using VLC to stream via UDP).
What do I have to do and implement in order to get the UDP stream from VLC and display it on the screen of my I device (of course i'm talking about writing code and not using VLC streamer :-) ).
Hope that's better and that I'll get some answers now.
Tnx

A video has to be buffered only if you receive the video from a server over internet via packets/Streams.
Else you can just play the video using below code:-
NSURL *url = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:#"yourVideo" ofType:#"yourVideoType" inDirectory:#""]];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[player view] setFrame:[self.view bounds]];
[self.view addSubview:[player view]];
[player play];
[player release];
You can implement the notification MPMoviePlayerLoadStateDidChangeNotification, if you are playing the videos after fetching over some data service.(GPRS,2G, Internet.)

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.

Playing chunck of bytes into MPMoviePlayerController on iPhone

My application is actually downloading a video I can easily read with MPMoviePlayerController. But now I have my video split and so on a segment form (meaning I receive a segment.init and then some other segments containing the video such as video_mp4_init.segment, video_mp4_0000.segment, video_mp4_0001.segment etc) in my bundle.
What I am looking for is some help about the way I need to read the bytes. So far I'm reading the same way I read a video:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"tos_mp4_media_0000" ofType:#"segment"]];
MPMoviePlayerViewController *playercontroller = [[MPMoviePlayerViewController alloc]
initWithContentURL:url];
[self presentMoviePlayerViewControllerAnimated:playercontroller];
playercontroller.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playercontroller.moviePlayer play];
A black screen launches then quit. I know MPMoviePlayer does not read .segment and I do guess this is not the way it should be done but I run out of ideas.
I'd find it a bit odd if MPMoviePlayer does not allow the reading of bytes but it might also be a problem. I can swap to another video reader if needed.
Any idea is welcome.
Edited for futher informations.

Pre-load an AVPlayer streaming video

I'm trying to play a streaming video with a AVPlayer without any network delay. Fortunately, our app has a progress screen before the screen that plays the video. I'm hoping to use some of the time on this progress screen to pre-load the video so it plays without delay on the next screen.
The most promising approach that I've come up with is to use an AVQueuePlayer to play 2 videos, the first would be a video that I play off screen (so you don't see it) and is silent, so you don't hear it. From what I've read on SO AVQueuePlayer buffers the nth+1 video when the nth video is near completion.
Here's my code to do this:
NSString *blackVideoPath = [[NSBundle mainBundle] pathForResource:#"black10-counting" ofType:#"MOV"];
AVPlayerItem *blackVideoItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:blackVideoPath]];
AVPlayerItem *realVideoItem = [AVPlayerItem playerItemWithURL:_videoWithEffectsURL];
NSArray *theItems = [NSArray arrayWithObjects:blackVideoItem, realVideoItem, nil];
AVQueuePlayer *theQueuePlayer = [AVQueuePlayer queuePlayerWithItems:theItems];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[theItems firstObject]];
AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:theQueuePlayer];
playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:playerLayer];
[theQueuePlayer play];
This does play my first video (for debugging I have a video with a counting soundtrack) but when reach the end and advance to the next screen (in playerItemDidReachEnd) my real video doesn't play immediately.
Just to make sure my URLs were correct I reversed blackVideoItem and realVideoItem in the list and I do hear the soundtrack to my "real" video.
I've searched SO a lot and it doesn't seem like there is a way to play a streaming video without a delay. I'd love to be wrong.
You may be able to do this without AVQueuePlayer.
As early as possible, create the AVPlayer with the remote asset.
Observe the AVPlayerItem (playback buffers, etc.) to make sure it has buffered enough data to play smoothly at the beginning. (See: Preloading video to play without delay)
Show your progress screen.
When the player item is ready, remove the progress screen
Depending on the network connection, you may not experience smooth playback the whole way through, but monitoring the player item should let you show some UI if your player is buffering.

MPMoviePlayerController for remote file on Amazon S3

My app allows videos to be displayed in UITableViewCells on iOS.
I'm currently storing my video files in Amazon S3 and utilizing Cloudfront. I got this code from the Apple docs:
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: myURL];
[player prepareToPlay];
[player.view setFrame: myView.bounds]; // player's frame must match parent's
[myView addSubview: player.view];
// ...
[player play];
I have implemented this code pretty much exactly into my own app. For some reason, it does not seem to work for me. I think it may have something to do with not having JWPlayer installed in my S3 bucket.
My question is: In order to display a video in the app that allows playing while loading the remaining contents of the video in the background, do I need to have JWPlayer in my S3 bucket?...or is this unnecessary given the use of MPMoviePlayerController.
Thanks!
Well the problem is that the MPMoviePlayerController can't play that file because is not streamed. [[MPMoviePlayerController alloc] initWithContentURL: myURL]; expects a network stream, in your case is not a network stream. What you could do, is download the file and save it in your app documents files and play it from there.

MPMoviePlayerController Audio show "Done" Button

I use the MPMoviePlayerController to Play an Audio Stream.
My code follows the example at:
http://iosdevelopertips.com/video/getting-mpmovieplayercontroller-to-cooperate-with-ios4-3-2-ipad-and-earlier-versions-of-iphone-sdk.html
Everything works fine, but while the stream is playing there is no "done"
button to close the Player.
I tested it first with a normal .mp3 file. With the file the only
possibility I found is to skip to the end,
so the player gets the MPMoviePlayerPlaybackDidFinishNotification
notification
(but this won't work on an endless stream, since there is no timeline to
skip to the end).
I tried various styles like [mp setControlStyle:MPMovieControlStyleFullscreen]; with no succes.
In the documentation at
MPMoviePlayerController Class stands:
This class plays any movie or audio
file supported in iOS. This includes
both streamed content and fixed-length
files
Is there a possibility to display that button while playing some audio
content, or has anyone another solution?
I tried to show you an screenshot but "new users can only post a maximum of two hyperlinks".
i found a solution by my self.
Using the MPMoviePlayerViewController class, instead of MPMoviePlayerController solved the problem:
NSString *path = #"http://yourstreamingurl.com/stream.m3u";
MPMoviePlayerViewController* mpviewController = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:path]];
mpviewController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
[self presentModalViewController:mpviewController animated:YES];
[[mpviewController moviePlayer] play];
For playing file locally, remove
mpviewController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
Other wise it will return
Terminating app due to uncaught exception NSInvalidArgumentException reason An AVPlayerItem cannot be associated with more than one instance of AVPlayer

Resources