Control buttons in AVPlayer and frame - ios

I have to play a series of videos in my app. I am using AVQueuePlayer to play the videos using the code:
AVQueuePlayer *queuePlayer = [[AVQueuePlayer alloc] initWithItems:items];
AVPlayerLayer *myPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:queuePlayer];
myPlayerLayer.frame = CGRectMake(0, 0, 320, 350);
[self.view.layer addSublayer:myPlayerLayer];
[self.queuePlayer play];
I am facing two issues.
When the video plays, the frame of player is not according to the given values(i.e. 0, 0, 320, 350).
No control buttons(volume,play,stop, forward etc) are being showed as they are shown when we play video with MPMediaPlayer. Am i missing something for both cases?
(I am using AVFoundation for the first time so these questions may seem stupid).
Thanks in advance.

When the video plays, the frame of player is not according to the
given values(i.e. 0, 0, 320, 350).
Apple's sample code doesn't use -playerLayerWithPlayer:. It creates a UIView subclass whose layer is an AVPlayerLayer. Perhaps there's a reason for that. I do that in my code and it works great. Take a look at the AVPlayerDemo code and try doing it that way.
No control buttons(volume,play,stop, forward etc) are being showed as
they are shown when we play video with MPMediaPlayer. Am i missing
something for both cases? (I am using AVFoundation for the first time
so these questions may seem stupid).
AVPlayer does not provide these for you. That's what MPMoviePlayerController is for. If you want controls and you want to use AVPlayer, you'll need to create and manage the controls yourself.

As an alternative to Dave's answer to your first question...
If using auto layout, you can store, as a local property, a reference to the player's layer returned by playerLayerWithPlayer: and update its frame whenever the view controller's view lays out its subviews -
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.playerLayer.frame = self.view.layer.bounds;
}
Or if you're working in a UIView subclass -
- (void)layoutSubviews
{
[super layoutSubviews];
self.playerLayer.frame = self.layer.bounds;
}
This assumes that you would like the player to fill the view; you can update the code if you have other intentions.

Related

iOS YTPlayerView force video quality

I am currently using iOS-youtube-player-helper library in our application. There is a view controller, with a YTPlayerView that has an aspect ratio of 16:9, which means it takes only a part of the screen. The video is loaded in medium and no matter how, I could not get it to play in 720P or 1080P. I am certain that these qualities are available, it's just the YTPlayerView forcing the quality based on the video player height. Because this is a library and not direct iframe embed, I cannot use "vq" parameter(specifying vq in playerVars does not seem to work), and setting the quality to be small then change it later does not work either(refer to this issue on GitHub)
Now, given the factor that I cannot make the YTPlayerView to fill up the whole screen, because of UI designing issues. So, is it possible to force the YTPlayerView to play in at least 720P? (Workarounds, changing the library code, ...)
Because this is an app that will be on App Store(and of course we don't want to have any legal disputes with google either), please don't suggest using libraries that are against the Youtube ToC such as XCDYouTubeKit
Many Thanks
I've found a workaround and this works well for me.
First of all, the problems depends by the webView size constructed inside the YTPlayerView. For example if you have a 320x200 playerView, try to forcing your video to 720hd don't work because the iFrame youtube player class re-switch to a better resolution according to your player size (in this case small quality because you have 320x200).
You can see this SO answer that explain this issue.
When you have imported the YTPlayerView class to your project you have two files: YTPlayerView.h and YTPlayerView.m
YTPlayerView.m (Update to work also on iPads)
I've change the function where the webview is initialized with a custom size (4k resolution) and to the last part I've added the possibility to scale the contents and restore the original frame, like this:
- (UIWebView *)createNewWebView {
CGRect frame = CGRectMake(0.0, 0.0, 4096.0, 2160.0); //4k resolution
UIWebView *webView = [[UIWebView alloc] initWithFrame:frame];
//UIWebView *webView = [[UIWebView alloc] initWithFrame:self.bounds];
webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
if ([self.delegate respondsToSelector:#selector(playerViewPreferredWebViewBackgroundColor:)]) {
webView.backgroundColor = [self.delegate playerViewPreferredWebViewBackgroundColor:self];
if (webView.backgroundColor == [UIColor clearColor]) {
webView.opaque = NO;
}
}
webView.scalesPageToFit = YES;
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
CGSize contentSize = webView.scrollView.contentSize;
CGSize viewSize = self.bounds.size;
float scale = viewSize.width / contentSize.width;
webView.scrollView.minimumZoomScale = scale;
webView.scrollView.maximumZoomScale = scale;
webView.scrollView.zoomScale = scale;
// center webView after scaling..
[webView setFrame:CGRectMake(0.0, self.frame.origin.y/3, 4096.0, 2160.0)];
} else {
webView.frame = self.bounds;
}
[webView reload];
return webView;
}
Hope this helps who try to use the Youtube original player in his project.
P.S.: All my tries were did with a swift project and the following vars:
var playerVars:Dictionary =
["playsinline":"1",
"autoplay":"1",
"modestbranding":"1",
"rel":"0",
"controls":"0",
"fs":"0",
"origin":"https://www.example.com",
"enablejsapi":"1",
"iv_load_policy":"3",
"showinfo":"0"]
Using the functions:
self.playerView.load(withVideoId: "Rk6_hdRtJOE", playerVars: self.playerVars)
and the follow method to force the resolution:
self.playerView.loadVideo(byId: "Rk6_hdRtJOE", startSeconds: 0.0, suggestedQuality: YTPlaybackQuality.HD720)
About iPads:
As reported by Edward in comments there was a little problem on iPads, that's because these devices seems don't apply scalesPageToFit. The goal is to check if the device is an iPad, then to scale (zooming out) the scrollView to host the little view bounds.
I've tested on my iPad air and it works. Let me know.

Play video in app instead of default player

I use the following code to play videos:
MPMoviePlayerViewController *theMovie=
[[MPMoviePlayerViewController alloc] initWithContentURL: movieURL];
theMovie.moviePlayer.repeatMode=MPMovieRepeatModeOne;
[self presentMoviePlayerViewControllerAnimated:theMovie];
This causes a the default movie player to cover the app. Instead I want the video to play inside the app itself as follows:
Can this be achieved?
You can set its frame like this:
theMovie.view.frame = CGRectMake(10, 10, 300, 300);
Then without presenting it add it as subview:
[self.view addSubview: theMovie.view];
Hope this helps.. :)
Yes, this can be achieved by using the AVPlayerLayer. Please see examples here:
"AV Foundation Programming Guide", "Putting It All Together: Playing a Video File Using AVPlayerLayer" section
A tutorial from the iosguy.com
Appuccino's "Playing Movies With AVPlayerLayer In iOS 6" video tutporial

