【问题标题】:Pick Music from iOS Library and Send / Save从 iOS 库中选择音乐并发送/保存
【发布时间】:2012-07-07 01:51:33
【问题描述】:

我对音乐文件有疑问。

我想从 iPhone/iTouch/iPad 的音乐库中选择 1 个/多个音乐文件并保存在我的文档文件夹中或发送到服务器。

我大致经历了MPMediaPickerControllerAddMusic(Sample Code)。 但是,我只能获得选择歌曲和播放的详细信息。

是否可以保存那些选定的歌曲,我也可以用它来发送到服务器?

谢谢

【问题讨论】:

  • 呵呵.. 我没有想过.. 我的全部要求基本上是能够将音乐文件(我在我的 Mac 上创建并通过 iTunes 同步到 iPhone 音乐库)发送到服务器..

标签: objective-c ios mpmediaitem mpmediapickercontroller


【解决方案1】:

是否可以保存那些选定的歌曲,我也可以用它们发送到服务器?

不,您只能播放 iTunes 资料库中的歌曲。
原始音频文件无法访问,可能是由于版权保护。

【讨论】:

    【解决方案2】:

    是的,有可能。

    我想对你有帮助

    // 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;
    
    }
    

    【讨论】:

    • 谢谢。有用。我为导出会话提供了错误的预设。
    【解决方案3】:

    我已经尝试并成功导出了 ipod 库歌曲。请在下面找到我的代码:

    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)
    } 
    }
    

    【讨论】:

    • 如何找到文件路径?你能告诉我代码和网址吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多