AVPlayer And Local Files

后端 未结 6 1460
名媛妹妹
名媛妹妹 2020-12-01 03:21

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 ASIH

相关标签:
6条回答
  • 2020-12-01 03:35

    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];
    
    0 讨论(0)
  • 2020-12-01 03:37

    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.

    0 讨论(0)
  • 2020-12-01 03:44

    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

    0 讨论(0)
  • 2020-12-01 03:49

    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.

    0 讨论(0)
  • 2020-12-01 03:57

    Try this

    NSString*thePath=[[NSBundle mainBundle] pathForResource:@"yourVideo" ofType:@"MOV"];
    NSURL*theurl=[NSURL fileURLWithPath:thePath];
    
    0 讨论(0)
  • 2020-12-01 03:58

    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];
    
     }
    
    0 讨论(0)
提交回复
热议问题