I am developing a music player app and used AVPlayer for that, I have to play audio from document directory and also stream it directly. But my AVPlayer is consuming a lot of CPU making the app to stuck at random places.
App Flow
Initiated an AVPlayer
Checked whether the player is in memory or
not, if yes then replaceCurrentItemWithPlayerItem with the new audio
asset.
And for stream passed the URL for the asset
Any help I can get.
Any Please let me know what CPU consumption is normal for a music app.
Thanks
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentsDirectory = [pathArray objectAtIndex:0];
NSString* filePath = [documentsDirectory returnDocumentDirectoryPath:#"filename.mp3"];
NSURL *soundURL;
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
soundURL = [NSURL fileURLWithPath:filePath isDirectory:NO];
}
if (_player != nil){
[_player pause];
[_player removeObserver:self forKeyPath:#"status"];
}
AVAsset *asset = [AVURLAsset URLAssetWithURL:soundURL options:nil];
AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
_player = [AVPlayer playerWithPlayerItem:anItem];
[_player addObserver:self forKeyPath:#"status" options:0 context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_player currentItem]];
And while changing the track following code is used
[_player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:[AVURLAsset URLAssetWithURL:soundURL options:nil]]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_player currentItem]];
[_player play];
And while streaming online
if(!_player)
_player = [[AVPlayer alloc] init];
resourcePath=#"www.google.com/abc.mp3"//stream URL
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:resourcePath] options:nil];
NSArray *keys = [NSArray arrayWithObject:#"playable"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
if(!playerPlaying){
[_player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:asset]];
}
}];
Related
I created avplayer like this but controlls are not showing.can any one explain is there any playback controls are we need to create our custom playbacks.
NSString *path = [[NSBundle mainBundle] pathForResource:#"sample2" ofType:#"mp4"];
_videoURL = [NSURL fileURLWithPath: path];
_videoAsset = [AVURLAsset assetWithURL:_videoURL];
_videoDuration = (int)CMTimeGetSeconds(_videoAsset.duration);
_playerItem = [AVPlayerItem playerItemWithAsset:_videoAsset];
_player = [AVPlayer playerWithPlayerItem:_playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = CGRectMake(0, self.frame.size.height*0.2, self.frame.size.width, self.frame.size.height*0.3);
[self.layer addSublayer:_playerLayer];
[_player play];
_isPlaying = YES;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:_playerItem];
I have a MPMediaItem in which is a video of the local itunes library of the iPad.
how can I play in a UIView this now?
The following code does not work:
MPMediaItem *video = [allVideos objectAtIndex:indexPath.row];
NSURL *url = [video valueForProperty:MPMediaItemPropertyAssetURL];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:url];
[player prepareToPlay];
[player.view setFrame: videoView.bounds];
[videoView addSubview: player.view];
[player play];
why does the following not work?
nothing happens...
MPMediaItem *song = [allVideos objectAtIndex:indexPath.row];
NSLog(#"%#",[song valueForProperty:MPMediaItemPropertyAssetURL]);
NSURL *url = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayer *player = [[AVPlayer alloc] init];
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:avAsset];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:playerItem];
player = [[AVPlayer alloc]initWithPlayerItem:playerItem];
//[player seekToTime:kCMTimeZero];
[player play];
I am trying to replace AVPlayer with MPMoviePlayerController as I want to be able to add an animation with transparent background to a view. The problem is the animation is not displaying with MPMoviePlayerController.
Please find my lines below. The first portion is with AVPlayer and it's work. The second is with MPMoviePlayerController and doesn't.
What the code does is it plays an animation and when this is done it is launching an action.
Code with AVPlayer (that works):
NSString *filepath = [[NSBundle mainBundle] pathForResource:theAnimationFileName ofType:theString;
//NSURL *fileURL = [NSURL fileURLWithPath:filepath];
// First create an AVPlayerItem
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:fileURL];
// Subscribe to the AVPlayerItem's DidPlayToEndTime notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
// Pass the AVPlayerItem to a new player
controlledPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];
AVPlayerLayer *animatedLayer = [AVPlayerLayer playerLayerWithPlayer:controlledPlayer];
[animatedLayer setFrame:CGRectMake(0, 0, 1024, 1024)];
[thisReplacementView.layer addSublayer: animatedLayer];
// Begin playback
[controlledPlayer play];
Code with MPMoviePlayerController (does not display anything):
NSString *moviePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:theString];
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:moviePath]];
moviePlayer.controlStyle = MPMovieControlModeDefault;
moviePlayer.view.frame = CGRectMake(0, 0, 1024, 1024);
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[thisReplacementView addSubview:moviePlayer.view];
[moviePlayer play];
NSURL *url = [NSURL URLWithString:#"http://iOS.mp4"];
self.moviePlayer = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &_error];
[self presentMoviePlayerViewControllerAnimated:self.moviePlayer];
-(void)playbackFinishedCallback:(NSNotification *)notification{
self.moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
self.moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayer];
[self.moviePlayer.view removeFromSuperview];
}
sorry for my question but i´ve implemented a intro- video and despite of the hardware silent-switch of my iPad, the audio is playing.
I´m also using the AVAudioplayer within my app just for playing short sound samples. Within this class, its the only region where i´ve set up the "AVAudioSessionCategory".
But for all audio playback only, there´s nothing hearable. Its just for my intro-video.
Any help how to fix that "audio-bug" so the movie player is silent?
Thanks you
Here´s my Audio-class:
- (id)initWithSoundfileName:(NSString*) file
{
if ((self = [super init]))
{
NSString* filename = [file stringByDeletingPathExtension];
NSString* fileextension = [file pathExtension];
// get file path from bundle
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: filename ofType: fileextension];
NSLog(#"AudioPlayer init: %#", soundFilePath);
NSURL* fileurl = [[NSURL alloc] initFileURLWithPath:soundFilePath];
NSError* error = nil;
AVAudioPlayer* audioplayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileurl error:&error ];
if (error) { NSLog(#"Error creating AVAudioPlayer %#", [error description]);}
// set audio policy
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:NULL];
self.player = audioplayer;
[self.player prepareToPlay];
[self.player setDelegate:self];
}
return self;
}
-(void) play{
[self.player play];
}
And here´s my video-playback method:
- (void)playIntroVideo
{
NSString *movpath = [[NSBundle mainBundle] pathForResource:#"mymovie" ofType:#"mp4"];
NSURL *fileURL = [NSURL fileURLWithPath:movpath];
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
self.moviePlayerController.fullscreen = YES;
self.moviePlayerController.scalingMode = MPMovieScalingModeAspectFit;
self.moviePlayerController.controlStyle = MPMovieControlStyleNone;
self.moviePlayerController.movieSourceType = MPMovieSourceTypeFile;
self.moviePlayerController.useApplicationAudioSession = NO;
[self.moviePlayerController.view setFrame: self.view.bounds];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.moviePlayerController];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlaybackStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.moviePlayerController];
[self.view addSubview:self.moviePlayerController.view];
[self.moviePlayerController prepareToPlay];
[self.moviePlayerController play];
}
Like #Till mentioned:
When I change the MoviePlayerController property to useApplicationAudioSession=TRUE, it fixes my problem. Audio Playback is silent.
i want to play a video within a UIView using MPMoviePlayerController.
After pressing a UIButton, the video appears and starts playing.
Unfortunately after 3-4 seconds, the video gets black, the audio is still playing.
Any ideas?
Thanks for all your time.
(Using Xcode 4.2.1)
-(void) playMovieButtonPressed:(UIButton*) button{
NSString* video = #"testmovie.m4v";
NSString *filepath = [[NSBundle mainBundle] pathForResource:[video stringByDeletingPathExtension] ofType:[video pathExtension]];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
MPMoviePlayerController* player = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlaybackComplete:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
player.movieSourceType = MPMovieSourceTypeFile;
[player.view setFrame:CGRectMake(20, 400, 300, 200)];
[self.view addSubview:player.view];
[player prepareToPlay];
[player play];
}
- (void) moviePlaybackComplete:(NSNotification*) notification {
NSLog(#"videoviewcontroller complete: %#", notification);
MPMoviePlayerController *mymoviePlayerController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:mymoviePlayerController];
}
I´ve talked to an Apple Engineer. The solution is that the player would have to be an instance variable or property of the view controller. So its still accessible when view was being torn down.
-(void) playMovieButtonPressed:(UIButton*) button{
NSString* video = #"testmovie.m4v";
NSString *filepath = [[NSBundle mainBundle] pathForResource:[video stringByDeletingPathExtension] ofType:[video pathExtension]];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
self.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
// .....
}