AVAudioPlayer doesn't play mp3? - ios

I want my AVAudioPlayer to play some mp3 files. It plays some of them but I have one file that can't be played!
To play the file I download it on my device into application folder and init it this way:
[[AVAudioPlayer alloc] initWithContentsOfURL:soundPath error:nil];
How to play the file? Why it doesn't play?
Link to a file: abc.mp3
EDIT:
(Here is the code that shows the error. There is a README inside the code. Try on the device.)
***.pch
#import <Availability.h>
#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#endif
ViewController.h
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
#interface SCRViewController : UIViewController <AVAudioPlayerDelegate>
{
UIButton *button;
__block UIProgressView *view;
NSOperationQueue *queue;
__block BOOL isFile;
UIButton *play;
NSString *path;
AVAudioPlayer *_player;
}
#end
ViewController.m
#import "ViewController.h"
#implementation SCRViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundColor:[UIColor yellowColor]];
[button setFrame:CGRectMake(50, 50, 220, 50)];
[button addTarget:self action:#selector(download) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Download" forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[self.view addSubview:button];
play = [UIButton buttonWithType:UIButtonTypeCustom];
[play setBackgroundColor:[UIColor yellowColor]];
[play setFrame:CGRectMake(50, 150, 220, 50)];
[play addTarget:self action:#selector(play) forControlEvents:UIControlEventTouchUpInside];
[play setTitle:#"Play" forState:UIControlStateNormal];
[play setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[play setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[self.view addSubview:play];
self->view = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
self->view.frame = CGRectMake(10, 120, 300, 20);
[self->view setProgress:0];
[self.view addSubview:self->view];
queue = [[NSOperationQueue alloc] init];
isFile = NO;
}
- (void) download
{
[button setBackgroundColor:[UIColor brownColor]];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateDisabled];
[button setEnabled:NO];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://iwheelbuy.com/abc.mp3"]];
//-------------------------------------------------------
//-------------------------------------------------------
// READ ME
//-------------------------------------------------------
//-------------------------------------------------------
// Test in on device
// I have uploaded another song for you. You can change link to http://iwheelbuy.com/def.mp3 and check the result
// def.mp3 works fine on the device
//-------------------------------------------------------
//-------------------------------------------------------
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
path = [path stringByAppendingPathComponent:#"song"];
if ( [[NSFileManager defaultManager] fileExistsAtPath:path])
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
isFile = YES;
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
//
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
{
CGFloat done = (CGFloat)((int)totalBytesRead);
CGFloat expected = (CGFloat)((int)totalBytesExpectedToRead);
CGFloat progress = done / expected;
self->view.progress = progress;
}];
[queue addOperation:operation];
}
- (void) play
{
if (isFile)
{
NSError *error = nil;
NSURL *url = [NSURL fileURLWithPath:path];
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(error || !_player)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:[error description] delegate:nil cancelButtonTitle:#"Try def.mp3" otherButtonTitles:nil];
[alert show];
}
else
{
[_player play]; // plays fine
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning" message:#"Download the file plz" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
}
#end

Non-ARC
You have to retain it during playback because it does not retain itself. It will stop playing instantly once it is dealloc-ed.
ARC
You need to hold the AVAudioPlayer instance in the class. And release it after it stops playing. For example,
#import <AVFoundation/AVFoundation.h>
#interface TAViewController () <AVAudioPlayerDelegate> {
AVAudioPlayer *_somePlayer; // strong reference
}
#end
#implementation TAViewController
- (IBAction)playAudio:(id)sender
{
NSURL *url = [[NSBundle mainBundle] URLForResource:#"kogmawjoke" withExtension:#"mp3"];
_somePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
_somePlayer.delegate = self;
[_somePlayer play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
if (player == _somePlayer) {
_somePlayer = nil;
}
}
#end

http://bugreport.apple.com
Engineering has determined that this issue behaves as intended based on the following information:
Could repro with attached sample app, but this is an expected behavior from AudioFile.
The issue is that AVAudioPlayer is being initialized with a url without a file extension and the corresponding file does not have a valid ID3 tag.Without a file extension or valid data, we cannot determine the right file format and hence such files will fail to open.This is an expected behavior.
In the sample code attached:
path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
path = [path stringByAppendingPathComponent:#"song"];
--> path will be something like:
/var/mobile/Applications/2FFD0147-E56B-47D4-B143-A9F19BE92818/Documents/song
--> NOTE: no file extension at the end.
abc.mp3 has an invalid ID3 tag size (0x2EE) unlike def.mp3 which has a valid tag size (0x927). Hence when these are specified as "…./song" without any extension, AudioFile just looks at the data and finds a valid sync word for def.mp3 but not for abc.mp3.
However, replacing stringByAppendingPathComponent:#"song" with stringByAppendingPathComponent:#"song.mp3" succeeds for abc.mp3, and could help for other mp3 files in general.
We consider this issue closed. If you have any questions or concern regarding this issue, please update your report directly (http://bugreport.apple.com).
Thank you for taking the time to notify us of this issue.

Related

Using AVPlayer and AVPlayerViewController, but audio and video not present

My code looks like this:
_player = [AVPlayer playerWithURL:destination];
_playerVC = [AVPlayerViewController new];
_playerVC.player = _player;
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:_playerVC animated:YES completion:^{
[_player play];
}];
});
_player represents AVPlayer and _playerVC represents AVPlayerViewController. I have strong global references to these objects.
Using terminal, I played the file located at the destination (open -a quicktime\ player destinationURLAbsoluteString) and saw the file is properly loaded since it was playing.
It is a m4v file. I have played a m4a file and it properly gave me audio. I have also substituted the url I have for destination to some remote url and that worked for video. This leads me to believe it has something to do with my video. What's weird is that my AVPlayerViewController does show a black screen with all the normal controls, and even shows the video is 2 minutes and 23 seconds. Upon opening the video file manually, I can see that it is also 2 minutes and 23 seconds.
I can forward through the video properly by dragging the white dot indicative of the video's position, but I never hear anything, nor do I see anything but the black screen and controls.
TL;DR
NSLog(#"Destination: %#",destination);
prints: file:///Users/MyLogin/Library/Developer/CoreSimulator/Devices/694F4C94-F785-4931-A312-4C3E7DE8673A/data/Containers/Data/Application/76C923BE-5B25-41F7-9145-63414657FDF6/Documents/mzvf_5914002519860647075.640x352.h264lc.D2.p.m4v
All in all, it looks like I'm properly retrieving the video, but for some reason my player controller is completely black and void of audio. Any help is much appreciated.
Source Code:
.m file:
#import "ViewController.h"
#import "View2ViewController.h"
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property NSDictionary *requestedSong;
#property (strong) AVPlayer *player; //Declare Globally
#property (strong) AVPlayerViewController *playerVC;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor yellowColor];
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
button.center = self.view.center;
button.backgroundColor = [UIColor blueColor];
[button setTitle:#"Query Songs" forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:button];
UIButton *button2 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 200, 50)];
button2.center = CGPointMake(button.center.x, button.center.y + 200);
button2.backgroundColor = [UIColor blueColor];
[button2 setTitle:#"Listen to the first song" forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(button2Clicked) forControlEvents:UIControlEventTouchDown];
[self.view addSubview:button2];
}
-(void)button2Clicked{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
NSURL *url = [NSURL URLWithString:[_requestedSong objectForKey:#"previewUrl"]];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:req];
[task resume];
}
-(void)buttonClicked{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
NSURL *url = [NSURL URLWithString:#"https://itunes.apple.com/search?media=movie&entity=movie&term=Mad"];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:url];
NSURLSessionDataTask *task = [session dataTaskWithRequest:req];
[task resume];
}
-(NSURL*)localFilePathForURL:(NSURL *) previewUrl{
//get the directory to use
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) objectAtIndex:0];
//create the full path
NSString *fullPath = [documentsPath stringByAppendingPathComponent:previewUrl.lastPathComponent];
//append the filename and append to document path url
return [NSURL fileURLWithPath:fullPath];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
NSURL* originalURL = downloadTask.originalRequest.URL;
NSURL *destination = [self localFilePathForURL:originalURL];
NSLog(#"Destination: %#",destination);
NSFileManager *defaultFileManager = [NSFileManager defaultManager];
if([defaultFileManager fileExistsAtPath:destination.absoluteString]){
[defaultFileManager removeItemAtURL:destination error:nil];
}
NSError *error;
#try {
[defaultFileManager copyItemAtURL:location toURL:destination error:&error];
} #catch (NSException *exception) {
NSLog(#"copy caught with exception: %#",exception);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
_player = [AVPlayer playerWithURL:destination];
_playerVC = [AVPlayerViewController new];
_playerVC.player = _player;
[self presentViewController:_playerVC animated:YES completion:^{
[_player play];
}];
});
NSLog(#"Hello");
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data{
NSError *error2;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:1 error:&error2];
_requestedSong = [[dict valueForKey:#"results"] objectAtIndex:0];
NSLog(#"Searched: %#",[_requestedSong objectForKey:#"trackName"]);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
completionHandler(NSURLSessionResponseAllow);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
#end
UPDATE:
Upon using the actual URL endpoint for mad max instead of downloading the video, it also displays a blank video. This must mean there's something weird about the format of the video or how it interacts with the AVPlayer.
You should setup observer for AVPlayer status to call play only when it will be ready to play.
How to do it - check answers here: AVPlayer And Local Files
check the following
if ((_playerVC.player.rate != 0) && (_playerVC.player.error == nil)) {
// player is playing
} else {
// Something wrong
}
also you can observe the rate property of the player. More info here

How to update UIImages after NSURLConnection delegate completes

So I'm pulling down about 50 images from my API using NSURLConnection, its working great, except its locking up the UI when it runs. I'm assuming that is because I'm updating the UI in real time form the NSURLConnection self delegate. So I'm thinking what I need to do is put placeholder loading images in the UIImage, then update them somehow once the delegate has acquired all the data, but how do I do that, can someone give me some coding examples?
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
NSData *imageData = _dataDictionary[ [connection description] ];
if(imageData!=nil)
{
NSLog(#"%#%#",[connection description],imageData);
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(self.x, 0, self.screenWidth, self.screenHight)];
// Process thi image
// resize the resulting image for this device
UIImage *resizedImage = [self imageScaleCropToSize:[UIImage imageWithData: imageData ]];
self.x = (self.x + imageView.frame.size.width);
if(self.x > self.view.frame.size.width) {
self.scrollView.contentSize = CGSizeMake(self.x, self.scrollView.frame.size.height);
}
[imageView setImage:resizedImage];
// add the image
[self.scrollView addSubview: imageView];
}
}
You can use SDWebImage library to achieve this.
Suppose imageArray have all the image url path.
You can use SDWebImageManager to download all the images and show them in ImageView. Also you can show downloading progress using this block.
- (void)showImages:(NSArray *)imageArray
{
SDWebImageManager *manager = [SDWebImageManager sharedManager];
for (NSString *imagePath in imageArray)
{
[manager downloadImageWithURL:[NSURL URLWithString:imagePath]
options:SDWebImageLowPriority
progress:^(NSInteger receivedSize, NSInteger expectedSize){}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL)
{
if(!error)
self.imgView_Image.image = image;
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"please check your Connection and try again" message:#"No Internet Connection" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alert show];
}
}];
}
}
First create protocol in that class .h, where you call NSURLConnection request for download image (Where you implement this method connectionDidFinishLoading).
#protocol YourClassNameDelegate <NSObject>
- (void)didFinishLoadingImage:(UIImage *)downloadImage;
#end
and create property for that protocol in same class,
#interface YourViewController : UIViewController
#property (nonatomic, retain) id<YourClassNameDelegate>delegate;
#end
then synthesise it in .m, #synthesize delegate;
After that call didFinishLoadingImage: in connectionDidFinishLoading,
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
NSData *imageData = _dataDictionary[ [connection description] ];
if(imageData!=nil)
{
NSLog(#"%#%#",[connection description],imageData);
UIImageView *imageView = [[UIImageView alloc] initWithFrame: CGRectMake(self.x, 0, self.screenWidth, self.screenHight)];
// Process thi image
// resize the resulting image for this device
UIImage *resizedImage = [self imageScaleCropToSize:[UIImage imageWithData: imageData ]];
self.x = (self.x + imageView.frame.size.width);
if(self.x > self.view.frame.size.width) {
self.scrollView.contentSize = CGSizeMake(self.x, self.scrollView.frame.size.height);
}
[self.delegate didFinishLoadingImage:resizedImage];
[imageView setImage:resizedImage];
// add the image
[self.scrollView addSubview: imageView];
}
}
and finally from where you push to YourViewController set delegate to self, like :
YourViewController *controller = [[YourViewController alloc] init];
controller.delegate = self;
//.....
in YourViewController.m, where you want to set downloaded image, in that class implement this method.
#pragma mark - YourClassName delegate method
- (void)didFinishLoadingImage:(UIImage *)downloadImage
{
//yourImageView.image = downloadImage;
}

In song loading time how to display activity indicator if user click the play button in iPhone using AVAudioplayer

I am working in AVAudioplayer in iOS. I am displaying an activity indicator for loading time if a user clicks the play button. My problem is that when I click the play button the loading time activity indicator is not displayed. In playing time activity indicator displayed that is my problem.
-(void)viewDidLoad
{
// loading View
loadingView=[[UILabel alloc]initWithFrame:CGRectMake(135, 200, 40, 40)];
loadingView.backgroundColor=[UIColor whiteColor];
loadingView.clipsToBounds=YES;
loadingView.layer.cornerRadius=10.0;
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(10, 11, activityView.bounds.size.width, activityView.bounds.size.height);
[loadingView addSubview:activityView];
}
-(void)playOrPauseButtonPressed:(id)sender
{
if(playing==NO)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible=YES;
[self.view addSubview:loadingView];
[activityView startAnimating];
[playButton setBackgroundImage:[UIImage imageNamed:#"Pause.png"] forState:UIControlStateNormal];
// Here Pause.png is a image showing Pause Button.
NSError *err=nil;
AVAudioSession *audioSession=[AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSLog(#"%# %d",urlsArray,selectedIndex);
NSString *sourcePath=[urlsArray objectAtIndex:selectedIndex];
NSData *objectData=[NSData dataWithContentsOfURL:[NSURL URLWithString:sourcePath]];
audioPlayer = [[AVAudioPlayer alloc] initWithData:objectData error:&err];
if(err)
{
NSLog(#"Error %ld,%#",(long)err.code,err.localizedDescription);
}
NSTimeInterval bufferDuration=0.005;
[audioSession setPreferredIOBufferDuration:bufferDuration error:&err];
if(err)
{
NSLog(#"Error %ld, %#", (long)err.code, err.localizedDescription);
}
double sampleRate = 44100.0;
[audioSession setPreferredSampleRate:sampleRate error:&err];
if(err)
{
NSLog(#"Error %ld, %#",(long)err.code,err.localizedDescription);
}
[audioSession setActive:YES error:&err];
if(err)
{
NSLog(#"Error %ld,%#", (long)err.code, err.localizedDescription);
}
sampRate=audioSession.sampleRate;
bufferDuration=audioSession.IOBufferDuration;
NSLog(#"SampeRate:%0.0fHZI/OBufferDuration:%f",sampleRate,bufferDuration);
audioPlayer.numberOfLoops = 0;
[audioPlayer prepareToPlay];
audioPlayer.delegate=self;
if(!audioPlayer.playing)
{
[audioPlayer play];
}
playing=YES;
}
else if (playing==YES)
{
[playButton setBackgroundImage:[UIImage imageNamed:#"play.png"] forState:UIControlStateNormal];
[audioPlayer pause];
playing=NO;
}
if (self.audioPlayer)
{
[self updateViewForPlayerInfo];
[self updateViewForPlayerState];
[self.audioPlayer setDelegate:self];
}
}
First know the concept on activity indicator before start to implement. Thats good attitude for us.
http://www.ioscreator.com/tutorials/display-an-activity-indicator
use the activity indicator to display a loading process connect the activity indicator to IBOutlet and synthesize in h file and code like this
declare like this in m file
#interface updatepoliticalViewController : UIViewController
{
UIActivityIndicatorView *spinner;
}
and synthesize spinner into ur h file this difenlty work
-(void)temp
{
spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(0.0, 0.0, 40.0, 40.0);
[spinner setCenter:CGPointMake(160, 240)];
[self.view addSubview:spinner];
spinner.color = [UIColor blueColor];
spinner.backgroundColor = [UIColor colorWithWhite:0.2 alpha:0.4];
[spinner startAnimating];
[spinner release];
}
use this method to stop the activity
-(void) myMethod{
[spinner stopAnimating];
spinner.hidden = YES;
}
call this function in view didload and specify how long u want to display the loading process
- (void)viewDidLoad
{
[super viewDidLoad];
[self temp];
[self performSelector:#selector(myMethod) withObject:nil afterDelay:5.0f];
}
hope it helps for you

Playing youtube video using HCYoutubeParser

I am using HCYoutubeParser(https://github.com/hellozimi/HCYoutubeParser) to play some videos in my ios app. When I am trying to play some video, it doesn't seem to play it.
The code looks like this:
- (void)playVideo:(id)sender
{
if (_urlToLoad)
{
MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc]initWithContentURL:_urlToLoad];
_mp = player;
[self presentViewController:_mp animated:YES completion:nil];
}
}
- (void)submitYouTubeURL:(id)sender {
[playButton setImage:nil forState:UIControlStateNormal];
NSURL *url = [NSURL URLWithString:_urlOfYoutube];
activityIndicator.hidden = NO;
[HCYoutubeParser thumbnailForYoutubeURL:url thumbnailSize:YouTubeThumbnailDefaultHighQuality completeBlock:^(UIImage *image, NSError *error) {
if (!error) {
[playButton setBackgroundImage:image forState:UIControlStateNormal];
playButton.hidden = NO;
NSDictionary *qualities = [HCYoutubeParser h264videosWithYoutubeURL:url];
_urlToLoad = nil;
_urlToLoad = [NSURL URLWithString:[qualities objectForKey:#"medium"]];
NSLog(#"%#",[NSURL URLWithString:[qualities objectForKey:#"medium"]]);
activityIndicator.hidden = YES;
[playButton setImage:[UIImage imageNamed:#"play_button"] forState:UIControlStateNormal];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
}];
}
The line that gives the problem is _urlToLoad = [NSURL URLWithString:[qualities objectForKey:#"medium"]];
[NSURL URLWithString:[qualities objectForKey:#"medium"]] returns null..
How do I solve this?
In my case , I was getting 0 key value pair for
NSDictionary *qualities = [HCYoutubeParser h264videosWithYoutubeURL:url];
Ie , I was getting qualities having 0 key value pair.
I found that code in HCYoutubeParser.m , in method + (NSDictionary *)h264videosWithYoutubeID:(NSString *)youtubeID a variable signature variable was not getting initialized , so I replaced NSString *signature = nil; with NSString *signature = #"";

Play MP3 Files with iPhone SDK [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
What's the easiest way to play a music file such as Mp3 with pause button?
very very simple a button play and another button pause that music
These are the codes for the requested actions,
appSoundPlayer is a property of AVAudioPlayer declared in h file. Also this example plays a song in the resource folder.
#pragma mark -
#pragma mark *play*
- (IBAction) playaction {
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"songname" ofType:#"mp3"];
NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
self.soundFileURL = newURL;
[newURL release];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
// Registers the audio route change listener callback function
AudioSessionAddPropertyListener (
kAudioSessionProperty_AudioRouteChange,
audioRouteChangeListenerCallback,
self
);
// Activates the audio session.
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: nil];
self.appSoundPlayer = newPlayer;
[newPlayer release];
[appSoundPlayer prepareToPlay];
[appSoundPlayer setVolume: 1.0];
[appSoundPlayer setDelegate: self];
[appSoundPlayer play];
[stopbutton setEnabled:YES];
[playbutton setEnabled: NO];
playbutton.hidden=YES;
pausebutton.hidden =NO;
}//playbutton touch up inside
#pragma mark -
#pragma mark *pause*
-(IBAction)pauseaction {
[appSoundPlayer pause];
pausebutton.hidden = YES;
resumebutton.hidden = NO;
}//pausebutton touch up inside
#pragma mark -
#pragma mark *resume*
-(IBAction)resumeaction{
[appSoundPlayer prepareToPlay];
[appSoundPlayer setVolume:1.0];
[appSoundPlayer setDelegate: self];
[appSoundPlayer play];
playbutton.hidden=YES;
resumebutton.hidden =YES;
pausebutton.hidden = NO;
}//resumebutton touch up inside
#pragma mark -
#pragma mark *stop*
-(IBAction)stopaction{
[appSoundPlayer stop];
[playbutton setEnabled:YES];
[stopbutton setEnabled:NO];
playbutton.hidden=NO;
resumebutton.hidden =YES;
pausebutton.hidden = YES;
}//stopbutton touch up inside
For short sounds or when the MP3 does not play well on the suggested code you can always use:
SystemSoundID soundID;
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/sound.mp3", [[NSBundle mainBundle] resourcePath]]];
AudioServicesCreateSystemSoundID((CFURLRef)url, &soundID);
AudioServicesPlaySystemSound (soundID);
Don't forget to add:
#import <AudioToolbox/AudioToolbox.h>
well here is a good tutorial available.
The theme is
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
and when you want to pause;
[audioPlayer pause];
hope this helps.
I'm afraid the answer stated no longer works in iOS 7 and above. You will need to use the following code:
in the header file (.h)
In order to handle the delegate methods like when the playing of the audio has finished audioPlayerDidFinishPlaying:, inherit from AVAudioPlayerDelegate .
#property (nonatomic, strong) AVAudioPlayer *player;
in the implementation file (.m)
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: resourceName
ofType: #"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: nil];
_player = newPlayer;
[_player prepareToPlay];
[_player setDelegate: self];
[_player play];
I like simple code and here is my solution : (Remember to add switch button to get music play. Have fun)
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
{
NSURL* bgURL;
AVAudioPlayer* bgPlayer;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
bgURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"mp3"]];
bgPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:bgURL error:nil];
}
#pragma mark AVAudioPlayer
- (IBAction)toggleMusic:(UISwitch*)sender {
NSLog(#"togging music %s", sender.on ? "on" : "off");
if (bgPlayer) {
if (sender.on) {
[bgPlayer play];
}
else {
[bgPlayer stop];
}
}
}
The Apple documentation here should have everything you need to know.
DIRAC API is free and quite easy to use.
We've used it in my talking robot app http://itunes.apple.com/us/app/daidai/id484833168 and it has been amazing to me how it manages to change the speed and pitch of voice
http://www.dspdimension.com/download/
The oalTouch sample code on the Apple iOS developer web site does what you want, and is ready to run.
It also shows how to test if another app (eg ipod) is playing a file already, which is handy if you want to allow your users to listen to their own music instead of yours.

Resources