[UIKit] Spotify Clone: Player 3

Junyoung Park·2022년 9월 10일
0

UIKit

목록 보기
20/142
post-thumbnail
post-custom-banner

Building Spotify App in Swift 5 & UIKit - Part 20 - Player Cover (Xcode 12, 2021, Swift 5) - App

Spotify Clone: Player 3

구현 목표

  • 플레이리스트 전체 재생 시 앨범 이미지 표현
  • 인덱스 사용 플레이리스트 재생

구현 태스크

  1. 트랙 배열 파라미터로 넘길 때 앨범 변수 추가한 새로운 변수 생성
  2. 뒤로 가기 버튼(backward) 클릭 시 새로운 큐 아이템 생성

핵심 코드

func playlistHeaderCollectionReusableViewDidTapPlayAll(_ header: PlaylistHeaderCollectionReusableView) {
        let tracksWithAlbum: [AudioTrack] = tracks.compactMap { track in
            var track = track
            track.album = self.album
            return track
        }
        PlaybackPresenter.shared.startPlayback(from: self, tracks: tracksWithAlbum)
    }
  • 현재 트랙 데이터에는 앨범 이미지로 사용 가능한 album 변수가 널 값이기 때문에 플레이리스트 뷰 컨트롤러가 가지고 있는 앨범 이미지를 추가
func didTapForward() {
        if tracks.isEmpty {
            player?.pause()
            player?.play()
        } else if let player = playerQueue {
            player.advanceToNextItem()
            guard index + 1 < tracks.count else { return }
            index += 1
            playerVC?.refreshUI()
        }
    }
// PlayBackPresenter
    
func refreshUI() {
        controlsView.configure(with: PlayerControlsViewViewModel(title: dataSource?.songName, subtitle: dataSource?.subtitle))
        imageView.sd_setImage(with: dataSource?.imageURL, completed: nil)
    }
// PlayerViewController
  • 실제 재생을 담당하는 서비스 클래스 내에서 앞으로 이동 버튼 감지 → 음원 재생(player.advanceToNextItem)과 함께 UI 패치 → refreshUI() 함수에서 사용하는 dataSourceindex 업데이트를 통해 값이 변경된 상태이기 때문에 UI 패치 성공
func didTapBackward() {
        if tracks.isEmpty {
            player?.pause()
        } else if let player = playerQueue {
            playerQueue?.pause()
            playerQueue?.removeAllItems()
            
            guard index - 1 >= 0 else { return }
            index -= 1
            var items = [AVPlayerItem]()
            
            for idx in index..<tracks.count {
                let track = tracks[idx]
                guard let url = URL(string: track.preview_url ?? "") else { continue }
                let item = AVPlayerItem(url: url)
                items.append(item)
            }
            playerQueue = AVQueuePlayer(items: items)
            playerQueue?.play()
            playerQueue?.volume = 0
            playerVC?.refreshUI()
        }
    }
  • 뒤로 가기 기능은 AVQueuePlayer 내부에서 구현되어 있지 않기 때문에 새로운 큐 배열을 만들어 사용 중
  • 뒤로 가기 버튼 할당 시마다 새로운 playerQueue를 만들어야 하기 때문에 속도 비효율적 → 단일/복수 플레이리스트 재생 모두 단일한 player 사용할 수 있다면 보다 효율적으로 시간을 사용 가능할 것이라 예상

구현 화면

profile
JUST DO IT
post-custom-banner

0개의 댓글