IOS5 - How To play videos within a programatically created View?

I'm creating a game for iPad using OpenGL. I have created a view (with a simple background) grammatically using the following code:
- (void) addNewView {
UIWindow* window = [UIApplication sharedApplication].keyWindow;
UIView *polygonView = [[UIView alloc] initWithFrame: CGRectMake ( 60, 0, 900, 900)];
polygonView.backgroundColor = [UIColor blueColor];
//here play a movie:-)
[window addSubview:polygonView];
[polygonView release];
}
and i'm display it using the following code within a case switch in a window:
[self addNewView];
This all works well.
However, I need help to implement a video feature in this view, when it is displayed.
Can anyone provide me with assistance in the form of code or a link to a relevant tutorial that can aid me with this?
Take a look at:
MPMoviePlayerController Class Reference
and
MPMoviePlayerViewController Class Reference
That should get you started.

MPMoviePlayerController stops and resets the movie when user tries to play fullscreen [iOS]

I embedded a MPMoviePlayerController on my mail view. I can play/pause the movie and seek forward/backward. But when I touch the "fullscreen button" the movie stops and the playback state is set to MPMoviePlaybackStateStopped... Should the movie be played in full screen?
Here is my code:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
player.shouldAutoplay = NO;
player.movieSourceType = MPMovieSourceTypeFile;
player.controlStyle = MPMovieControlStyleEmbedded;
player.allowsAirPlay = YES;
player.view.frame = CGRectMake(xPos, yPos, width, height);
[self.view addSubview:player.view];
I found my bug: when pressing the full screen toggle button in MPMoviePlayerController's view, the method "viewWillLayoutSubviews" is invoked. I could never imagine this behavior...
I hope my experience can be useful to other developers.
Remember that any containing ViewController will have its viewWillDisappear, viewDidDisappear methods invoked when the MPMoviePlayerController goes full screen. Also, viewWillAppear and viewWillDisappear get called when it comes back from full screen.
If you have any logic in there that affects video playback behavior, it'll get called unless you use some conditional logic to see if the video is still playing.

MPMoviePlayerController showing up late with http url request

I'm developing an iPad app with 4.1 and deployment-target 3.2.
I have a UITableViewController which adds a new View to the main view if a row becomes selected.
In the UIViewController of the new view I've following code in the viewDidLoad method:
- (void)viewDidLoad
{
MPMoviePlayerController* player = [[MPMoviePlayerController alloc] initWithContentURL:movieurl];
[[self.view viewWithTag:1] addSubview:player.view];
player.view.frame = CGRectMake(0, 0, 512, 289);
[player play];
[super viewDidLoad];
}
movieurl is an URL with a http address of our CDN.
the viewWithTag:1 is a simple standard UIView with the same frame like the player.
Now, if I click on the tablerow, the new view appears with the subview (with tag 1) in it.
And the player is not showing up. After some time, when the movie is ready to play, the movieplayer shows up like wanted and starts playing the movie.
The movieplayer works fine, it only appears really lately.
Is there any way to show the movieplayer directly on the view? Just before the movie has finished preloading. The player can be in a loadingstate or something like this.
The mainpoint is, that the player shows up from beginning, so there's no empty space in the view.
Thank you for your help!
I have the same question and a comment that before I upgraded to the most recent XCode that forced me to use 4.2 as base SDK this was working fine for me. I had 4.1 iPhone and the player showed up immediately with Movie Loading... label ...
This is no longer the case after upgrade and 4.2 base sdk selection even with 3.2 as target.

Resources