I am using the MPMoviePlayerController to play video stored in main bundle.
However sometime when I play video it plays the video but shows the black screen in that case seek bar also works properly.
At that time if I switch to fullscreen mode and get back to normal mode(or send app in background mode and bring it in foreground mode) then it plays(resumes) video properly(did not show the black screen).
Please refer the below screenshot of an App:
UPDATE:
Below is the code used to play video:
- (void)playVideo:(NSString *)filepath {
NSLog(#"get audiosession");
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil ];
NSLog(#"finish audiosession");
appDelegate.currentCourseNoExt = [filepath stringByDeletingPathExtension];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#.mp3",appDelegate.currentCourseNoExt]];
NSError *error;
NSLog(#"get avaudioplayer");
AVAudioPlayer *avPlayerTemp = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
NSLog(#"finish avaudioplayer");
avPlayer = avPlayerTemp;
NSLog(#"copy avaudioplayer");
// get frame
CGRect frame = self.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size.height -= 0;
NSLog(#"self.view.frame - %#",NSStringFromCGRect(self.view.frame));
appDelegate.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:filepath]];
appDelegate.moviePlayer.view.frame = frame;
appDelegate.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:appDelegate.moviePlayer.view];
[self.view sendSubviewToBack:(appDelegate.moviePlayer.view)];
imgBottomAdvertisement.frame = CGRectMake(0, appDelegate.moviePlayer.view.frame.size.height - imgBottomAdvertisement.frame.size.height, imgBottomAdvertisement.frame.size.width, imgBottomAdvertisement.frame.size.height);
[appDelegate.moviePlayer.backgroundView addSubview:imgBottomAdvertisement];
appDelegate.moviePlayer.currentPlaybackRate= 1.0;
appDelegate.moviePlayer.currentPlaybackTime = appDelegate.SMile.doubleValue;
[avPlayer setRate:0];
[appDelegate.moviePlayer play ];
[avPlayer play];
}
The above method is called from viewDidAppear method of ViewController.
Related
for my app I want the user to record a video which will be stored in the caches directory for repeated use throughout the application.
NSString *DestFilename = # "output.mov";
//Set the file save to URL
NSLog(#"Starting recording to file: %#", DestFilename);
NSString *DestPath;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
DestPath = [paths objectAtIndex:0];
DestPath = [DestPath stringByAppendingPathComponent:DestFilename];
NSURL* saveLocationURL = [[NSURL alloc] initFileURLWithPath:DestPath];
[MovieFileOutput startRecordingToOutputFileURL:saveLocationURL recordingDelegate:self];
The NSLog says:
url = file:///var/mobile/Containers/Data/Application/BD41ABB0-77BA-4872-B447-07906A3C6FA7/Library/Caches/output.mov
How can I load or possibly embed this video into one of the ViewControllers in my storyboard?
Basically, your video URL is there, so you can load the video into your view controller and play it in 2 possible approaches: using MPMoviePlayerController or AVPlayer
For example from your view controller
//The first approach
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:saveLocationURL];
[self.moviePlayerController.view setFrame: CGRectMake(0, 0, 1024, 768)];
[self.view addSubview:self.moviePlayerController.view];
[self.moviePlayerController play];
//The second approach
self.playerItem = [AVPlayerItem playerItemWithURL:saveLocationURL];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
layer.frame = CGRectMake(0, 0, 1024, 768);
[self.view.layer addSublayer:layer];
[self.player play];
Hope this will help you.
I am new to Xcode,please help me out. I added AVPlayer in View Controller in IOS app.It displays Video in view But without audio. Any help anybody
Advance thank you
the reason you audio is mute because you might have not initialize AVAudioSession Check this out ..
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
UIView *myView = previewView;
videoController = [[MPMoviePlayerViewController alloc]initWithContentURL:videoPlayUrl];
videoController.view.frame = myView.bounds;
[videoController.view setBounds:previewView.bounds];
videoController.moviePlayer.controlStyle = MPMovieControlStyleNone;
videoController.moviePlayer.scalingMode = MPMovieScalingModeFill;
videoController.moviePlayer.shouldAutoplay = NO;
videoController.view.clipsToBounds = YES;
[previewView.layer addSublayer:videoController.view.layer];
[videoController.moviePlayer prepareToPlay];
I am trying to make a background music in my game with AVAudioPlayer, so I set this code at the initWithSize method of my SKScene:
//SETTING BACKGROUND MUSIC//
NSError * err = nil;
NSURL * musicFile = [[NSBundle mainBundle] URLForResource:#"Cosmic Rush" withExtension:#"m4a"];
music = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:&err];
if(err)
{
NSLog(#"%#", [err userInfo]);
return;
}
[music prepareToPlay];
music.numberOfLoops = -1;
[music setVolume:0.5];
//SETTING BACKGROUND MUSIC//
Then, in another method: [music play]; However, the sound never plays, and I have tried all sort of extensions: .mp3, .caf, .mp4 etc. I have also checked people who had the same problem, but none of the solutions that solved their problems worked with mine.
there is a easier way to add background music to your scene. i use the following steps and works just as good as any other methods and it is easier.
import the #import AVFoundation; at the top of your scene.
add it as a property right after your #implementation.
AVAudioPlayer *_backgroundMusicPlayer;
then declare a method for the music
- (void)playBackgroundMusic:(NSString *)filename
{
NSError *error;
NSURL *backgroundMusicURL =
[[NSBundle mainBundle] URLForResource:filename
withExtension:nil];
_backgroundMusicPlayer =
[[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundMusicURL error:&error];
_backgroundMusicPlayer.numberOfLoops = -1;
[_backgroundMusicPlayer prepareToPlay];
[_backgroundMusicPlayer play];
}
after that create a reference to that method in your -(id)initWithSize:(CGSize)size like the following
[self playBackgroundMusic:#"bgMusic.mp3"];
that should take care of the background music for you.
Does anyone know of a way to adjust an AVPlayer track's volume when it is playing over Airplay? I have tried AVAudioMix and MPVolumeView but neither of them work. I have tried on iOS 5 and iOS 6 and am using the latest xcode 4.5.1. A simple example of this not working is Apple's AVPlayerTestApp which does a simple fade out using setVolumeRampFromStartVolume. This works fine on the device but doesn't if connected through Airplay.
In ViewDidLoad I load a track and start it playing (this is all taken from AVPlayerTestApp)
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:TRUE error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
self.mediaItems = [[[MPMediaQuery songsQuery] items] mutableCopy];
NSURL *anUrl = [[mediaItems objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVURLAsset URLAssetWithURL:anUrl options:nil];
AVPlayerItem *myPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
self.myPlayer1 = [[[AVPlayer alloc] initWithPlayerItem:myPlayerItem] retain];
[myPlayer1 play];
then I have a button which opens an alertview allowing user to set volume and switch on airplay
MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame: CGRectMake(10, 37, 260, 20)] autorelease];
UIAlertView *volumeAlert = [[UIAlertView alloc] initWithTitle:#"Volume" message:#"" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[volumeView sizeToFit];
[volumeAlert addSubview:volumeView];
[volumeAlert show];
[volumeAlert release];
then another button which fades out the currently playing track
AVAsset *asset = [myPlayer1.currentItem asset];
NSArray *keys = [NSArray arrayWithObject:#"tracks"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^(void) {
NSError *error = nil;
AVKeyValueStatus trackStatus = [asset statusOfValueForKey:#"tracks" error:&error];
CMTime currentTime;
switch (trackStatus) {
case AVKeyValueStatusLoaded:
if(myPlayer1)
{
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray * allAudioParams = [NSMutableArray array];
for (AVAssetTrack *t in tracks) {
AVMutableAudioMixInputParameters *params =[AVMutableAudioMixInputParameters audioMixInputParameters];
float fadeOutSeconds = 5;
currentTime = [myPlayer1 currentTime];
[params setVolumeRampFromStartVolume: 1.0 toEndVolume: 0.0 timeRange: CMTimeRangeMake(currentTime, CMTimeMakeWithSeconds(fadeOutSeconds, 1))];
[params setTrackID:[t trackID]];
[allAudioParams addObject:params];
}
AVMutableAudioMix * zeromix = [AVMutableAudioMix audioMix];
[zeromix setInputParameters:allAudioParams];
[myPlayer1.currentItem setAudioMix:zeromix];
}
break;
case AVKeyValueStatusFailed:
// error occured loading AVAsset
NSLog(#"error occured loading AVAsset");
break;
case AVKeyValueStatusCancelled:
// loading of the AVAsset was cancelled
NSLog(#"loading of the AVAsset was cancelled");
break;
default:
break;
}
}];
This works as expected on the device and fades the volume when the button is tapped. However, if Airplay is turned on the volume change doesn't get through. Using MPMoviePlayController I can do fades myself which work over Airplay but AVPlayer has less latency over Airplay so I would rather use that.
Any help much appreciated.
As Sam_899 didn't post an answer I'll have to do it. As far as I can work out, it is impossible to control the volume of avplayer over airplay unless the connection is made with mirroring turned on. As the only way to turn mirroring on is from outside your app the only option is to inform users how to turn it on themselves and hope they are happy with it! For those who don't know how to turn on mirroring over airplay; double click the home button, swipe left to the volume control, tap the airplay icon, choose the airplay device to connect to then switch mirroring on.
I have a short movie for looping in the background of my view. I use MPMoviePlayerController to play the movie. repeatMode is set to MPMovieRepeatModeOne and this works fine on iPad 2, 3 and in Simulator. On iPad 1 however, the movie loops once and stops right after the second playback. The project is iOS 5 w/o ARC (tested from GM up to 5.1.1).
- (void)loadVideo {
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"movieFileName.m4v" ofType:nil];
self.videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:urlStr]];
self.videoPlayer.controlStyle = MPMovieControlStyleNone;
self.videoPlayer.scalingMode = MPMovieScalingModeFill;
self.videoPlayer.repeatMode = MPMovieRepeatModeOne;
self.videoPlayer.view.userInteractionEnabled = NO;
[self.videoPlayer.view setFrame:self.movieContainer.bounds];
[self.movieContainer addSubview:self.videoPlayer.view];
}
How can I get the movie looping on iPad 1?
After trying out a lot, I finally found a solution to this problem:
After registering for the notification of changed playback-state MPMoviePlayerPlaybackStateDidChangeNotification, the movie loops endlessly and doesn't stop after the second playback on iPad 1. Keep in mind, that this behaviour didn't take place on iPad 2, 3 or Simulator.
The selector performed for the notification must not be empty. Just assign a bool or something. The extended code from above would be:
- (void)loadVideo {
// Create the controller
NSString *urlStr = [[NSBundle mainBundle] pathForResource:#"movieFileName.m4v" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:urlStr];
self.videoPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
// Configure the controller
self.videoPlayer.controlStyle = MPMovieControlStyleNone;
self.videoPlayer.scalingMode = MPMovieScalingModeFill;
self.videoPlayer.repeatMode = MPMovieRepeatModeOne;
self.videoPlayer.view.userInteractionEnabled = NO;
[self.videoPlayer.view setFrame:self.movieContainer.bounds];
// Register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerNotification:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:videoPlayer];
self.listeningToMoviePlayerNotifications = YES;
// Add its view to the hierarchy
[self.movieContainer addSubview:self.videoPlayer.view];
}
- (void)moviePlayerNotification:(NSDictionary *)userInfo {
// Do anything here, for example re-assign the listeningToMoviePlayerNotification-BOOL
self.listeningToMoviePlayerNotifications = YES;
}