SwiftUI 음악재생

핏핏·2022년 12월 11일

[ios]SwiftUI

목록 보기
1/4
post-thumbnail

AVAudioPlayer , SwiftUI를 이용하여 음악 재생하기

AudioPlayerView 파일을 생성해준다.

ContentView에서 AudioPlayerView를 호출합니다.

import SwiftUI
import AVKit

struct ContentView: View {
    @State var audioPlayer: AVAudioPlayer!
    var body: some View {
        AudioPlayerView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

AudioPlayerView

재생상태바 구현

HStack{
                Text(formattedProgress).font(.caption.monospacedDigit())
                
                GeometryReader{ gr in
                    Capsule()
                        .stroke(Color.blue, lineWidth: 2)
                        .background(
                            Capsule()
                                .foregroundColor(Color.blue)
                                .frame(width: gr.size.width * progress, height: 8), alignment: .leading)
                }.frame( height: 8)
                
                Text(formattedDurtaion).font(.caption.monospacedDigit())
            }
            

버튼 영역구현

HStack {
                Spacer()
                Button(action: {
                    let decrease = self.audioPlayer.currentTime - 15
                    if decrease < 0.0 {
                        self.audioPlayer.currentTime = 0.0
                    } else {
                        self.audioPlayer.currentTime -= 15
                    }
                    
                }){
                    Image(systemName: "gobackward.15")
                        .font(.title)
                        .imageScale(.medium)
                }
                Spacer()
                Button(action: {
                    if audioPlayer.isPlaying {
                        playing = false
                        self.audioPlayer.pause()
                    }else if !audioPlayer.isPlaying{
                        playing = true
                        self.audioPlayer.play()
                    }
                    
                }){
                    Image(systemName: playing ? "pause.circle.fill" : "play.circle.fill")
                        .font(.title)
                        .imageScale(.large)
                }
                
                Spacer()
                Button(action: {
                    let increase = self.audioPlayer.currentTime + 15
                    if increase < self.audioPlayer.duration {
                        self.audioPlayer.currentTime = increase
                    } else {
                        self.audioPlayer.currentTime = duration
                    }
                    
                }){
                    Image(systemName: "goforward.15")
                        .font(.title)
                        .imageScale(.medium)
                }
                Spacer()
            }

mp3삽입

https://www.soundhelix.com/audio-examples
해당사이트에서 맘에드는 mp3파일을 다운받아서 프로젝트 asset에 삽입합니다.

초기화 함수 구현

func initialiseAudioPlayer(){

		let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.minute, .second]
        formatter.unitsStyle = .positional
        formatter.zeroFormattingBehavior = [.pad]
       
        
        let path = Bundle.main.path(forResource: "SoundHelix-Song-1", ofType: "mp3")!
        self.audioPlayer = try! AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
        self.audioPlayer.prepareToPlay()
        
        formattedDurtaion = formatter.string(from: TimeInterval(self.audioPlayer.duration))!
        
        duration = self.audioPlayer.duration
        
        Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            if !audioPlayer.isPlaying{
                playing = false
            }
            
            progress = CGFloat(audioPlayer.currentTime / audioPlayer.duration)
            
            formattedProgress = formatter.string(from: TimeInterval(self.audioPlayer.currentTime))!
        }
    }

최종 AudioPlayerView

//
//  AudioPlayerView.swift
//  PlayMusic
//
//  Created by 정민식 on 2022/12/11.
//

import SwiftUI
import AVKit

struct AudioPlayerView: View {
    
    @State var audioPlayer: AVAudioPlayer!
    @State var progress:CGFloat = 0.0
    @State private var playing: Bool = false
    @State var duration: Double = 0.0
    @State var formattedDurtaion: String = "20:00"
    @State var formattedProgress: String = "00:00"
    
    var body: some View {
        VStack {
            Spacer()
            
            HStack{
                Text(formattedProgress).font(.caption.monospacedDigit())
                
                GeometryReader{ gr in
                    Capsule()
                        .stroke(Color.blue, lineWidth: 2)
                        .background(
                            Capsule()
                                .foregroundColor(Color.blue)
                                .frame(width: gr.size.width * progress, height: 8), alignment: .leading)
                }.frame( height: 8)
                
                Text(formattedDurtaion).font(.caption.monospacedDigit())
            }
            
            Spacer()
            HStack {
                Spacer()
                Button(action: {
                    let decrease = self.audioPlayer.currentTime - 15
                    if decrease < 0.0 {
                        self.audioPlayer.currentTime = 0.0
                    } else {
                        self.audioPlayer.currentTime -= 15
                    }
                    
                }){
                    Image(systemName: "gobackward.15")
                        .font(.title)
                        .imageScale(.medium)
                }
                Spacer()
                Button(action: {
                    if audioPlayer.isPlaying {
                        playing = false
                        self.audioPlayer.pause()
                    }else if !audioPlayer.isPlaying{
                        playing = true
                        self.audioPlayer.play()
                    }
                    
                }){
                    Image(systemName: playing ? "pause.circle.fill" : "play.circle.fill")
                        .font(.title)
                        .imageScale(.large)
                }
                
                Spacer()
                Button(action: {
                    let increase = self.audioPlayer.currentTime + 15
                    if increase < self.audioPlayer.duration {
                        self.audioPlayer.currentTime = increase
                    } else {
                        self.audioPlayer.currentTime = duration
                    }
                    
                }){
                    Image(systemName: "goforward.15")
                        .font(.title)
                        .imageScale(.medium)
                }
                Spacer()
            }
            Spacer()
        }.padding()
            .onAppear(){
                initialiseAudioPlayer()
            }
        
    }
    
    func initialiseAudioPlayer(){
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.minute, .second]
        formatter.unitsStyle = .positional
        formatter.zeroFormattingBehavior = [.pad]
        
        let path = Bundle.main.path(forResource: "SoundHelix-Song-1", ofType: "mp3")!
        self.audioPlayer = try! AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
        self.audioPlayer.prepareToPlay()
        
        formattedDurtaion = formatter.string(from: TimeInterval(self.audioPlayer.duration))!
        
        duration = self.audioPlayer.duration
        
        Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            if !audioPlayer.isPlaying{
                playing = false
            }
            
            progress = CGFloat(audioPlayer.currentTime / audioPlayer.duration)
            
            formattedProgress = formatter.string(from: TimeInterval(self.audioPlayer.currentTime))!
        }
    }
}



struct AudioPlayerView_Previews: PreviewProvider {
    static var previews: some View {
        AudioPlayerView()
            .previewLayout(
                PreviewLayout.fixed(width: 400, height: 300))
            .previewDisplayName("Default preview")
        AudioPlayerView()
            .previewLayout(
                PreviewLayout.fixed(width: 400, height: 300))
            .previewDisplayName("Default preview2")
            .environment(\.sizeCategory, .accessibilityExtraLarge)
    }
}
profile
계발자

0개의 댓글