Adjust Quality while streaming video with AVPlayer - ios

How can I able to set low or high quality video withstreaming video with AVPlayer?
My code is as follow:
self.videoPlayerItem = [AVPlayerItem playerItemWithURL:videoUrl];
videoPlayer = [AVPlayer playerWithPlayerItem:self.videoPlayerItem];
videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
CGRect frame = self.frame;
videoPlayerLayer = [AVPlayerLayer layer];
[videoPlayerLayer setPlayer:videoPlayer];
[videoPlayerLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
Thanks for your time

You can lower the video quality/bitrate by setting AVPlayerItem's preferredPeakBitRate.
Re-set it to zero to get the usual "highest quality/bitrate supported by your connection" behaviour.
N.B. A bitrate less than or equal to preferredPeakBitRate must be available for this to work, e.g. in an HLS stream.

Related

How to Speed up the audio Playing in MpMoviePlayerController

I am using MPMoviePlayerController in my app to play the video and audios. I want to give an option to user to play the audio/video slower/faster then the normal speed i.e 0.5x (slower then normal ), 1x (normal speed), 2x (double speed then normal.).
I want to know is there any way that i can speed up/down the MPMoviePlayerController streaming so that user can have options to listen/view the audio/video at slower/faster speed.
i found the solution to this problem myself.
When you use MPMoviePlayerController and make its instance then you have a property of MpMoviePlayerController as currentPlaybackRate. It is set to 1.0 by default means normal playing. If you sets its value to 1.5 or 2.0 then it will play the currently playing audio at that speed.
See the following code.
MPMoviePlayerController *moviePlayer = [MPMoviePlayerController alloc]init];
moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
moviePlayer.contentURL = #"http://someduumyUrl.com" ;
moviePlayer.controlStyle = MPMovieControlStyleDefault;
[moviePlayer prepareToPlay];
moviePlayer.currentPlaybackRate = 2.0 // will play the audio at double speed.

iOS AVPlayer won't play

I have the following code set up to play a video in my iOS app, but it just doesn't play. The app compiles and runs, but all I get a red frame where I positioned it. When debugging, I found that the the program doesn't even step into the last line [player play]. Also, the video runs fine in a UIWebView.
NSString *streamingString = [NSString stringWithFormat:#"http://youtu.be/...."];
AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:streamingString]];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
[layer setPlayer:player];
[layer setFrame:CGRectMake(50, 50, 400, 300)];
[layer setBackgroundColor:[UIColor redColor].CGColor];
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.view.layer addSublayer:layer];
[player play];
I am a new programmer and this is my first post to Stackoverflow, so please excuse me if I have not given enough information or am missing something obvious! Thank you so much!
assetWithURL: is often, but not always, used with a URL that points to a file already on the device, often within the bundle. If you are using an external URL, such as one on the internet, the url must resolve to a video that is in a format that the AVPlayer can understand. A URL to a YouTube web page will not work. In general, you can't play a YouTube video in AVPlayer.
Check out this document from Apple and this video on YouTube.
EDIT:
Some developers have used this library to play a YouTube video in their app. Another option is to use a UIWebView.

Using AVPlayer to view transparent video

I am trying to view a video witch has an alpha channel (the background is transparent). The only problem is that I don't seem to get how to make the background of the player transparent. I know I have to use AVplayer, but I can't access it's .view property. How can I add it to the subview and add a layer?
NSString *path = [NSString stringWithFormat:#"%#%#", [[NSBundle mainBundle] resourcePath], #"/New Project 5.m4v"];
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
moviePlayer = [[AVPlayer alloc] initWithURL:filePath];
AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:moviePlayer];
self.playerLayer.frame = self.view.bounds;
moviePlayer.view.alpha = 0.3;
[moviePlayer.layer addSublayer:playerLayer];
[moviePlayer play];
The iOS SDK does not properly support alpha channel video playback. That applies for AVFramework as well as the MediaPlayer Framework. Video material that contains an alpha channel will not work as you expect it to when using Apple's API.
And as you actually show within your code, AVPlayer does not use a UIView as its surface for playing videos but a subclass of CALayer, AVLayer.
You will need to rethink your application design or chose a different playback SDK.

