ios音乐播放器使用综述

问题有:

1.  关于网络上的数据流播放,之前是使用github上的AudioStream库进行网络歌曲的播放。但是这么做之后发现跟AVPlayer(播放ipod歌曲)发生冲突,于是AudioSteamer库就只能放弃了。

2.  关于ipod的歌曲播放,基本上无法操作ipod的歌曲,如果要通过dlna传送本机ipod的歌曲,那么必须先将ipod的歌转存到本地,这个过程比较麻烦,于是放弃了。

3.  ipod的歌曲读取需要通过MediaPlayer、MediaItem来读取ipod的数据。

4.  在线音乐、流媒体、直播流都可以通过AVPlayer来播放,而不再使用AudioStreamer。

5.  ipod的歌曲播放可以用MediaPlayer中的IpodPlayer来播放,但是保存方便还是使用AVPlayer。

6.  AVPlayer可以播放本地歌曲,因此从网络下载的本地歌曲也可以是用这个来播放。

7.  AVPlayer类有个子类,AVQueuePlayer,可以添加队列进行控制播放。

总结:音乐播放器必须使用AVPlayer,可以播放应用内保存的音乐,播放网络音乐,播放网络电台、播放ipod音乐,设置后台播放,设置封面,还可以创建播放队列。

关于AVPlayer的使用有几个问题:

  1.  设置后台播放

    在info.plist中需要添加Required background modes,并且添加值App plays audio

    在应用的delegate中Launch函数里添加代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions



{



    // Override point for customization after application launch.



    {



        if([application respondsToSelector:@selector(beginReceivingRemoteControlEvents)])



            [application beginReceivingRemoteControlEvents];



        [self becomeFirstResponder]; // this enables listening for events



        



        [[AVAudioSessionsharedInstance] setCategory:AVAudioSessionCategory Playbackerror:nil];



        [[AVAudioSessionsharedInstance] setActive: YES error: nil];



    }



    return YES;



}



- (BOOL)canBecomeFirstResponder{



    return YES;



}

 

    setCategory这个方法设定了这个应用的声音播放实例可以在后台播放,并且音频播放是可打断或被打断的。

    delegate要继承UIResponser借口,beginReceivingControlEvents调用后就可以接受ipod control的消息。

    becomeFirstResponder方法使用后会在ipod control有响应后将消失传递到这个类做响应。

2.  后台播放时,ipod control的点击事件响应。

    在appdelegate中(因为设置成了响应者)加入响应代码

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {

    switch (event.subtype) {

        case UIEventSubtypeRemoteControlTogglePlayPause:

            NSLog(@"play btn toggle");

            break;

        case UIEventSubtypeRemoteControlPlay:

            NSLog(@"play event");

            break;

        case UIEventSubtypeRemoteControlPause:

            NSLog(@"pause event");

            break;

        case UIEventSubtypeRemoteControlStop:

            NSLog(@"stop event");

            break;

        case UIEventSubtypeRemoteControlPreviousTrack:

            NSLog(@"prev event");

            break;

        case UIEventSubtypeRemoteControlNextTrack:

            NSLog(@"next event");

            break;

        default:

            break;

    }

}

 

    这里做音乐播放器后台ipod操作的响应控制。

3.  后台播放时,设置ipod control的封面图片,歌曲名等信息。通过设置当前媒体播放器的信息来实现。

    在应用弹出去或者歌曲切换事件出发的时候调用该函数。

    

- (void)configNowPlayingInfoCenter {

    

    if (NSClassFromString(@"MPNowPlayingInfoCenter")) {

        

        MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];

        

        UIImage *image = [UIImage imageNamed:@"figo.png"];

        

        MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc] initWithImage:image];

        

        NSDictionary*songInfo = [NSDictionary dictionaryWithObjectsAndKeys:

                                 @"华哥", MPMediaItemPropertyArtist,

                                 @"嘿嘿", MPMediaItemPropertyTitle,

                                 artwork, MPMediaItemPropertyArtwork,

                                 @"嘿嘿", MPMediaItemPropertyAlbumTitle,

                                 nil];

        center.nowPlayingInfo = songInfo;

        

    }

}

