본문 바로가기
Dev.Mobile/iPhone

[iOS] ZenPlayer for iOS 음악재생 기능 추가

by Devkin 2012. 7. 24.

HTM5+CSS3 조합의 ZenPlayer 를 보면 UI가 매우 수려하다. 해당 UI가 GitHub 에 iOS 용으로 포팅되어 올라왔다. 음악재생등의 기능은 없이 단순히 UI만 구현되어 있는 버전이다. CoreAnimation Layer 를 사용하여 애니메이션 전환이 구현되어 있고, 웹UI와 비교해서는 탐색을 위한 터치 이벤트는 현재 iOS용에서는 구현되어 있지 않다. 만일, 해당 터치이벤트가 추가적으로 구현이 안된다면 따로 구현하여 적용하고 싶을 정도로 훌륭한 UI다.



음악재생 기능을 위한 MPMusicPlayerController 추가


오리지널 ZenPlayer-for-iOS Repo 를 fork 하여, iPod 음악목록을 가져와 랜덤(셔플)하게 재생하는 기능을 구현. MPMediaQuery 로 Music 목록에서 Title 로 그루핑하여 쿼리목록을 작성하고, MPMusicPlayerController 로 해당 쿼리를 Queue 하여 Shuffle 모드로 재생. 참고로 해당 재생 기능은 시뮬레이터에서는 지원하지 않는다. 간략히 코드를 살펴보면, 


Query Music

MPMediaQuery 로 iPod Music Type 에서 Title 로 Grouping 한 Query를, Shuffle Mode 로 설정된 MPMusicPlayerController 에 Queue 하고 NSNotificationCenter 를 이용하여, Item 의 재생상태와 변경여부를 통지받도록 설정.

- (void) queryMusic
{
    MPMediaQuery *q = [[MPMediaQuery alloc] init];
    [q addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType]];
    [q setGroupingType:MPMediaGroupingTitle];
    
    self.player = [MPMusicPlayerController applicationMusicPlayer];
    [self.player setRepeatMode:MPMusicRepeatModeAll];
    [self.player setShuffleMode:MPMusicShuffleModeSongs];
    [self.player setQueueWithQuery: q];
    
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(handleItemChanged:) 
                                                 name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification 
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleStateChanged:)
                                                 name:MPMusicPlayerControllerPlaybackStateDidChangeNotification
                                               object:nil];
    
    [self.player beginGeneratingPlaybackNotifications];
}

Play Music

버튼 클릭 시, 버튼 UI State를 변경하고 음악재생. 재생되는 Progress 상태를 표시하기 위해, NSTimer 를 이용하여 초당 진행상태를 float value (0.0 ~ 1.0) 로 할당하여 표시.

- (void) zenPlayerButtonDidTouchUpInside:(id)sender;
{
    LOG_CURRENT_METHOD;
    if(self.zenPlayerButton.state == ZenPlayerButtonStateNormal)
    {
        [self.player pause];
        [self.timerProgress invalidate];
    }
    else
    {
        [self.player play];
        self.timerProgress = [NSTimer scheduledTimerWithTimeInterval:1.0 
                                                              target:self 
                                                            selector:@selector(updateTime:) 
                                                            userInfo:nil 
                                                             repeats:YES];
        self.zenPlayerButton.state = ZenPlayerButtonStatePlaying;
    }
}

- (void) updateTime:(NSTimer *)timer
{
    if(self.player.playbackState == MPMusicPlaybackStatePlaying)
    {
        CGFloat progress = [self.player currentPlaybackTime] / [[self.player.nowPlayingItem valueForKey:MPMediaItemPropertyPlaybackDuration] doubleValue];
        self.zenPlayerButton.progress = progress;
        NSLog(@"progress : %f\n", progress);
    }
}

재생 음악 변경 시

해당곡 재생이 완료되고, 다음곡이 재생될 시점에 MPMusicPlayerControllerNowPlayingItemDidChangeNotification이 발생하며 해당 Noti 에서, 로딩 애니메이션을 표시하고 다시 재생 애니메이션 표시. (로컬에서는 로딩 state 가 큰 의미가 없으나, 다음곡이 재생된다는 표시를 위해 설정. 스트리밍 재생에서는 로딩 state 사용이 유용할 듯.)

- (void)handleItemChanged:(id)notification
{
    NSLog(@"ItemChanged:\n");
    if(self.player.playbackState == MPMusicPlaybackStatePlaying)
    {
        self.zenPlayerButton.state = ZenPlayerButtonStateLoading;
        self.zenPlayerButton.state = ZenPlayerButtonStatePlaying;
    }
}



GitHub Repo


원본 ZenPlayer-for-iOS Repo : https://github.com/noradaiko/ZenPlayer-for-iOS

음악재생 추가 fork Repo : https://github.com/dev-life/ZenPlayer-for-iOS


반응형

댓글