Display MPMoviePlayerController during media loading

I use a MPMoviePlayerController to play audio (ex: http://www.stanford.edu/group/edcorner/uploads/podcast/ballmer090506.mp3) or video (ex: http://video.ted.com/talk/podcast/2011U/None/RicElias_2011U.mp4)
myMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:theURL];
myMoviePlayer.view.frame = CGRectMake(-80, 80, 480, 320);
myMoviePlayer.controlStyle = MPMovieControlStyleFullscreen;
myMoviePlayer.movieSourceType = MPMovieSourceTypeFile;
myMoviePlayer.scalingMode = MPMovieScalingModeAspectFit;
myMoviePlayer.useApplicationAudioSession = TRUE;
[myMoviePlayer prepareToPlay];
[myMoviePlayer play];
It works well, my only one problem is during the loading time (between 5s and 20s if I have a bad 3G reception), I have a black screen.
I would like to have MPMoviePlayerController diplayed with the "Loading..." label and the UIActiviyIndicator in his top bar during this time, like YouTube videos.
How can I do that?
Thanks.
Just use MPMoviePlayerViewController instead of MPMoviePlayerController. It should do what you want.

Fast switching between videos using AVFoundation

I'm writing an application where the user can record up to 6 video clips each with a duration of 2 seconds. When the video clips are recorded the user can play with them using 6 buttons - one for each clip. The user can then record a movie by switching between the 6 clips. The problem is that I need near instantaneous switching between the 6 clips when the user presses a button - otherwise the illusion of playing with the clips is lost - the functionality is somewhat similar to the app called CamBox in the App Store.
I first tried initializing every clip with and AVAsset in an AvPlayerItem in an AVPlayer every time the user pressed a button. The output of the player was directed at a an AVPlayerLayer in my main view. The problem is that the time it takes to load and start playing is quite long, meaning the the video lags when the user presses the buttons in rapid succession.
I the decided to try to preload all the clips using 5 AVPlayers and 5 AVPlayerLayers. The 5 PlayerLayers are inserted into my main view and when the user presses a button the currently playing AVPlayer is paused and rewound and the the currently visible AVPlayerLayer is hidden. The new AVPlayer is started and the corresponding AVPlayerLayer is shown. It works pretty ok being much faster than my first solution although not instantaneous but the problem is that I can only preload 4 clips meaning than when the user presses the button that play the last two the it lags big time. Below is my code to preload the clips
-(void)loadVideos
{
layers = [[NSMutableArray alloc] initWithCapacity:6];
players = [[NSMutableArray alloc] initWithCapacity:6];
for(int i = 1; i < 7; i++)
{
NSURL* fileURL = [NSURL fileURLWithPath:[self getFileName:i]];
AVPlayerItem* avPlayerItem = [[[AVPlayerItem alloc] initWithURL:fileURL] autorelease];
[avPlayerItem addObserver:self forKeyPath:#"status" options:0 context:nil];
AVPlayer *avPlayer = [[[AVPlayer alloc] initWithPlayerItem:avPlayerItem] autorelease];
[avPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
[avPlayer addObserver:self forKeyPath:#"currentItem" options:0 context:nil];
AVPlayerLayer* layer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
layer.frame = self.playerView.bounds;
[playerView.layer addSublayer:layer];
[layers addObject:layer];
[players addObject:avPlayer];
layer.hidden = YES;
}
}
The event handler for the 6 buttons looks like this:
- (IBAction)takeBtnClicked:(id)sender {
int tag = ((UIButton*)sender).tag;
AVPlayer* player;
AVPlayerLayer* layer;
if (layerIndex > -1) {
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player pause];
layer.hidden = YES;
[player seekToTime:kCMTimeZero];
}
layerIndex = tag-1;
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player play];
layer.hidden = NO;
}
I'm prette sure that the limitation of 4 preloaded video clips is a hardware limitation, but what is the alternative. Does anybody have any ideas?
Thanks in advance.
See my answer for iphone-smooth-transition-from-one-video-to-another, it shows a library you can use to implement this logic and an example app with 3 buttons that kick off animated clips. Each clip also has an associated sound effect.

Resources