简体   繁体   中英

Swift 3, XCode 8 - Changing Local Video on Button Press - AVPlayer

I'm trying to create an app that will change videos on each button press.

Currently: The video loops and the button does nothing

Goals: The button will cycle to the next video based on the array index. I plan on associating another array with text descriptions to go along with each video.

Thoughts: I think a JSON based implementation would probably work better. This is my first iOS app and I'm trying to keep it simple. Thoughts and help are greatly appreciated!

Here is the function that loops the video. The name of name of the video is held in an array called videoId:

class WorkoutViewController: UIViewController{
@IBOutlet weak var videoView: UIView!
@IBOutlet weak var infoCardView: UIView!

var currentVidIndex: Int = 0    

var player: AVPlayer?
var playerLayer: AVPlayerLayer?    

override func viewDidLoad() {
    super.viewDidLoad()
    shadowBackground()
}
var videoId: [String] = ["bodyweight_fitness_arch","bodyweight_fitness_assisted_squat","bodyweight_fitness_band_dislocates"]


func setLoopingVideo(){
    let path = Bundle.main.path(forResource: videoId[currentVidIndex], ofType: "mp4")
    let url = URL.init(fileURLWithPath: path!)
    let player = AVPlayer(url: url)
    let playerLayer = AVPlayerLayer(player: player) 
    playerLayer.frame = videoView.bounds
    self.videoView.layer.insertSublayer(playerLayer, at: 0)
    player.play()

    // Create observer to monitor when video ends, when it does so set the video time to the start (zero)

    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: player.currentItem, queue: nil)

    {
        Notification in player.seek(to: kCMTimeZero)
        player.play()  
    }   

func shadowBackground(){
    infoCardView.layer.cornerRadius = 3.0
    infoCardView.layer.shadowColor = 
           UIColor.black.withAlphaComponent(0.6).cgColor
    infoCardView.layer.shadowOffset = CGSize(width: 0, height: 0)
    infoCardView.layer.shadowOpacity = 0.9        

    videoView.layer.cornerRadius = 3.0
    videoView.layer.shadowColor = 
    UIColor.black.withAlphaComponent(0.6).cgColor
    videoView.layer.shadowOffset = CGSize(width: 0, height: 0)
    videoView.layer.shadowOpacity = 0.9

}
override func viewDidAppear(_ animated: Bool) {
    setLoopingVideo()
}

@IBAction func showNextVideo(_ sender: UIButton) {
    if currentVidIndex < videoId.count{
        currentVidIndex += 1
        print (currentVidIndex)
    } else {
        NSLog("Nothing")
    }
}

What it looks like

If you want to change a video on every button click, you have to create always new AVPlayer object.

  1. create and remember your AVPlayer object
  2. create and remember your AVPlayerLayer

-- when button clicked --

  1. remove AVPlayerLayer from the parent
  2. stop AVPlayer (old video)
  3. goto step 1 with new video URL

Here was my solution:

func clearVid(){
    if let player = self.player{
        player.pause()
        self.player = nil

    }
    if let layer = self.playerLayer{
        layer.removeFromSuperlayer()
        self.playerLayer = nil
    }

   self.videoView.layer.sublayers?.removeAll()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM