Pick Music from iOS Library and Send / Save
-
19-06-2021 - |
Question
I have a query regarding Music Files.
I want to select 1/more Music files from the Music Library of iPhone/iTouch/iPad and Save in my Documents Folder or Send it to Server.
I roughly went through MPMediaPickerController and AddMusic(Sample Code). But, I could only get details of selecting Songs and Playing it.
Is it possible to Save those selected Songs, which I can also use to Send to Server ?
Thanks
Solution
Is it possible to save those selected songs, which I can also use to send to server?
No, you can only play songs from the iTunes library.
The raw audio files are not accessible, probably due to copyright protection.
OTHER TIPS
Yes, it is possible.
I think it will help you
// Have to add this framework
//CoreMedia.framework
//AudioToolbox.framework
//CoreAudio.framework
//MediaPlayer.framework
//AVFoundation.framework
//in UploadAudioViewController.h file
#import <UIKit/UIKit.h>
#import <CoreAudio/CoreAudioTypes.h>
#import <AudioToolbox/AudioToolbox.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreMedia/CoreMedia.h>
@interface UploadAudioViewController : UIViewController<UIActionSheetDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,MPMediaPickerControllerDelegate,AVAudioRecorderDelegate, AVAudioPlayerDelegate,AVAudioSessionDelegate>{
MPMediaItem *song;
NSURL *exportURL;
}
@property (nonatomic, retain) NSData *audioData;
// in UploadAudioViewController.m file
#import "UploadAudioViewController.h"
//#import < AudioToolbox/AudioToolbox.h>
@interface UploadAudioViewController ()
@end
@implementation UploadAudioViewController
@synthesize musicPlayer,audioData;
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = @"Upload Audio";
self.musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
self.audioData=nil;
}
#pragma mark Browse Audio from Device
-(void)PickAudioForIndex_iPhone
{
if ([[[UIDevice currentDevice] model] isEqualToString:@"iPhone Simulator"]) {
//device is simulator
UIAlertView *alert1;
alert1 = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"There is no Audio file in the Device" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok",nil];
alert1.tag=2;
[alert1 show];
//[alert1 release],alert1=nil;
}else{
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = NO; // this is the default
[self presentViewController:mediaPicker animated:YES completion:nil];
}
}
#pragma mark Media picker delegate methods
-(void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {
// We need to dismiss the picker
[self dismissViewControllerAnimated:YES completion:nil];
// Assign the selected item(s) to the music player and start playback.
if ([mediaItemCollection count] < 1) {
return;
}
song = [[mediaItemCollection items] objectAtIndex:0];
[self handleExportTapped];
}
-(void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
// User did not select anything
// We need to dismiss the picker
[self dismissViewControllerAnimated:YES completion:nil ];
}
-(void)handleExportTapped{
// get the special URL
if (! song) {
return;
}
//[self startLoaderWithLabel:@"Preparing for upload..."];
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
NSLog (@"Core Audio %@ directly open library URL %@",
coreAudioCanOpenURL (assetURL) ? @"can" : @"cannot",
assetURL);
NSLog (@"compatible presets for songAsset: %@",
[AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]);
/* approach 1: export just the song itself
*/
AVAssetExportSession *exporter = [[AVAssetExportSession alloc]
initWithAsset: songAsset
presetName: AVAssetExportPresetAppleM4A];
NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);
exporter.outputFileType = @"com.apple.m4a-audio";
NSString *exportFile = [myDocumentsDirectory() stringByAppendingPathComponent: @"exported.m4a"];
// end of approach 1
// set up export (hang on to exportURL so convert to PCM can find it)
myDeleteFile(exportFile);
//[exportURL release];
exportURL = [NSURL fileURLWithPath:exportFile];
exporter.outputURL = exportURL;
// do the export
[exporter exportAsynchronouslyWithCompletionHandler:^{
int exportStatus = exporter.status;
switch (exportStatus) {
case AVAssetExportSessionStatusFailed: {
// log error to text view
NSError *exportError = exporter.error;
NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);
//errorView.text = exportError ? [exportError description] : @"Unknown failure";
//errorView.hidden = NO;
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
case AVAssetExportSessionStatusCompleted: {
NSLog (@"AVAssetExportSessionStatusCompleted");
//fileNameLabel.text = [exporter.outputURL lastPathComponent];
// set up AVPlayer
//[self setUpAVPlayerForURL: exporter.outputURL];
///////////////// get audio data from url
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
NSURL *audioUrl = exportURL;
NSLog(@"Audio Url=%@",audioUrl);
self.audioData = [NSData dataWithContentsOfURL:audioUrl];
break;
}
case AVAssetExportSessionStatusUnknown: {
NSLog (@"AVAssetExportSessionStatusUnknown");
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
case AVAssetExportSessionStatusExporting: {
NSLog (@"AVAssetExportSessionStatusExporting");
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
case AVAssetExportSessionStatusCancelled: {
NSLog (@"AVAssetExportSessionStatusCancelled");
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
case AVAssetExportSessionStatusWaiting: {
NSLog (@"AVAssetExportSessionStatusWaiting");
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
default: {
NSLog (@"didn't get export status");
//[self stopLoader];
//[self showAlertWithMessage:@"There ia an error!"];
break;
}
}
}];
}
#pragma mark conveniences
NSString* myDocumentsDirectory(){
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [paths objectAtIndex:0];;
}
void myDeleteFile (NSString* path){
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSError *deleteErr = nil;
[[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
if (deleteErr) {
NSLog (@"Can't delete %@: %@", path, deleteErr);
}
}
}
// generic error handler from upcoming "Core Audio" book (thanks, Kevin!)
// if result is nonzero, prints error message and exits program.
static void CheckResult(OSStatus result, const char *operation)
{
if (result == noErr) return;
char errorString[20];
// see if it appears to be a 4-char-code
*(UInt32 *)(errorString + 1) = CFSwapInt32HostToBig(result);
if (isprint(errorString[1]) && isprint(errorString[2]) && isprint(errorString[3]) && isprint(errorString[4])) {
errorString[0] = errorString[5] = '\'';
errorString[6] = '\0';
} else
// no, format it as an integer
sprintf(errorString, "%d", (int)result);
fprintf(stderr, "Error: %s (%s)\n", operation, errorString);
exit(1);
}
#pragma mark core audio test
BOOL coreAudioCanOpenURL (NSURL* url){
OSStatus openErr = noErr;
AudioFileID audioFile = NULL;
openErr = AudioFileOpenURL((__bridge CFURLRef) url,
kAudioFileReadPermission ,
0,
&audioFile);
if (audioFile) {
AudioFileClose (audioFile);
}
return openErr ? NO : YES;
}
I have tried and succeed in exporting the ipod library song . Please find my code below:
extension AudioPostViewController: MPMediaPickerControllerDelegate {
func mediaPicker(mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
dismissViewControllerAnimated(true, completion: {
print("You selected \(mediaItemCollection)")
let item: MPMediaItem = mediaItemCollection.items[0]
let pathURL: NSURL? = item.valueForProperty(MPMediaItemPropertyAssetURL) as? NSURL
if pathURL == nil {
Alert.showPopupWithMessage("Unable to read DRM protected file.")
return
}
let title = item.valueForProperty(MPMediaItemPropertyTitle) as? String ?? "Now Playing..."
print("\(pathURL), title : \(title) ")
// get file extension andmime type
let str = pathURL!.absoluteString
let str2 = str.stringByReplacingOccurrencesOfString("ipod-library://item/item", withString: "")
let arr = str2.componentsSeparatedByString("?")
var mimeType = arr[0]
mimeType = mimeType.stringByReplacingOccurrencesOfString(".", withString: "")
// Export the ipod library as .m4a file to local directory for remote upload
let exportSession = AVAssetExportSession(asset: AVAsset(URL: pathURL!), presetName: AVAssetExportPresetAppleM4A)
exportSession?.shouldOptimizeForNetworkUse = true
exportSession?.outputFileType = AVFileTypeAppleM4A
FilePath.removeAudioFile() // Remove file if it exists
let fileUrl = FilePath.testFilePathURL()
exportSession?.outputURL = fileUrl
exportSession?.exportAsynchronouslyWithCompletionHandler({ () -> Void in
if exportSession!.status == AVAssetExportSessionStatus.Completed {
dispatch_async(dispatch_get_main_queue(), {
// Prepare audio to play
self.audioTitle = title
self.audioPath = fileUrl
self.mimeType = "audio/m4a"
self.audioFileName = "audio.m4a"
UIView.animateWithDuration(0.45, animations: {
if Platform.DeviceType.iPhone4 {
self.libraryBottomSpacing.constant = 5
self.view.layoutIfNeeded()
} else {
self.libraryBottomSpacing.constant = 25
self.view.layoutIfNeeded()
}
}, completion: {
(v: Bool) in
self.loadJukeBox(self.audioPath!, title: title)
})
})
} else {
dispatch_async(dispatch_get_main_queue(), {
Alert.showPopupWithMessage("Unable to read file as its DRM protected.")
})
}
})
})
}
func mediaPickerDidCancel(mediaPicker: MPMediaPickerController) {
dismissViewControllerAnimated(true, completion: nil)
}
}