I'm working on a IOS App (With Storyoard). I have a ViewController:
//movieViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface movieViewController : UIViewController {
MPMoviePlayerViewController *moviePlayer;
}
#property (strong, nonatomic) MPMoviePlayerViewController *moviePlayer;
-(void) playMovie;
#end
//movieViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self playMovie];
}
-(void)playMovie
{
NSString *videoPath = [[NSBundle mainBundle] pathForResource:#"movie"
ofType:#"mov"];
moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL
fileURLWithPath:videoPath]];
[self presentMoviePlayerViewControllerAnimated:moviePlayer];
}
When I run I see my viewController with a "Loading..." that takes forever.
You should call -prepareToPlay and/or -play. Per MPMoviePlayerController's documentation:
Starting in iOS 5.0, in order to facilitate finer-grained playback control, a new movie player is not automatically prepared to play.
-(IBAction)startVideo:(id)sender
{
NSURL *video = [[NSURL alloc] initWithString:#"http://www.w3schools.com/html/movie.mp4"];
MPMoviePlayerViewController *controller = [[MPMoviePlayerViewController alloc]initWithContentURL:video];
controller.view.frame = CGRectMake(20, 50, 280, 180);
controller.moviePlayer.view.center = self.view.center;
[self.view addSubview:controller.view];
[controller.moviePlayer prepareToPlay];
[controller.moviePlayer play];
}
Related
I am attempting to play a simple mp4 file full screen when a view loads. Here is the code:
I am NOT getting a video at all, but I know the viewDidLoad is being called and that there is a view present.
//
// FirstViewController.m
// WSTR Finale
//
// Created by Chris Muench on 10/6/14.
// Copyright (c) 2014 World Series of Team Roping. All rights reserved.
//
#import "WatchLiveViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#interface WatchLiveViewController ()
#end
#implementation WatchLiveViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *movieURL = [NSURL URLWithString:#"http://download.wavetlan.com/SVV/Media/HTTP/H264/Talkinghead_Media/H264_test1_Talkinghead_mp4_480x360.mp4"];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
moviePlayer.view.transform = CGAffineTransformConcat(moviePlayer.view.transform, CGAffineTransformMakeRotation(M_PI_2));
UIWindow *backgroundWindow = [[UIApplication sharedApplication] keyWindow];
[moviePlayer.view setFrame:backgroundWindow.frame];
[backgroundWindow addSubview:moviePlayer.view];
[moviePlayer play];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Try this code:
MPMoviePlayerViewController *mpvController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
mpvController.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
mpvController.moviePlayer.scalingMode = MPMovieScalingModeFill;
mpvController.view.transform = CGAffineTransformConcat(mpvController.view.transform, CGAffineTransformMakeRotation(M_PI_2));
[self presentViewController:mpvController animated:NO completion:^{
[mpvController.moviePlayer play];
}];
I think you are missing prepareToPlay. Try something like this:
...
[moviePlayer prepareToPlay];
[moviePlayer play];
I'm trying to use the library https://github.com/arturfelipet/AnimatedLogin
I created my own project and wrote exactly the same code as in their example (but in my project I used Storyboard), but the video only shows a black screen. Here's the way I create the MPMoviePlayerController:
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController () {
MPMoviePlayerController *player;
}
#property (nonatomic, strong) MPMoviePlayerController *player;
#end
#implementation ViewController
#synthesize player;
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect screen = [[UIScreen mainScreen] bounds];
NSURL *movieUrl = [[NSBundle mainBundle] URLForResource:#"background" withExtension:#"mp4"];
self.player = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
player.view.frame = screen;
player.scalingMode = MPMovieScalingModeFill;
[self.player setControlStyle:MPMovieControlStyleNone];
[self.view addSubview:player.view];
[player prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playVideo)
name:MPMoviePlayerReadyForDisplayDidChangeNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.player];
[player play];
}
- (void)moviePlayerDidFinish:(NSNotification *)note
{
if (note.object == self.player) {
NSInteger reason = [[note.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue];
if (reason == MPMovieFinishReasonPlaybackEnded)
{
[self.player play];
}
}
}
-(void)playVideo{
[player play];
}
#end
But it's only a black screen when the app shows up. I'm using this code in my LoginViewController which presents from App Delegate like this:
if (![PFUser currentUser])
self.window.rootViewController = [UIStoryboard instansiateVCWithClass:[TPLoginViewController class]];
Maybe it has to do something with that? I've tried so many things and would really appreciate an answer.
Thanks.
That is because you doing all initializing in your viewDidLoad. Which means that processing will block your screen until all the task are done completely.
Put that code in a method and call it after delay using:
[self performSelector:<#(SEL)#> withObject:<#(id)#> afterDelay:<#(NSTimeInterval)#>];
EDIT: As turned out after checking with #tracifycray, there was some problem with URL,it was turning out nil somehow. As he said, "Yes, I got it to work. I tried to use a .mov-file instead, and then it worked".
I have a 15 second animation in my app that is currently way too inefficient to be workable as it uses 1.5GB of RAM.
Am I using the animation properties of UIImageView incorrectly? Perhaps there is a different solution. All I want is for it to loop for a certain duration.
There will be improvements I can make to the 539 images to make them more efficient, but they still need to be retina size etc. Currently it is 30fps.
- (void)viewDidLoad {
[super viewDidLoad];
_animationFrames = [[NSMutableArray alloc] init];
for (long l = 0; l < 540; l++) {
NSString *frameNumber = [NSMutableString stringWithFormat:#"AnimationFrames-%04ld", l];
UIImage *frame = [UIImage imageNamed:frameNumber];
[_animationFrames addObject:frame];
}
UIImageView *animation = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
animation.animationImages = _tutorialFrames;
animation.animationDuration = 14;
[self.view addSubview: animation];
[animation startAnimating];
}
Thanks to Mirko Brunner's comments I discovered that I could use an embedded movie rather than play the animation through UIImageView, though I ended up going with AVPlayer rather than MPMoviePlayer.
#import "VideoViewController.h"
#import AVFoundation;
#interface VideoViewController ()
#property (weak, nonatomic) AVPlayer *avPlayer;
#property (weak, nonatomic) AVPlayerLayer *avPlayerLayer;
#end
#implementation VideoViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self avPlayer];
[self.avPlayer play];
}
- (AVPlayer *)avPlayer {
if (!_avPlayer) {
NSURL *url = [[NSBundle mainBundle]
URLForResource: #"Video" withExtension:#"mp4"];
_avPlayer = [AVPlayer playerWithURL:url];
_avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_avPlayer];
_avPlayerLayer.frame = self.view.layer.bounds;
[self.view.layer addSublayer: _avPlayerLayer];
_avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_avPlayer currentItem]];
}
return _avPlayer;
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}
I'd seen many people facing this issue. Have tried implementing some of their solutions (declaring a property for moviePlayer, explicitly set _moviePlayer.contentURL. But its still showing a black screen for me (iOS7).
Here's the code:
MoviePlayer.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface MoviePlayer : UIViewController
#property (nonatomic, strong) MPMoviePlayerController *moviePlayer;
#property (nonatomic,weak) NSURL *vidURL;
#end
MoviePlayer.m
#import "MoviePlayer.h"
#interface MoviePlayer ()
#end
#implementation MoviePlayer
-(void)viewDidLoad {
[super viewDidLoad];
_moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:_vidURL];
NSLog(#"%#", _vidURL);
_moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
CGAffineTransform landscapeTransform;
landscapeTransform = CGAffineTransformMakeRotation(90*M_PI/180.0f);
landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);
_moviePlayer.view.transform = landscapeTransform;
_moviePlayer.contentURL = _vidURL;
[_moviePlayer.view setFrame:self.view.bounds];
[self.view addSubview:_moviePlayer.view];
}
#end
Print out of the NSLog:
assets-library://asset/asset.mov?id=07E61ABA-3EEB-461B-B170-000E7AE3F9A8&ext=mov
Update:
vidURL passed from another viewControlelr:
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
ALAsset *asset = self.assets[indexPath.row];
ALAssetRepresentation *defaultRep = [asset defaultRepresentation];
NSURL *vidURL = [defaultRep url];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
MoviePlayer *moviePController = [storyboard instantiateViewControllerWithIdentifier:#"moviePlayer"];
moviePController.vidURL = vidURL;
[self.navigationController presentViewController:moviePController animated:YES completion:nil];
}
Try registering for MPMoviePlayerLoadStateDidChangeNotification
and MPMoviePlayerPlaybackDidFinishNotification
and use
if (self.player.loadState ==MPMoviePlaybackStateInterrupted) {
NSLog(#"MPMoviePlaybackStateInterrupted");
}else if (self.player.loadState ==MPMoviePlaybackStatePaused) {
// [self RemoveVideoCache];
NSLog(#"MPMoviePlaybackStatePaused");
}else if (self.player.loadState ==MPMoviePlaybackStateSeekingBackward) {
// [self RemoveVideoCache];
NSLog(#"MPMoviePlaybackStateSeekingBackward");
}
else if (self.player.loadState ==MPMoviePlaybackStateSeekingForward) {
NSLog(#"MPMoviePlaybackStateSeekingForward");
}else if (self.player.loadState ==MPMoviePlaybackStateStopped) {
NSLog(#"MPMoviePlaybackStateStopped");
}
Turns out I just had to play it after adding it as a subview:
[_moviePlayer play];
I'm trying to loop a local video, but I keep having issues. The iphone simulator build will succeed but the video won't play or loop. I'm in the middle of making an App that just plays a video on loop after the LaunchImage. Does it have something to do with the MPMoviePlayerController?
Here's the code:
ViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface ViewController : UIViewController
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (strong, nonatomic) MPMoviePlayerController *moviePlayer;
#end
#implementation ViewController
#synthesize moviePlayer;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString*thePath=[[NSBundle mainBundle] pathForResource:#"ColoredDiamond" ofType:#".mp4"];
NSURL*theurl=[NSURL fileURLWithPath: thePath];
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:theurl];
[self.moviePlayer.view setFrame:CGRectMake(40,197,240,160)];
[self.moviePlayer prepareToPlay];
[self.moviePlayer setShouldAutoplay:YES];
[self.view addSubview:self.moviePlayer.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playBackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/* - (void) playbackFinished: (NSNotification*) notification{
NSLog(#"playBackFinished");
if(moviePlayer){
[moviePlayer play];
}
}
*/
#end
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:theurl];
[self.moviePlayer.view setFrame:CGRectMake(40,197,240,160)];
[self.moviePlayer prepareToPlay];
[self.moviePlayer setRepeatMode:MPMovieRepeatModeOne];
[self.moviePlayer setShouldAutoplay:YES];
[self.view addSubview:self.moviePlayer.view];
RepeatMode determines how the movie player repeats the playback of the movie.
#property (nonatomic) MPMovieRepeatMode repeatMode
The default value of this property is MPMovieRepeatModeNone.
List of available repeat modes,
MPMovieRepeatModeNone,
MPMovieRepeatModeOne
Available in iOS 3.2 and later.
Related Sample Code : MoviePlayer
Declared In : MPMoviePlayerController.h