在这些时候可以触发:

- (void)applicationDidEnterBackground:(UIApplication *)application

{

    [self configNowPlayingInfoCenter];

}
-(void)playerItemDidReachEnd:(NSNotification *)notification {

    [self configNowPlayingInfoCenter];

}

4.  音乐播放队列的播放顺序是通过监听音乐播放结束或开始,再做相应的处理,在appdelegat中监听事件。这些事件需要Audio框架中开启。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:)

                                                 name:AVPlayerItemDidPlayToEndTimeNotification object:[player currentItem]];

    监听这些事件后,进行播放队列调整。或者是ipod control切换歌曲的时候调整ipod封面和歌名。

5.  使用AVPlayer播放歌曲

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:)

                                                 name:AVPlayerItemDidPlayToEndTimeNotification object:[player currentItem]];

    

    AVPlayerItem *item1 = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://192.168.1.127/5.mp3"]];

    AVPlayerItem *item2 = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://192.168.1.127/1.mp3"]];

    AVPlayerItem *item3 = [AVPlayerItem playerItemWithAsset:[AVAsset assetWithURL:[NSURL URLWithString:@"http://shoutmedia.abc.net.au:10326"]]];

    AVPlayerItem *item4 = [AVPlayerItem playerItemWithAsset:[AVAsset assetWithURL:[NSURL URLWithString:@"http://192.168.1.127/1.mp3"]]];

    NSArray *items = @[item3,item4];

    queuePlayer = [AVQueuePlayer queuePlayerWithItems:items];
  [queuePlayer play];

   有队列,通过事件回调控制封面和播放顺序的方式。

6.  播放ipod的歌曲

    要使用Mediaplayer库,Audio库

MPMediaQuery *myPlaylistsQuery = [MPMediaQuery songsQuery];

    NSArray *playlists = [myPlaylistsQuery collections];

    GDSongNet *newSong;

    NSMutableArray *array = [[NSMutableArray alloc] init];;

    for (MPMediaPlaylist *playlist in playlists) {

        newSong = nil;

        newSong = [[GDSongNet alloc] init];

        NSArray *songs = [playlist items];

        for (MPMediaItem *song in songs) {

            newSong.songStatusType = [NSNumber numberWithInt:PLAYER_LOCAL];

            newSong.songCoverUrl = @"/Public/Images/nopic_80x80.jpg";

            newSong.songMusic_id = [song valueForProperty:MPMediaItemPropertyPersistentID];//MPMediaItemPropertyPersistentID

            newSong.songMusic_name = [song valueForProperty:MPMediaItemPropertyTitle];

            newSong.songSinger = [song valueForProperty:MPMediaItemPropertyArtist];//

            newSong.songType_id = [NSNumber numberWithInt:1];

            newSong.songUrl =  [song valueForProperty:MPMediaItemPropertyAssetURL];

            

            [array addObject:newSong];

        }

    }

    

    self.localMusics = array;

7.  AVPlayer检索元数据

    元数据的数组:

NSArray *metaDatas = [[[mPlayercurrentItem] asset] commonMetadata];

     遍历获取数据

    for (AVMetadataItem* item in mMetadata)

    {

        NSString* commonKey = [item commonKey];

        

        if ([commonKey isEqualToString:AVMetadataCommonKeyTitle])

        {

            [mTitleLabel setText:[item stringValue]];

            [mTitleLabel setHidden:NO];

        }

        if ([commonKey isEqualToString:AVMetadataCommonKeyCopyrights])

        {

            [mCopyrightLabel setText:[item stringValue]];

            [mCopyrightLabel setHidden:NO];

        }

    }

 

 

 

 附件:测试项目

你可能感兴趣的:(ios)