No audio played using MPMoviePlayerController - iphone

I have been using MPMoviePlayerController to play mp4 file. Video is playing fine but there is no audio at all.
I have downloaded first in one function and played using another. Please check the code below. Am I doing anything wrong here...
- (void) download_file : (NSString *) msg_url
{
if (msg_url != nil) {
// Download and play
NSURL *url = [NSURL URLWithString:msg_url];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
char file_path[512] = {0};
get_app_data_path(OFI_VC_MAILBOX_PATH, file_path); // Give document path.
NSString *filePath = [NSString stringWithFormat:#"%s/%#", file_path,#"mailbox.mp4"];
[urlData writeToFile:filePath atomically:YES];
[self performSelectorOnMainThread:#selector(play_mp4_file:) withObject:filePath waitUntilDone:NO];
}
}
}
- (void) play_mp4_file : (NSString *) filepath
{
if (is_same_view == true) {
[self.view setUserInteractionEnabled:YES];
if (filepath != nil) {
NSURL *file_url = [NSURL fileURLWithPath:filepath];
moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL:file_url];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
moviePlayer.useApplicationAudioSession = YES;
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
}
}
}
Thanks for your helps

I have fixed the issue. Problem is with .mp4 extension, I have used .mov. Its playing audio now.

Related

AVPlayer is Not Playing From NSCachesDirectory?

