티스토리 뷰

반응형

AudioPlayer

// https://ahmetkasimnazli.medium.com/creating-an-audio-player-with-avkit-in-swiftui-a17f3b704fad
// 오디오 플레이어
struct ContentView: View {
    @State var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            HStack {
                Button {
                    if viewModel.isPlaying {
                        viewModel.pause()
                    } else {
                        viewModel.play()
                    }
                } label: {
                    Image(systemName: viewModel.isPlaying ? "pause.circle" : "play.circle")
                        .font(.largeTitle)
                }
                
                Slider(value: $viewModel.currentTime, in: 0...viewModel.totalTime) { editing in
                    if editing {
                        if viewModel.isPlaying {
                            viewModel.pause()
                        }
                    } else {
                        viewModel.player?.currentTime = viewModel.currentTime
                        viewModel.play()
                    }
                }
            }
            
            HStack {
                Text("\(formatTime(viewModel.currentTime))")
                Spacer()
                Text("\(formatTime(viewModel.totalTime))")
            }
        }
        .animation(.linear(duration: 0.1), value: viewModel.currentTime)
        .padding()
    }
    
    private func formatTime(_ time: TimeInterval) -> String {
        let seconds = Int(time) % 60
        let minutes = Int(time) / 60
        return String(format: "%02d:%02d", minutes, seconds)
    }
}
import Foundation
import AVKit

/// 오디오 뷰모델
@Observable final class ViewModel {
    
    var player: AVAudioPlayer?
    var isPlaying = false
    var totalTime: TimeInterval = 0.0
    var currentTime: TimeInterval = 0.0
    var timer: Timer?
    
    init() {
        guard let url = Bundle.main.url(forResource: "sample", withExtension: "wav") else { return }
        setupAudio(withURL: url)
    }
    
    private func setupAudio(withURL url: URL) {
        do {
            // 무음모드에서도 재생되도록 설정
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
            try AVAudioSession.sharedInstance().setActive(true) // 오디오 세션 활성화. 앱이 백그라운드로 이동하거나 중단되었을 때, 다시 활성화해야함
            
            player = try AVAudioPlayer(contentsOf: url)
            player?.prepareToPlay()
            totalTime = player?.duration ?? 0.0
        } catch {
            print("Error loading audio: \(error)")
        }
    }
    
    func play() {
        guard let player else { return }
        isPlaying = true
        player.play()
        startTimer()
    }
    
    func pause() {
        guard let player else { return }
        isPlaying = false
        player.pause()
        stopTimer()
    }
    
    private func startTimer() {
        stopTimer()
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in
            self?.updateProgress()
        }
    }
    
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
    
    private func updateProgress() {
        guard let player else { return }
        
        currentTime = player.currentTime
        
        if !player.isPlaying {
            pause()
            currentTime = 0
        }
    }
}

iOS

Swift

SwiftUI

Xcode

Objective-C

Audio Player

Music Player

음악 재생기

노래 플레이어

// https://ahmetkasimnazli.medium.com/creating-an-audio-player-with-avkit-in-swiftui-a17f3b704fad // 오디오 플레이어 struct ContentView: View { @State var viewModel = ViewModel() var body: some View { VStack { HStack { Button { if viewModel.isPlaying { viewModel.pause() } else { viewModel.play() } } label: { Image(systemName: viewModel.isPlaying ? "pause.circle" : "play.circle" ) .font(.largeTitle) } Slider(값: $viewModel.currentTime, in: 0...viewModel.totalTime) { 편집 중 if 편집 { if viewModel.isPlaying { viewModel.pause() } } else { viewModel.player ?.currentTime = viewModel.currentTime viewModel.play() } } } HStack { Text("\(formatTime(viewModel.currentTime))") Spacer() Text("\(formatTime(viewModel.totalTime))") } } .animation(.linear(duration: 0.1), value: viewModel.currentTime) .padding() } private func formatTime(_ time: TimeInterval) -> String { let 초 = Int(time) % 60 let 분 = Int(time ) / 60 return String(형식: "%02d:%02d", 분, 초) } }
 
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함