playerItemDidReachEnd moves to wrong ViewController - objective-c

My app has a start page and a second page with buttons that play videos. When a video is finished the AVPlayer is dismissed with playerItemDidReachEnd. But for some reason it shows the start page and not the second page when the player is dismissed. How can I get it to show the second page instead?
#import "ViewController.h"
#import AVKit;
#import AVFoundation;
#interface ViewController ()
#property(nonatomic, readonly) AVPlayerItem *currentItem;
#end
#implementation ViewController
AVPlayerViewController *playerViewController;
- (void)viewDidLoad {
[super viewDidLoad];
playerViewController = [[AVPlayerViewController alloc] init];
}
-(void)playerItemDidReachEnd:(NSNotification *) notification {
//remove the player
[self dismissViewControllerAnimated:NO completion:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (IBAction)playVideo:(id)sender {
NSURL *url = [NSURL URLWithString:#"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
AVURLAsset *asset = [AVURLAsset assetWithURL: url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset];
AVPlayer * player = [[AVPlayer alloc] initWithPlayerItem: item];
playerViewController.player = player;
UIScreen *mainScreen = [UIScreen mainScreen];
CGRect viewRect = mainScreen.bounds;
playerViewController.view.frame = viewRect;
playerViewController.showsPlaybackControls = YES;
[self.view addSubview:playerViewController.view];
[player play];
/* When the player item has played to its end time we'll dismiss the controller */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:playerViewController.player.currentItem];
}
#end

If I understand your code correctly, your "second page" is ViewController.
You are adding AVPlayerViewController by [self.view addSubview:playerViewController.view];, so you need to remove this view by calling
[playerViewController.view removeFromSuperview].
After [self dismissViewControllerAnimated:NO completion:nil];, you dismiss whole ViewController, not only AVPlayerViewController.

Related

mp4 video uploaded from android not play on ios

We have an app that allows user to upload videos and images to server.
if i upload a mp4 video from android , it is not playing in ios devices.
this is my code. player status shows up readytoplay but it doesn't load up and no error comes up. vieo is playing fine with web and android.
here is video url : https://justgolive.net/assets/uploads/newrecordings/20919/19777983355a28e15326df6.mp4
NSURL *streamURL = [NSURL URLWithString:_videoUrl];
player = [AVPlayer playerWithURL:streamURL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame =self.previewView.frame;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
//CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height/1.2);
[self.previewView.layer addSublayer:playerLayer];
// [self.playerContainer setUserInteractionEnabled:NO]; //to avoid touch events when activity is on
[self.player addObserver:self forKeyPath:#"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[player currentItem]];
I have tried with your url of Video and working with below code:
header file like this:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIView *playerView;
#end
Implementation file like this:
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property (nonatomic) AVPlayer *player;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"https://justgolive.net/assets/uploads/newrecordings/20919/19777983355a28e15326df6.mp4"];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
CALayer *superlayer = self.playerView.layer;
self.player.volume = 20.0;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
[playerLayer setFrame:self.playerView.bounds];
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
playerLayer.frame = self.playerView.layer.bounds;
[superlayer addSublayer:playerLayer];
[self.player seekToTime:kCMTimeZero];
[self.player play];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Loading the same ViewController after watching MPMoviePlayerController

I have a ViewController which displays the information about the selected show, and the play button of the MPMoviePlayerController is there. Now, the issue is when I clicked on the full screen of the player then clicked done. It is supposed to go back to the ViewController which displays the info, but it isn't. But it is going in to the viewDidLoad of the ViewController and it doesn't display anything at all. I feel like something is on the top of the ViewController or something like that
Here's how I remove the player controller
- (void)dealloc
{
self.delegate = nil;
self.activityIndicator = nil;
[self deregisterMoviePlayerNotifications];
[self.player.view removeFromSuperview];
[self removeFromSuperview];
[self stopVideo];
self.player = nil;
}
You should use AVPlayerViewController as MPMoviePlayerController is deprecated. You can use this code on play button
-(void)playButton{
AVPlayer *player = [[AVPlayer alloc]initWithURL:urlVideo];
AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
controller.player = player;
controller.videoGravity = AVLayerVideoGravityResizeAspectFill;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
controller.videoGravity = AVLayerVideoGravityResizeAspect;
[self presentViewController:controller animated:YES completion:nil];
[player play];
}
-(void)playerItemDidReachEnd:(NSNotification*)notification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self dismissViewControllerAnimated:YES completion:nil];
}
Note : Don't forget to add AVFoundation.framework.

Background Video Objective-c

I want to play a loop background video in my view. I wrote this code :
-(AVPlayerLayer*)playerLayer{
if(!_playerLayer){
// find movie file
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"fond_login" ofType:#"mp4"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:[[AVPlayer alloc]initWithURL:movieURL]];
_playerLayer.frame = CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height);
[_playerLayer.player play];
return _playerLayer;
}
return nil; }
-(void)replayMovie:(NSNotification *)notification {
NSLog(#"Finis");
[self.playerLayer.player play];}
And in my viewdidload, I have :
[self.view.layer addSublayer:self.playerLayer];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(replayMovie:)
name: AVPlayerItemDidPlayToEndTimeNotification
object:nil];
My problem is that the video don't play in loop. I see the video one time and it's finish. I don't know why ..
Thank's
EDIT :
I see another tutorial.
#import MediaPlayer;
#property (nonatomic, strong) MPMoviePlayerController *moviePlayer;
My code in viewDidLoad :
NSURL *videoURL = [[NSBundle mainBundle] URLForResource:#"my_video" withExtension:#"format"];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
self.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
self.moviePlayer.view.frame = self.view.frame;[self.view insertSubview:self.moviePlayer.view atIndex:0];
[self.moviePlayer play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(loopVideo) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];
And :
- (void)loopVideo {
[self.moviePlayer play]; }
It's work perfectly.
In your replayMovie: method you need to seek back to the beginning:
- (void)replayMovie:(NSNotification *)notification {
[(AVPlayerItem *)notification.object seekToTime:kCMTimeZero];
}
You're also going to want to set the actionAtItemEnd of the AVPlayer so it doesn't pause:
_playerLayer.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

How to make MPMoviePlayerController fullscreen in landscape and not fullscreen in portrait

I have a MPMoviePlayerController that is initialized as follows:
//Code in my UIViewController
#property (nonatomic, strong) UIView *myVideoView;
#property (nonatomic, strong) MPMoviePlayerController *myVideoPlayer;
- (void) initializeVideoPlayer
{
CGRect frame = CGRectMake(0, 70, self.view.frame.size.width, 200);
self.myVideoView = [[UIView alloc] initWithFrame:frame];
[self.view addSubview:self.myVideoView];
NSURL *videoURL = [NSURL fileURLWithPath:path];
self.myVideoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
self.myVideoPlayer.controlStyle = MPMovieControlStyleEmbedded;
self.myVideoPlayer.shouldAutoplay = YES;
[self.myVideoPlayer.view setFrame: self.myVideoView.bounds];
[self.myVideoView addSubview: self.myVideoPlayer.view];
//Play video
[self.myVideoPlayer prepareToPlay];
[self.myVideoPlayer play];
}
My question is how do I get the video to play in fullscreen when the user rotates the phone to landscape and not fullscreen when the phone is in portrait.
I've tried adding the following to my UIViewController
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
[self.myVideoPlayer setFullscreen:YES animated:YES];
}
else
{
[self.myVideoPlayer setFullscreen:NO animated:YES];
}
}
However, the problem with this is that once the player is in fullscreen, the willAnimateRotationToInterfaceOrientation no longer gets called; therefore, even when the user rotates back to portrait, the video is still in fullscreen.
Try using an MPMoviePlayerViewController instead of an MPMoviePlayerController. Just initialize it in your UIViewController and use its moviePlayer property as you would with a plain MPMoviePlayerController. If you subclass MPMoviePlayerViewController you can control what's happening when the device rotates by implementing willAnimateRotationToInterfaceOrientation etc.
In AppDelegate.h:
#property(nonatomic)BOOL allowRotation;
in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RootViewController * root = [[RootViewController alloc] init];
self.window.rootViewController = root;
//add two Notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(MPVisionVideoNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(MPVisionVideoNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (void) moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
self.allowRotation = YES;
}
- (void) moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
self.allowRotation = NO;
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.allowRotation) {
return UIInterfaceOrientationMaskLandscapeRight ;
}
return UIInterfaceOrientationMaskPortrait;
}
//this can rotate the windows when to fullscreen state