Hi I am Trying to Play Video Files From NSCachesDirectory. The Player is not loading the Files from NSCachesDirectory in videoView layer.
Is it Possible to play Video from cacheDirectory Memory?
Please suggest me...
I have tried this..
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [myPathList objectAtIndex:0];
NSString *songPath = [[NSString alloc] initWithString: [cachesDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Song.%#", downloadURL]]];
NSURL *pathurl = [[NSURL alloc] initFileURLWithPath:songPath];
NSLog(#"--pathurl---%#",pathurl);
avPlayer =[AVPlayer playerWithURL:pathurl];
self.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:avPlayer];
if ( !([avPlayer status] == AVPlayerStatusReadyToPlay) && (dataReceivedSoFar.length >10000))
{
avPlayerLayer.frame =CGRectMake(0, 0, 320, 450);
[[self.videoView layer] addSublayer:avPlayerLayer];
[avPlayer play];
NSLog(#"Video IS Playing");
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
KVO approach.
Add observer:
self.player = [AVPlayer playerWithURL:url];
[self.player addObserver:self forKeyPath:#"status" options:0 context:&PlayerStatusContext];
Observing value
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (context == &PlayerStatusContext) {
AVPlayer *thePlayer = (AVPlayer *)object;
if ([thePlayer status] == AVPlayerStatusFailed) {
NSError *error = [self.player error];
// Respond to error: for example, display an alert sheet.
return;
}
// Deal with other status change if appropriate.
if ([thePlayer status] == AVPlayerStatusReadyToPlay) {
[self play];
}
}
// Deal with other change notifications if appropriate.
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
return;
}
Playing:
- (IBAction)play:sender {
[self.player play];
}
EDITING:
As awolCZ said AVPlayer can not play partially downloaded files. But you could use something like http://test.com/test.mp3 for URL.
I'm not sure that [avPlayer status] == AVPlayerStatusReadyToPlay returns YES in this case. It takes some time for AVPlayer to load the item. You should can play immediately even if it's better way to track AVPlayer.status using KVO.
Lukas
EDIT: Try it this way (quick win):
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [myPathList objectAtIndex:0];
NSString *songPath = [[NSString alloc] initWithString: [cachesDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Song.%#", downloadURL]]];
NSURL *pathurl = [[NSURL alloc] initFileURLWithPath:songPath];
NSLog(#"--pathurl---%#",pathurl);
avPlayer =[AVPlayer playerWithURL:pathurl];
self.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame =CGRectMake(0, 0, 320, 450);
[[self.videoView layer] addSublayer:avPlayerLayer];
[avPlayer play];

XCODE IOS memory leak for AVAudioPlayer

I use ARC.
Here is the method for starting the audio in my code:
.h file:
#property (retain,nonatomic)AVAudioPlayer *myAudio;
and .m files
-(void)myPlaySound:(NSString *)mySoundFile NumberOfLoops:(int)loopsCount ofType:(NSString *)fileType
{
if([myAudio isPlaying])
{
[myAudio stop];
}
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:mySoundFile
ofType:fileType]];
NSError *error;
myAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:&error];
self.theAudio = myAudio;
myAudio.volume = audioVolume;
myAudio.numberOfLoops = loopsCount;
myAudio.currentTime = 0.0;
[myAudio prepareToPlay];
if([myAudio play] == NO)
{
NSLog(#"error");
}
}
Based on the button press, I play different audio files of different length and bit rate and types.
Its working, but I get memory leak issue.

Can AVFoundation play Audio and get Details of it On the IOS 5.0 Simulator?

Can the Above be Done using only AVFoundation.framework?
i Tried doing a few experiment but i can't really get it to work
(sorry newbie here please do tell me where to put the codes at Example: ViewController or the MainView)
These are my code,(UI Components are inside as i'm do not want use interface builder)
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSError *error;
buttonPlay = [[UILabel alloc] initWithFrame:CGRectMake(0, 350, 100, 50)];
buttonPlay.text = #"Play";
// Get the file path to the song to play.
NSString* path;
NSURL* url;
path = [[NSBundle mainBundle] pathForResource:#"Bring_Me_To_Life.mp3" ofType:nil];
url = [NSURL fileURLWithPath:path];
NSData *_objectData = [NSData dataWithContentsOfURL:url];
//Initialize the AVAudioPlayer.
audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
// Preloads the buffer and prepares the audio for playing.
audioPlayer.numberOfLoops = 0;
audioPlayer.volume = 1.0f;
[audioPlayer prepareToPlay];
if (audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[audioPlayer play];
[self addSubview:buttonPlay];
}
return self;
}
-(void)touchesBegan:(CGPoint)location{
if(CGRectContainsPoint(buttonPlay.frame, location)){
NSLog(#"Dec from Chl %f",[audioPlayer peakPowerForChannel:0]);
NSLog(#"Length of Clip %f",[audioPlayer duration]);
}
}
try this
audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];

IOS [NSURL initFileURLWithPath:]: nil string parameter on loading video

I have a problem with my video content. I want to load a video from my viewcontroller and I get this error:
[NSURL initFileURLWithPath:]: nil string parameter
When I try to load the video from a url the video wont show up.
I am sure that my variable targetURN is not nil.
From here I load my viewcontroller:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0:
[self openVideoView:#"Video"];
break;
case 1:
[self openWebview:#"About"];
break;
case 2:
[self openWebview:#"http://www.url.com"];
break;
}
}
- (void)openVideoView:(NSString *)url{
IDPVideoView *vv = [[IDPVideoView alloc] initWithURN:url];
[self presentModalViewController:vv animated:NO];
}
In my viewcontroller:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *videoURL = nil;
if ([self.targetURN hasPrefix:#"http"])
{
videoURL = [NSURL URLWithString:targetURN];
}
else
{
videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:targetURN ofType:#"mp4"]];
}
if(videoURL != nil) {
MPMoviePlayerController *moviePlayer =
[[MPMoviePlayerController alloc] initWithContentURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;
[moviePlayer prepareToPlay];
[self.view addSubview:moviePlayer.view];
[moviePlayer setFullscreen:YES animated:YES];
}
}
have you tried allocating the url first?
NSURL *vidURL = [[NSURL alloc] initWithString:self.targetURN];
as a general advice, try using self.targetURN all the time, or synchronize it to a different name like
#synchronize targetURN = _targetURN
and then use _targetURN in your code.this makes sure that you (in any case) use the right property.
(of course this goes for all your properties)
I solved the error part by adding this line
NSString *urlString = [NSString stringWithFormat:url];
- (void)openVideoView:(NSString *)url{
NSString *urlString = [NSString stringWithFormat:url];
IDPVideoView *vv = [[IDPVideoView alloc] initWithURN:url];
[self presentModalViewController:vv animated:NO];
}
But the video is still not showing up.

AVPlayer And Local Files

I am building a MP3 player for iOS that plays audio files hosted on the web. I want to offer the ability to play the files offline so I have the files downloading using ASIHTTP but I am cannot seem to find info on initiallzing AVPlayer with a mp3 in the app documents directory. Has anyone done this before? Is it even possible?
*I posted an answer below that shows how to use the iOS AvPlayer for both local and http files. Hope this helps!
I decided to answer my own question because I felt like there is very little documentation on how to use the Apple provided AVPlayer for both local and stream (over http) files. To help understand the solution, I put together a sample project on GitHub in Objective-C and Swift The code below is Objective-C but you can download my Swift example to see that. It is very similar!
What I found is that the two ways of setting up the files are almost identical except for how you instantiate your NSURL for the Asset > PlayerItem > AVPlayer chain.
Here is an outline of the core methods
.h file (partial code)
-(IBAction) BtnGoClick:(id)sender;
-(IBAction) BtnGoLocalClick:(id)sender;
-(IBAction) BtnPlay:(id)sender;
-(IBAction) BtnPause:(id)sender;
-(void) setupAVPlayerForURL: (NSURL*) url;
.m file (partial code)
-(IBAction) BtnGoClick:(id)sender {
NSURL *url = [[NSURL alloc] initWithString:#""];
[self setupAVPlayerForURL:url];
}
-(IBAction) BtnGoLocalClick:(id)sender {
// - - - Pull media from documents folder
//NSString* saveFileName = #"MyAudio.mp3";
//NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSString *documentsDirectory = [paths objectAtIndex:0];
//NSString *path = [documentsDirectory stringByAppendingPathComponent:saveFileName];
// - - -
// - - - Pull media from resources folder
NSString *path = [[NSBundle mainBundle] pathForResource:#"MyAudio" ofType:#"mp3"];
// - - -
NSURL *url = [[NSURL alloc] initFileURLWithPath: path];
[self setupAVPlayerForURL:url];
}
-(void) setupAVPlayerForURL: (NSURL*) url {
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:anItem];
[player addObserver:self forKeyPath:#"status" options:0 context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == player && [keyPath isEqualToString:#"status"]) {
if (player.status == AVPlayerStatusFailed) {
NSLog(#"AVPlayer Failed");
} else if (player.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayer Ready to Play");
} else if (player.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
-(IBAction) BtnPlay:(id)sender {
[player play];
}
-(IBAction) BtnPause:(id)sender {
[player pause];
}
Check out the Objective-C source code for a working example of this.
Hope this helps!
-Update 12/7/2015 I now have a Swift example of the source code you can view here.
I got AVPlayer to work with local URL by prepending file:// to my local url
NSURL * localURL = [NSURL URLWithString:[#"file://" stringByAppendingString:YOUR_LOCAL_URL]];
AVPlayer * player = [[AVPlayer alloc] initWithURL:localURL];
Yes,thats possible to download and save the .mp3(or any kind of file)into NSDocument directory and then you can retrive from that and play by using AVAudioPlayer.
NSString *downloadURL=**your url to download .mp3 file**
NSURL *url = [NSURLURLWithString:downloadURL];
NSURLConnectionalloc *downloadFileConnection = [[[NSURLConnectionalloc] initWithRequest: [NSURLRequestrequestWithURL:url] delegate:self] autorelease];//initialize NSURLConnection
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileDocPath = [NSStringstringWithFormat:#"%#/",docDir];//document directory path
[fileDocPathretain];
NSFileManager *filemanager=[ NSFileManager defaultManager ];
NSError *error;
if([filemanager fileExistsAtPath:fileDocPath])
{
//just check existence of files in document directory
}
NSURLConnection is used to download the content.NSURLConnection Delegate methods are used to support downloading.
(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSFileManager *filemanager=[NSFileManagerdefaultManager];
if(![filemanager fileExistsAtPath:filePath])
{
[[NSFileManagerdefaultManager] createFileAtPath:fileDocPath contents:nil attributes:nil];
}
NSFileHandle *handle = [NSFileHandlefileHandleForWritingAtPath:filePath];
[handle seekToEndOfFile];
[handle writeData:data];
[handle closeFile];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alertView=[[UIAlertViewalloc]initWithTitle:#”"message:
[NSStringstringWithFormat:#"Connection failed!\n Error - %# ", [error localizedDescription]] delegate:nilcancelButtonTitle:#”Ok”otherButtonTitles:nil];
[alertView show];
[alertView release];
[downloadFileConnectioncancel];//cancel downloding
}
Retrieve the downloaded Audio and Play:
NSString *docDir1 = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *myfilepath = [docDir1 stringByAppendingPathComponent:YourAudioNameinNSDOCDir];
NSLog(#”url:%#”,myfilepath);
NSURL *AudioURL = [[[NSURLalloc]initFileURLWithPath:myfilepath]autorelease];
Just write your code to play Audio by using AudioURL
I Like to know if u have any clarification in this regard.
Thank you
Try this
NSString*thePath=[[NSBundle mainBundle] pathForResource:#"yourVideo" ofType:#"MOV"];
NSURL*theurl=[NSURL fileURLWithPath:thePath];
Swift local playback version, assuming I have a file "shelter.mp3" in my bundle:
#IBAction func button(_ sender: Any?) {
guard let url = Bundle.main.url(forResource: "shelter", withExtension: "mp3") else {
return
}
let player = AVPlayer(url: url)
player.play()
playerView?.player = player;
}
See here for details about playerView or playing a remote url.
its very difficult to play a song using a Avplayer why you are not use a MPMoviePlayerController player . i have play song from document directory .i am posting a code pls refer this .its working fine .and also u directly from url live .
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *publicDocumentsDir = [paths objectAtIndex:0];
NSString *dataPath = [publicDocumentsDir stringByAppendingPathComponent:#"Ringtone"];
NSString *fullPath = [dataPath stringByAppendingPathComponent:[obj.DownloadArray objectAtIndex:obj.tagvalue]];
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
NSURL *url = [NSURL fileURLWithPath:fullPath];
videoPlayer =[[MPMoviePlayerController alloc] initWithContentURL: url];
[[videoPlayer view] setFrame: [self.view bounds]];
[vvideo addSubview: [videoPlayer view]];
videoPlayer.view.frame=CGRectMake(0, 0,260, 100);
videoPlayer.view.backgroundColor=[UIColor clearColor];
videoPlayer.controlStyle = MPMovieControlStyleFullscreen;
videoPlayer.shouldAutoplay = YES;
[videoPlayer play];
videoPlayer.repeatMode=YES;
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(moviePlayerEvent:) name:MPMoviePlayerLoadStateDidChangeNotification object:videoPlayer];
/* NSNotificationCenter *notificationCenter1 = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(moviePlayerEvent1:) name:MPMoviePlaybackStateStopped object:videoPlayer];
*/
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playbackStateChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:videoPlayer];
}
-(void)playbackStateChange:(NSNotification*)notification{
if([[UIApplication sharedApplication]respondsToSelector:#selector(setStatusBarHidden: withAnimation:)])
{
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationNone];
}
else
{
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
}
}
-(void)moviePlayerEvent:(NSNotification*)aNotification{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
}
-(void)moviePlayerEvent1:(NSNotification*)aNotification{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
}