I have subclassed AVPlayerViewController so that I can show it in landscape mode on iPhone by overriding supportedInterfaceOrientations. This works fine. But when I click on cloud at the bottom right to select Subtitle and CC option, it opens in Portrait mode. What could be the reason?
Is there any other way to display AVPlayerViewController in landscape mode without subclassing it?
Do you mean only creating a simple Class? Because is simple, just create a new Class and add a AVLayer instead of creating an AVPlayerViewController:
NSString *videoPath = [[NSBundle mainBundle] pathForResource:#"Movie" ofType:#"mp4"];
NSURL *videoURL = [NSURL fileURLWithPath:videoPath];
AVPlayerItem * playerItem = [AVPlayerItem playerItemWithURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:playerLayer];
[player play];
Then override the right methods:
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
Related
I am doing the implementation of video splash similar to Uber in my application. I had added two buttons in the storyboard at the bottom part with equal spacing in storyboard. Now i am adding AVPlayer to play a video present in NSBundle. While running the application the video is playing but i cant see my buttons at the bottom part. Why it is happening? Please suggest..
- (void)createVideoPlayer {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"welcome_video" ofType:#"mp4"];
NSURL *url = [NSURL fileURLWithPath:filePath];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
self.player.volume = PLAYER_VOLUME;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.videoGravity = UIViewContentModeScaleToFill;
playerLayer.frame = self.playerView.layer.bounds;
[self.playerView.layer addSublayer:playerLayer];
[self.player play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
- (void)moviePlayDidEnd:(NSNotification*)notification{
AVPlayerItem *item = [notification object];
[item seekToTime:kCMTimeZero];
[self.player play];
}
The screenshot of buttons in storyboard:
The output in simulator:
You can see buttons are missing and Note: constraints of these buttons are correct and i can see them in every preview...
You need to call bringSubviewToFront to bring your Button outlet front and visible on AVPlayer after adding AVPlyer instance in your view.
[self.view bringSubviewToFront:buttonOutlet];
You can try calling bringSubviewToFront on the button after you've added the avplayer.
I have a video player. when I try to play it in full screen mode, it comes from top left corner. how can I resolve this?`
-(void)video_player:(int)index {
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:[_video_Array objectAtIndex:index] ofType: nil];
url = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVPlayerItem *currentItem = [AVPlayerItem playerItemWithURL:url];
_playerViewController = [[AVPlayerViewController alloc] init];
_playerViewController.videoGravity = AVLayerVideoGravityResize;
_playerViewController.view.frame = self.view.bounds;
_playerViewController.showsPlaybackControls = NO;
_video = [AVPlayer playerWithPlayerItem:currentItem];
_playerViewController.player = _video;
_playerViewController.view.userInteractionEnabled = false;
_playerViewController.view.backgroundColor = [UIColor whiteColor];
[_playerViewController.player play];
self.view.autoresizesSubviews = YES;
[self.view addSubview:_playerViewController.view];
}
`
I found a solution that is more simple and its working for me. Please try this,
let screenWidth = UIScreen.mainScreen().bounds.size.width;
let screenHeight = UIScreen.mainScreen().bounds.size.height'
_playerViewController.view.frame = UIView(frame: CGRect(x: 10, y: 10, width: screenWidth-20, height: screenHeight-20))
Before one is not working means please try the below code,
_playerViewController.frame = CGRectMake(10, 10, screenWidth-20, screenHeight-20)
Instead of using AVPlayerViewController, you can do the same as below :
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:self.videoURLStr] options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:playerItem];
[self.viewToPlay setPlayer:player];
[player addObserver:self forKeyPath:#"status" options:0 context:nil];
Don't forget to add - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context method in your class.
Create a subclass of UIView - PlayerView as below , and create a property of it in your VideoPlayerController class.
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface PlayerView : UIView
#property (nonatomic) AVPlayer *player;
#end
----------
#import "PlayerView.h"
#implementation PlayerView
+ (Class)layerClass {
return [AVPlayerLayer class];
}
- (AVPlayer*)player {
return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
}
#end
For full screen set your viewToPlay's frame to desired frame.
- (void)fullScreenAction:(id)sender
{
self.viewToPlay.frame = desiredFrame;
}
Check Playback from developer.apple.com - The Player View for reference.
The property "videoGravity" that you have used in your code cuts the video if set to AVLayerVideoGravityResizeAspectFill (default value is 'AVLayerVideoGravityResize'). AVPlayerViewController provides a view controller environment through which AVPlayer video is displayed to the user together with a number of controls.
These controls can be made by code in custom way as required with just few lines of code and its not at all difficult.
set the player's frame to [UIScreen mainScreen].bounds
make _playerViewController.view transfrom
[_playerViewController.view setTransform:CGAffineTransformMakeRotation(-M_PI_2)];
I want play an video in the view(6,60,412,229)
I Added below code.
cell.movieplayer = [[MPMoviePlayerController alloc]initWithContentURL:app.array1[row]];
cell.videoview.hidden=NO;
cell.img.hidden=YES;
// [[cell.movieplayer view]setFrame:CGRectMake(0.0f, 0.0f, 412.0f, 221.0f)];
cell.movieplayer.view.frame = cell.img.frame;
[cell.videoview addSubview:cell.movieplayer.view];
NSLog(#"%#",cell.movieplayer);
[cell.movieplayer play];
But video is not playing at the same position and it is playing -30 position.please help me out.
img is the image view and video view is view and both are at the same position.
In iOS 9, MPMoviePlayerViewController will be deprecated. It's probably about time to move away from it, in favour of the AVKit classes, like AVKitPlayerViewController. This could be cause for some refactoring, since AVKitPlayerViewController cannot be subclassed, but if this keeps XCDYouTubeKit working in the future (and with features like Picture-in-Picture), then it should be worth the effort in the long run.
// grab a local URL to our video
NSURL *videoURL = [NSURL URLWithString:#"Your_Url"];
// create an AVPlayer
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
// create a player view controller
AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
controller.player = player;
[player play];
// show the view controller
[self addChildViewController:controller];
[self.view addSubview:controller.view];
controller.view.frame = self.view.frame;
if you want to play the video in cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
cell.videoItem = [AVPlayerItem playerItemWithURL:url];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem];
cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer];
cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[cell.videoItem addObserver:self forKeyPath:#"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[cell.videoItem addObserver:self forKeyPath:#"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
cell.avLayer.frame = CGRectMake(5, 9, 310, 310);
[cell.contentView.layer addSublayer: cell.avLayer];
[ cell.videoPlayer play];
[cell.contentView addSubview:cell.videoActivity];
});
});
}
You probably don't want to use MPMoviePlayerController since it's old and deprecated in iOS 9.
Check out AVPlayer instead.
In my application, I'm trying to play video using URL from my server . I'm using the UITableView to display the video list and by tapping the Cell from the list, the video will play in sub view. Now I want to play the video in landscape mode.
This is the current video code.
_movieplayer = [[MPMoviePlayerController alloc]initWithContentURL: [NSURL URLWithString:[self urlencode:self.strPlayUrl]]];
[[_movieplayer view] setFrame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.view addSubview: [_movieplayer view]];
[_movieplayer setShouldAutoplay:YES];
[_movieplayer prepareToPlay];
[self.movieplayer play];
In the above code, how do I make it work so that it plays in landscape mode. Please guide me on this. Been stuck on this for a long time.
Add this to your viewcontroller with the movieplayer
#property (nonatomic, strong) MPMoviePlayerController* mpc;
- (void)setUpMPC
{
NSURL* m = [[NSBundle mainBundle] URLForResource:#"YourVideo" withExtension:#"mp4"];
MPMoviePlayerController* mp = [[MPMoviePlayerController alloc] initWithContentURL:m];
self.mpc = mp; // retain policy
self.mpc.shouldAutoplay = NO;
[self.mpc prepareToPlay];
self.mpc.view.frame = CGRectMake(50, 50, self.view.bounds.size.width, self.view.bounds.size.height);
}
-(NSUInteger)supportedInterfaceOrientations {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskLandscape;
}
Probably you should implement the shouldAutorotateToInterfaceOrientation and supportedInterfaceOrientations methods in your viewController
#property (nonatomic, strong) MPMoviePlayerController* moviePlayerController;
#pragma mark # - Init -
- (void) createAndPlayMovieForURL: (NSURL*) movieURL
{
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
[self.moviePlayerController.view setFrame: self.view.bounds];
[self.view addSubview: self.moviePlayerController.view];
[self.view bringSubviewToFront: self.overlayView];
}
#pragma mark - Rotation -
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation
{
return YES;
}
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
It's my first post, and may be it may seem incorrect.
So, I've to make rotation in cocos2d on iPad (5.1)
I use 2 different videos to each orientation.
And there I have 2 problems:
The app starts in portrait mode, and plays video normally. I call (play) the video 5-10 times, when video finishs I rotate simulator. The view rotates, BUT when I call (play) video - it shows white screen and the next message:
"WARNING: under normal conditions, _fillInQueueWithExtraSpace:ignoreExistingItems: should not be re-entered."
Then If I rotate screen again (several times) - and play it in landscape mode - it plays video well.
Also vice versa. When I start from landscape mode
The View rotating problem.
When I rotate view to the left/right landscape (from portrait) - can't rotate view backward. So I can rotate only in clockwise or counter clockwise. How to fix it?
-(id) init {
pathToVideoP = [[NSBundle mainBundle] pathForResource:#"video_portrait" ofType:#"mp4"];
pathToVideoL = [[NSBundle mainBundle] pathForResource:#"video_landscape" ofType:#"mp4"];
theMovieP = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:pathToVideoP]];
theMovieL = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL fileURLWithPath:pathToVideoL]];
}
-(void) playVideoButtonClicked {
movieButton.visible = FALSE;
if (sharedManager.isPortrait){
theMovie = theMovieP;
} else {
theMovie = theMovieL;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(movieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:[theMovie moviePlayer]];
CGSize size = [[CCDirector sharedDirector] winSize];
[[[CCDirector sharedDirector] openGLView] addSubview:theMovie.view];
player = [self.theMovie moviePlayer];
player.controlStyle = MPMovieControlStyleNone;
[theMovie moviePlayer].view.backgroundColor = [UIColor whiteColor];
theMovie.view.frame = CGRectMake(0, 0, size.width, size.height);
if (sharedManager.isPortrait) {
CGAffineTransform transform = player.view.transform;
player.view.transform = transform;
}
else if (sharedManager.changeOrientation)
{
CGAffineTransform transform = player.view.transform;
transform = CGAffineTransformRotate(transform, (-M_PI/2 ));
player.view.transform = transform;
}
sharedManager.changeOrientation = NO;
player.backgroundView.backgroundColor = [UIColor whiteColor];
theMovie.view.backgroundColor = [UIColor whiteColor];
player.view.userInteractionEnabled = NO;
player.scalingMode = MPMovieScalingModeNone;
[player play];
}
-(void) moviePreloadDidFinish:(id)sender {
}
-(void) movieFinishedCallback:(NSNotification*) aNotification {
theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
[player stop];
[theMovie.view removeFromSuperview];
movieButton.visible = TRUE;
}
Add this line of code After creating Player Object.
player = [self.theMovie moviePlayer];
player.controlStyle = MPMovieControlStyleNone;
It's necessary in below version of iOS 6.0. May be it's helpful.
[player prepareToPlay];