首页 > 解决方案 > SwiftUI:如何播放下一个音频

问题描述

我正在制作其中包含音频播放器并与 Firebase 连接的应用程序。我不知道如何播放下一首歌。我知道我必须尝试使用​​ firstIndex 但真的不知道在哪里可以找到答案,所以我在这里问请帮忙。这是代码:

import SwiftUI
import MediaPlayer
import AVFoundation
import FirebaseStorage

let MainColor = Color(#colorLiteral(red: 0.2588235294, green: 0.7411764706, 
blue: 0.7764705882, alpha: 1))
let SecondColor = Color(#colorLiteral(red: 0.4470588235, green: 0.7490196078, 
blue: 0.2705882353, alpha: 1))
let screenW = UIScreen.main.bounds.width
let screenH = UIScreen.main.bounds.height

struct ZespolView: View {
@State private var showFirst = false

@ObservedObject var bede_zycData : Bede_zycData

var body: some View{
    NavigationView{
        ScrollView(.horizontal, showsIndicators: false){
            HStack(spacing: 10){
                NavigationLink(
                    destination: AlbumCellBedeZyc(image: "bede_zyc_img", name: "Będę żyć, by kochać", artist: "Zespół Filadelfia", numberOfSongs: "11", dateOfRelase: "2008", bede_zycData: bede_zycData),
                    label: {ZespolCellView(image: "bede_zyc_img", name: "Będę żyć, by kochać", artist: "Zespół Filadelfia", numberOfSongs: "11", dateOfRelase: "2008")}).foregroundColor(.black)
            }
        }.frame(height: screenW/2.5 + 150)
        .navigationTitle("Test view")
    }
  }
}

struct ZespolCellView : View {
@State var image : String
@State var name : String
@State var artist : String
@State var numberOfSongs : String
@State var dateOfRelase : String
var body: some View{
    VStack(alignment: .leading){
        Image(image)
            .resizable()
            .scaledToFit()
            .cornerRadius(30)
            .shadow(color: Color.black.opacity(0.6), radius: 15)
            .frame(width: screenW/2.5, height: screenW/2.5)
        Text(name)
            .font(.system(size: 15, weight: .bold))
            .padding(5)
        Text(artist)
            .font(.system(size: 14, weight: .thin))
            .padding(.horizontal, 5)
    }.frame(width: screenW/2.5, height: screenW/2.5 + 150)
    .padding(.horizontal)
 }
}


struct AlbumCellBedeZyc : View {
@State var image : String
@State var name : String
@State var artist : String
@State var numberOfSongs : String
@State var dateOfRelase : String
@State private var isPresented = false

@ObservedObject var bede_zycData : Bede_zycData

@State private var currentSong : Bede_zycInfo?

@Environment(\.presentationMode) var mode1 : Binding<PresentationMode>

var body: some View{
    VStack{
        HStack{
            Image(image)
                .resizable()
                .scaledToFit()
                .cornerRadius(10)
                .shadow(color: Color.black.opacity(0.6), radius: 15)
                .frame(width: screenW/2.4, height: screenW/2.4)
            Spacer(minLength: 0)
            VStack(alignment: .leading, spacing: 5){
                HStack{
                    Text("Album")
                        .font(.system(size: 15, weight: .thin))
                    Circle()
                        .frame(width: 5, height: 5)
                    Text(numberOfSongs)
                        .font(.system(size: 15, weight: .thin))
                    Circle()
                        .frame(width: 5, height: 5)
                    Text(dateOfRelase)
                        .font(.system(size: 15, weight: .thin))
                }.foregroundColor(Color.black.opacity(0.5))
                Text(name)
                    .font(.title)
                    .foregroundColor(.black)
                Text(artist)
                    .foregroundColor(Color.black.opacity(0.5))
                    .font(.system(size: 19, weight: .thin))
            }.frame(width: screenW/2.3)
        }.frame(width: screenW - 30)
        .padding(.top, 150)
        .padding(.horizontal)
        HStack(spacing: 18){
            Button(action: {
                
            }, label: {
                ZStack{
                    Color.black
                    VStack{
                        Image(systemName: "play.circle")
                        Text("Odtwarzaj")
                    }.font(.system(size: 18))
                    .foregroundColor(.white)
                }.frame(width: screenW/2.3, height: 50, alignment: .center)
                .cornerRadius(10)
                .shadow(radius: 15)
            }).padding(.leading)
            Button(action: {
                
            }, label: {
                ZStack{
                    Color.black.opacity(0.05)
                    VStack{
                        Image(systemName: "shuffle")
                        Text("Lososwo")
                    }.font(.system(size: 18))
                    .foregroundColor(.black)
                }.frame(width: screenW/2.3, height: 50, alignment: .center)
                .cornerRadius(10)
                .shadow(radius: 15)
            }).padding(.trailing)
        }.frame(width: screenW - 30)
        .padding(.horizontal)
        ScrollView(.vertical, showsIndicators: false){
            LazyVStack(alignment: .leading){
                ForEach(bede_zycData.bede_zyc, id:\.self){ data in
                    NavigationLink(destination:
                                    PlayerViewBedeZyc(bede_zycData: data, album: name, image: image, artist: artist)
                                   , label: {
                                    HStack{
                                        Text(data.number)
                                            .foregroundColor(Color.black.opacity(0.9))
                                            .font(.system(size: 20))
                                            .padding(.horizontal)
                                        VStack(alignment: .leading){
                                            Text(data.name)
                                                .foregroundColor(Color.black)
                                                .font(.system(size: 20))
                                            Text(artist)
                                                .foregroundColor(Color.black.opacity(0.5))
                                                .font(.system(size: 18))
                                        }
                                        Spacer()
                                        Text("2:36")
                                            .foregroundColor(Color.black.opacity(0.5))
                                            .font(.system(size: 18))
                                            .padding()
                                    }.padding()
                                })
                }
            }.padding(.top)
        }
    }.padding(.horizontal)
    .edgesIgnoringSafeArea(.top)
    .navigationBarBackButtonHidden(true)
    .navigationBarItems(leading: Button(action: {
        self.mode1.wrappedValue.dismiss()
    }, label: {
        Image(systemName: "chevron.left")
            .foregroundColor(.black)
            .font(.system(size: 28))
    }))
  }
}

struct PlayerViewBedeZyc : View {
@Environment(\.presentationMode) var presentationMode1
@State var bede_zycData : Bede_zycInfo
@State var album : String
@State var image : String
@State var artist : String

@State var player = AVPlayer()
@State var isPlaying : Bool = false

var body: some View{
    VStack(alignment: .center){
        Text(album)
            .bold()
        .padding(.top, 90)
        .padding()
        
        Image(image)
            .resizable()
            .scaledToFit()
            .cornerRadius(10)
            .shadow(radius: 20)
            .frame(width: screenW/1.3, height: screenW/1.3)
            .padding()
        
        Text(bede_zycData.name)
            .font(.title)
            .bold()
            .multilineTextAlignment(.center)
            .padding()
        Text(artist)
            .foregroundColor(Color.black.opacity(0.5))
            .font(.system(size: 18))
            .padding(.bottom, 50)
        HStack(spacing: 20){
            Button(action: {
                
            }, label: {
                Image(systemName: "shuffle")
            }).foregroundColor(Color.black.opacity(0.4))
            .font(.system(size: 22))
            Button(action: {
                
            }, label: {
                Image(systemName: "backward.end")
            }).foregroundColor(Color.black)
            .font(.system(size: 40))
            Button(action: {
                
            }, label: {
                Image(systemName: "play.circle")
            }).foregroundColor(Color.black)
            .font(.system(size: 80))
            Button(action: {
                playPause()
            }, label: {
                Image(systemName: "forward.end")
            }).foregroundColor(Color.black)
            .font(.system(size: 40))
            Button(action: {
                
            }, label: {
                Image(systemName: "repeat")
            }).foregroundColor(Color.black.opacity(0.4))
            .font(.system(size: 22))
        }
        Spacer()
    }.onAppear(){
        playSong()
    }
    
    .edgesIgnoringSafeArea(.top)
    .navigationBarBackButtonHidden(true)
    .navigationBarItems(leading: Button(action: {
        presentationMode1.wrappedValue.dismiss()
    }, label: {
        Image(systemName: "chevron.left")
            .foregroundColor(.black)
            .font(.system(size: 28))
    }))
}

func playSong(){
    let storage = Storage.storage().reference(forURL: self.bede_zycData.url)
    storage.downloadURL { (url, error) in
        if error != nil {
            print(error!)
        }else{
            do{
                try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
                try AVAudioSession.sharedInstance().setActive(true)
            }catch{
                
            }
            player = AVPlayer(playerItem: AVPlayerItem(url: url!))
        }
    }
}
func playPause(){
    self.isPlaying.toggle()
    if isPlaying == false{
        player.pause()
    }else{
        player.play()
    }
}
func next(){

  }
}

这是数据结构:

import SwiftUI
import Firebase

struct Bede_zycInfo : Hashable {
var id = UUID()
var name : String
var number : String
var url : String
}

class Bede_zycData : ObservableObject{

@Published public var bede_zyc = [Bede_zycInfo]()

func loadData(){
    Firestore.firestore().collection("Bede_zyc").order(by: "number", descending: false).getDocuments { (snapshot, error) in
        if error == nil {
            for doc in snapshot!.documents{
                let name = doc.data()["name"] as? String ?? "error"
                let number = doc.data()["number"] as? String ?? "number"
                let url = doc.data()["url"] as? String ?? "error?"
                
                self.bede_zyc.append(Bede_zycInfo(name: name, number: number, url: url))
            }
        }else{
            print(error)
        }
    }
    
  }
}

和@main代码:

import SwiftUI
import Firebase


@main
struct testApp: App {

let bede_zycdata = Bede_zycData()

init(){
    FirebaseApp.configure()
    bede_zycdata.loadData()
}

var body: some Scene {
    WindowGroup {
        ZespolView(bede_zycData: bede_zycdata)
    }
  }
}

请帮忙!!!

标签: firebaseaudiogoogle-cloud-firestoreswiftui

解决方案


推荐阅读