How to Open Youtube video in MPMoviePlayerController and Play it

i use this method before 1 time. but Now i can not get video from this URL that direct-play YouTube video in MPMoviePlayerController.
URL = http://www.youtube.com/watch?v=JPUWNcGDyvM&feature=player_embedded
- (void)viewDidLoad
{
player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.youtube.com/watch?v=JPUWNcGDyvM&feature=player_embedded"]]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
//---play movie---
[player prepareToPlay];
[player pause];
player.view.frame = CGRectMake(0, 0, 320, 367);
[self.view addSubview:player.view];
[super viewDidLoad];
}
and My movieFinishedCallback is as Under ...
- (void) movieFinishedCallback:(NSNotification*) aNotification
{
player = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
}
Create a custom uiwebview: please follow instruction
1) Create a interface .h file named "YouTubeView.h"
#import <UIKit/UIKit.h>
#interface YouTubeView : UIWebView
{
}
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType;
#end
2) in to .m file
#import "YouTubeView.h"
#implementation YouTubeView
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType
{
NSString *strMimeType;
if([mimeType length]>0)
{
strMimeType = mimeType;
}
else
{
strMimeType =#"x-shockwave-flash"; //#"x-shockwave-mp4";
}
if (self = [super init])
{
// Create webview with requested frame size
self = [[UIWebView alloc] initWithFrame:frame];
// HTML to embed YouTube video
NSString *youTubeVideoHTML = #"<html><head>\
<body style=\"margin:0\">\
<embed id=\"yt\" src=\"%#\" type=\"application/%#\" \
width=\"%0.0f\" height=\"%0.0f\"></embed>\
</body></html>";
// Populate HTML with the URL and requested frame size
NSString *html = [NSString stringWithFormat:youTubeVideoHTML, urlString,strMimeType, frame.size.width, frame.size.height];
// Load the html into the webview
[self loadHTMLString:html baseURL:nil];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
#end
3) Import the youtubeview file in the controller where you want to play you tube video and create uiview like the code below
YouTubeView *videoVw = [[YouTubeView alloc] initWithStringAsURL:[NSString
stringWithFormat:#"%#",strNormalVdoURL] frame:CGRectMake(0,0,320,480) mimeSubType:#"x-shockwave-
flash"];
[self.view addSubview:videoVw];
[videoVw release];
videoVw = nil;
Note: Video will play in device only so check in device
if possible to open your URL into UIWebview then take a button in your class and redirect it on to the WebsiteViewController class may be it helps u
WebsiteViewController.h ///----
#interface WebsiteViewController : UIViewController <UIWebViewDelegate>
{
IBOutlet UIWebView *webView;
}
#property(nonatomic,retain) IBOutlet UIWebView *webView;
WebsiteViewController.m ///---
-(void)viewDidLoad {
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:#"url"];
[self.webView setScalesPageToFit:YES];
[self.webView loadRequest:request];
[request release];
}