如何跟踪歌曲何时完成AVAudioPlayer

时间:2017-06-23 16:10:09

标签: ios swift swift3 avaudioplayer audio-player

我想跟踪播放歌曲的时间。我从网上尝试了不同的解决方案,但他们无法解决我的问题。 我实现了audioPlayerDidFinishPlaying方法,但它无效。 如果播放歌曲完成,我怎么能理解?

我正在使用playSound功能

播放歌曲

playSound func:

func playSound(name: String ) {
    guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else {
        print("url not found")
        return
    }

    do {
        /// this codes for making this app ready to takeover the device audio
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        /// change fileTypeHint according to the type of your audio file (you can omit this)
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)
        // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
        player!.play()
    } catch let error as NSError {
        print("error: \(error.localizedDescription)")
    }
}

audioPlayerDidFinishPlaying func:

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    print("finished")//It is not working, not printing "finished"
}

如何解决我的问题?播放歌曲的方法如何完成

编辑:我正在添加整个代码。

//
//  ViewController.swift

import UIKit
import SwiftVideoBackground
import AudioToolbox
import AVFoundation


class ViewController: UIViewController,AVAudioPlayerDelegate {

    var player: AVAudioPlayer?

    @IBOutlet weak var backgroundVideo: BackgroundVideo!

    @IBOutlet weak var initialLabel: UILabel!

    @IBOutlet weak var statementLabel: UILabel!


    var mp3: [String] = ["turk_milleti_demokrattir","xyz"]
    var fav: [String] = ["0","0"]
    var name: [String] = ["Türk milleti demokrattır","xy"]


    var toggleState = 1


    @IBOutlet weak var playB: UIButton!

    var counter = 0

    var duration = 0.1


    override func viewDidLoad() {
        super.viewDidLoad()

        player?.delegate = self

        playB.setImage(UIImage(named: "playbtn.png"), for: .normal)

        statementLabel.text = name[counter]

       backgroundVideo.createBackgroundVideo(name: "abc", type: "mp4")





    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func likeButton(_ sender: Any) {


        fav[counter] = "1"
        print(fav[0...1])


    }

    @IBAction func playButton(_ sender: Any) {
        let name = mp3[counter]
        playSound(name: name)


        let playBtn = sender as! UIButton
        if toggleState == 1 {
            player?.play()
            toggleState = 2
            playBtn.setImage(UIImage(named: "pausebtn.png"), for: .normal)
        } else {
            player?.pause()
            toggleState = 1
            playBtn.setImage(UIImage(named:"playbtn.png"),for: .normal)
        }  

    }


    @IBAction func nextButton(_ sender: Any) {

        counter = counter + 1

        if counter == mp3.count {
            counter = 0
        }

        toggleState = 2
        playB.setImage(UIImage(named: "pausebtn.png"), for: .normal)

        playSound(name: mp3[counter])

        statementLabel.text = name[counter]

    }





    func playSound(name: String ) {
        guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else {
            print("url not found")
            return
        }

        do {
            /// this codes for making this app ready to takeover the device audio
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

            /// change fileTypeHint according to the type of your audio file (you can omit this)
            player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)



            // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
            player!.play()
        } catch let error as NSError {
            print("error: \(error.localizedDescription)")
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("finished")//It is not working, not printing "finished"
    }


}

2 个答案:

答案 0 :(得分:2)

我在Leo Dabus的帮助下解决了我的问题。 我改变了我编辑的代码。我搬了player?.delegate = selfplaySound func。最后,它正在发挥作用。

playSound& audioPlayerDidFinishPlaying功能:

  func playSound(name: String ) {
        guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else {
            print("url not found")
            return
        }

        do {
            /// this codes for making this app ready to takeover the device audio
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

            /// change fileTypeHint according to the type of your audio file (you can omit this)
            player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)

            player?.delegate = self

            // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
            player!.play()
        } catch let error as NSError {
            print("error: \(error.localizedDescription)")
        }
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("finished")//It is working now! printed "finished"!
    }

不要忘记将AVAudioPlayerDelegate添加到ViewController!

class ViewController: UIViewController,AVAudioPlayerDelegate {

答案 1 :(得分:2)

您没有正确设置播放器的代理。

在viewDidLoad中,你的播放器将是零,所以这一行:

    player?.delegate = self

什么都不做(问号是可选的链接,所以如果玩家== nil,它什么都不做。)

您需要在加载播放器后设置委托。