首页 > 解决方案 > 在视频和照片媒体之间切换类似于 snapchat 或 instagram 中的故事功能

问题描述

我允许用户捕获图像和视频并将它们保存到我的服务器。当用户点击图标时,他们应该能够查看存储在该特定位置的所有媒体。目前,我很难评估视频何时结束以移动到下一段媒体,或者视频何时完成处理并准备好播放

我正在尝试使用通知中心在准备好播放时进行更新,但它仍然无法正常工作。我还包括一个计时器,它可以让图像自动查看 3 秒,或者如果它是视频,它会获取视频持续时间并在视频结束播放后移动

//方法: func showFeed() {

        //ensure there is media to present
        if media.count > 0 {
            //check if media is of type video or image
            //show first piece of media initially
            if media[mediaIndex].media_type! == "CAMERA" || media[mediaIndex].media_type! == "LIBRARY" {
                videoDisplay.isHidden = true

                timeInterval = 3.0
                photoDisplay.kf.setImage(with: URL(string: Constants.Server.PHOTO_URL + media[mediaIndex].media_photo_url!))


            } else if media[mediaIndex].media_type! == "VIDEO" {

                //check if photoview is hidden & if not hide it
                videoDisplay.isHidden = false

                var url = URL(fileURLWithPath: Constants.Server.VIDEO_URL + media[mediaIndex].media_video_url!)

                prepareToPlay(url)

            }

            //date formatter

            //media time stamp
            let timeStampStr = formatter.string(from: media[mediaIndex].media_created_at!)
            media_time_stamp.text = GlobalService.sharedInstance().UTCToLocal(date: timeStampStr)
        }

    //begin timer
    //make sure repeat is set to false so timer is fresh
    /*
    if timerCounter == nil {
        timerCounter = Timer.scheduledTimer(withTimeInterval: TimeInterval(timeInterval), repeats: false, block: {(timer) in
              self.scrollToNextCell()
        })
    }
    */

}

这是对 prepareToPlay() 的下一个调用

func prepareToPlay(_ url: URL) { //从播放器获取时间间隔

    let asset = AVAsset(url: url)

    let assetKeys = [
        "playable",
        "hasProtectedContent"
    ]

    playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)

    playerItem!.addObserver(self,
                           forKeyPath: #keyPath(AVPlayerItem.status),
                           options: [.old, .new],
                           context: &playerItemContext)

    player = AVPlayer(playerItem: playerItem!)

}

//处理播放项状态的变化 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

    // Only handle observations for the playerItemContext
    guard context == &playerItemContext else {
        super.observeValue(forKeyPath: keyPath,
                           of: object,
                           change: change,
                           context: context)
        return
    }

    if keyPath == #keyPath(AVPlayerItem.status) {
        let status: AVPlayerItem.Status
        if let statusNumber = change?[.newKey] as? NSNumber {
            status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
        } else {
            status = .unknown
        }

        // Switch over status value
        switch status {
        case .readyToPlay:

        //hide loading screen
        mediaLoadingView.isHidden = true
        activityIndicator.stopAnimating()
        //play video
        let assetDuration = player?.currentItem?.asset.duration
        let duration = CMTimeGetSeconds(assetDuration!)
        let timeIntervalDuration = Float(duration)
        timeInterval = timeIntervalDuration
        //add player to player layer
        playerLayer = AVPlayerLayer(player: player!)

        //add player layer to UIView
        //move resize aspect fill to where it will be loaded before frame of layer is calculated
        playerLayer!.videoGravity = .resizeAspectFill

        playerLayer!.frame = self.view.bounds

        videoDisplay.layer.addSublayer(playerLayer!)
         player?.play()

        // Player item is ready to play.
        case .failed:
         let alert = SCLAlertView()
         alert.showError("Failed", subTitle: "video was unable to properly load")
        case .unknown:

            // Player item is not yet ready.
            mediaLoadingView.isHidden = false
            activityIndicator.startAnimating()
            print("player not yet ready")
        }
    }
}

我打算让媒体(如果是视频)立即开始播放,但它没有

标签: swiftavfoundationinstagramavkitsnapchat

解决方案


推荐阅读