Использование AVSynchronizedLayer на avplayer в Swift 4 - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь добавить анимации на мой avplayer с помощью AVSynchronizedLayer. Для этого я добавил анимации на CALayer и добавил этот слой в AVSynchronizedLayer. Но анимация не работает, просто работает простое видео.

func exportVideoWithAnimation() {
        let composition = AVMutableComposition()
        let track =  self.asset?.tracks(withMediaType: AVMediaType.video)
        let videoTrack:AVAssetTrack = track![0] as AVAssetTrack
        let timerange = CMTimeRangeMake(kCMTimeZero, (self.asset?.duration)!)
        let compositionVideoTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: CMPersistentTrackID())!

        do {
            try compositionVideoTrack.insertTimeRange(timerange, of: videoTrack, at: kCMTimeZero)
            compositionVideoTrack.preferredTransform = videoTrack.preferredTransform
        } catch {
            print(error)
        }

        //if your video has sound, you don’t need to check this
        if self.audioIsEnabled {
            let compositionAudioTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: CMPersistentTrackID())!

            for audioTrack in (self.asset?.tracks(withMediaType: AVMediaType.audio))! {
                do {
                    try compositionAudioTrack.insertTimeRange(audioTrack.timeRange, of: audioTrack, at: kCMTimeZero)
                } catch {
                    print(error)
                }
            }
        }

        let size = videoTrack.naturalSize

        let videolayer = CALayer()
        videolayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)


        parentlayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        parentlayer.addSublayer(videolayer)
        //this is the animation part
        var time = [0.00001, 4, 9, 12, 16] //I used this
        var imgarray = self.selectedImageArray

        parentlayer.removeFromSuperlayer()



        for image in 0..<self.selectedImageArray.count {
            let nextPhoto = imgarray[image]

            let horizontalRatio = CGFloat(self.outputSize.width) / nextPhoto.size.width
            let verticalRatio = CGFloat(self.outputSize.height) / nextPhoto.size.height
            let aspectRatio = min(horizontalRatio, verticalRatio)
            let newSize: CGSize = CGSize(width: nextPhoto.size.width * aspectRatio, height: nextPhoto.size.height * aspectRatio)
            let x = newSize.width < self.outputSize.width ? (self.outputSize.width - newSize.width) / 2 : 0
            let y = newSize.height < self.outputSize.height ? (self.outputSize.height - newSize.height) / 2 : 0
            let blackLayer = CALayer()
            blackLayer.removeAllAnimations()
            //MARK:- Animations
            ///#1. left->right///
            if(self.globalSelectedTransitionTag == 0){
                blackLayer.frame = CGRect(x: 0, y: 0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor
                blackLayer.opacity = 0
                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)


                let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
                if(image%2==0){
                    scaleAnimation.values = [0.9, 1.0, 0.9]
                }else{
                    scaleAnimation.values = [1.0, 0.9, 1.0]
                }
                scaleAnimation.beginTime = CFTimeInterval(time[image])
                scaleAnimation.duration = 10
                scaleAnimation.isRemovedOnCompletion = false
                blackLayer.add(scaleAnimation, forKey: "transform.scale")

                let fadeInOutAnimation = CABasicAnimation(keyPath: "opacity")
                fadeInOutAnimation.fromValue = 1
                fadeInOutAnimation.toValue = 0.6
                fadeInOutAnimation.duration = 10
                fadeInOutAnimation.beginTime = CFTimeInterval(time[image])
                fadeInOutAnimation.isRemovedOnCompletion = false
                blackLayer.add(fadeInOutAnimation, forKey: "opacity")

            }
                //2.right->left
        else if(self.globalSelectedTransitionTag == 1){
                if(image == 0 || image == 2 || image == 4){
                    blackLayer.frame = CGRect(x: 0, y: -videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let animation = CABasicAnimation()
                    animation.keyPath = "position.y"
                    animation.fromValue = videoTrack.naturalSize.height
                    animation.toValue = -2*videoTrack.naturalSize.height
                    animation.duration = 10
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    // animation.speed = 0.7

                    blackLayer.add(animation, forKey: "basic")
                }else{

                    blackLayer.frame = CGRect(x: 0, y: -videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let animation = CABasicAnimation()
                    animation.keyPath = "position.y"
                    animation.fromValue = -videoTrack.naturalSize.height
                    animation.toValue =  2*videoTrack.naturalSize.height
                    animation.duration = 10
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    blackLayer.add(animation, forKey: "basic")
                }
            }else if(self.globalSelectedTransitionTag == 2){
                // #4. bottom->top

                blackLayer.frame = CGRect(x: 0, y: -videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor

                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)
                if(image%2 == 0 ){
                    let animation = CABasicAnimation()
                    animation.keyPath = "position"

                    animation.fromValue = [200, 200]
                    animation.toValue = [2200, 2200]
                    animation.duration = 5
                    print("CACurrentMediaTime()",CACurrentMediaTime())
                    animation.beginTime = CFTimeInterval(time[image]); //CACurrentMediaTime() + 5.0;
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    blackLayer.add(animation, forKey: "basic")

                }else{
                    let animation = CABasicAnimation()
                    animation.keyPath = "position.y"
                    animation.fromValue = 2 * videoTrack.naturalSize.height
                    animation.toValue = -videoTrack.naturalSize.height
                    animation.duration = 5
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    //   animation.speed = 0.7
                    blackLayer.add(animation, forKey: "basic")

                    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                    fadeOutAnimation.fromValue = 1
                    fadeOutAnimation.toValue = 0
                    fadeOutAnimation.duration = 10
                    fadeOutAnimation.beginTime = CACurrentMediaTime() + 0.3;
                    fadeOutAnimation.isRemovedOnCompletion = false
                    //fadeOutAnimation.speed = 0.7

                    blackLayer.add(fadeOutAnimation, forKey: "opacity")

                }



            }else if(self.globalSelectedTransitionTag == 3){

                ///#5. opacity(1->0)(left->right)///

                blackLayer.frame = CGRect(x: -videoTrack.naturalSize.width, y: 0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor

                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)

                let animation = CABasicAnimation()
                animation.keyPath = "position.x"
                animation.fromValue = -videoTrack.naturalSize.width
                animation.toValue = 2 * (videoTrack.naturalSize.width)
                animation.duration = 3
                animation.beginTime = CFTimeInterval(time[image])
                //  animation.speed = 0.7

                animation.fillMode = kCAFillModeForwards
                animation.isRemovedOnCompletion = false
                blackLayer.add(animation, forKey: "basic")

                let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                fadeOutAnimation.fromValue = 1
                fadeOutAnimation.toValue = 0
                fadeOutAnimation.duration = 5
                fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                fadeOutAnimation.isRemovedOnCompletion = false
                // fadeOutAnimation.speed = 0.7

                blackLayer.add(fadeOutAnimation, forKey: "opacity")
            }
            else if(self.globalSelectedTransitionTag == 4){
                blackLayer.frame = CGRect(x: 2 * videoTrack.naturalSize.width, y: 0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor

                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)

                let animation = CABasicAnimation()
                animation.keyPath = "position.x"
                animation.fromValue = 2 * videoTrack.naturalSize.width
                animation.toValue = -videoTrack.naturalSize.width
                animation.duration = 5
                animation.beginTime = CFTimeInterval(time[image])
                animation.fillMode = kCAFillModeForwards
                animation.isRemovedOnCompletion = false
                blackLayer.add(animation, forKey: "basic")

                let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                fadeOutAnimation.fromValue = 1
                fadeOutAnimation.toValue = 0
                fadeOutAnimation.duration = 15
                fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                fadeOutAnimation.isRemovedOnCompletion = false

                blackLayer.add(fadeOutAnimation, forKey: "opacity")
            }else if(self.globalSelectedTransitionTag == 5){
                ///#7. opacity(1->0)(top->bottom)///

                blackLayer.frame = CGRect(x: 0, y: 2 * videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor

                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)

                let animation = CABasicAnimation()
                animation.keyPath = "position.y"
                animation.fromValue = 2 * videoTrack.naturalSize.height
                animation.toValue = -videoTrack.naturalSize.height
                animation.duration = 3
                animation.beginTime = CFTimeInterval(time[image])
                animation.fillMode = kCAFillModeForwards
                animation.isRemovedOnCompletion = false
                //   animation.speed = 0.7
                blackLayer.add(animation, forKey: "basic")

                let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                fadeOutAnimation.fromValue = 1
                fadeOutAnimation.toValue = 0
                fadeOutAnimation.duration = 3
                fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                fadeOutAnimation.isRemovedOnCompletion = false
                //fadeOutAnimation.speed = 0.7

                blackLayer.add(fadeOutAnimation, forKey: "opacity")
            }
            else if(self.globalSelectedTransitionTag == 6){
                //#10. scale(big->small->big)///
                if(image == 0){
                    blackLayer.frame = CGRect(x: 0, y:0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
                    rotationAnimation.keyTimes = [0,1]
                    rotationAnimation.values = [0, M_PI]
                    rotationAnimation.duration = 5
                    rotationAnimation.beginTime = CFTimeInterval(time[image])
                    rotationAnimation.repeatCount = 1
                    blackLayer.add(rotationAnimation, forKey: nil)

                }


                else if(image == 1){
                    blackLayer.frame = CGRect(x: 0, y: -videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let animation = CABasicAnimation()
                    animation.keyPath = "position.y"
                    animation.fromValue = -videoTrack.naturalSize.height
                    animation.toValue = 2 * videoTrack.naturalSize.height
                    animation.duration = 3
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    blackLayer.add(animation, forKey: "basic")

                    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                    fadeOutAnimation.fromValue = 1
                    fadeOutAnimation.toValue = 0
                    fadeOutAnimation.duration = 3
                    fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                    fadeOutAnimation.isRemovedOnCompletion = false
                    blackLayer.add(fadeOutAnimation, forKey: "opacity")
                }else if(image == 2){
                    blackLayer.frame = CGRect(x: 0, y: 0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor
                    blackLayer.opacity = 0

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
                    scaleAnimation.values = [1, 0, 1]
                    scaleAnimation.beginTime = CFTimeInterval(time[image])
                    scaleAnimation.duration = 3
                    scaleAnimation.isRemovedOnCompletion = false
                    blackLayer.add(scaleAnimation, forKey: "transform.scale")

                    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                    fadeOutAnimation.fromValue = 1
                    fadeOutAnimation.toValue = 1
                    fadeOutAnimation.duration = 3
                    fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                    fadeOutAnimation.isRemovedOnCompletion = false
                    blackLayer.add(fadeOutAnimation, forKey: "opacity")
                }else if(image == 3){

                    blackLayer.frame = CGRect(x: 0, y: -videoTrack.naturalSize.height, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                    blackLayer.backgroundColor = UIColor.clear.cgColor

                    let imageLayer = CALayer()
                    imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                    imageLayer.contents = imgarray[image].cgImage
                    blackLayer.addSublayer(imageLayer)

                    let animation = CABasicAnimation()
                    animation.keyPath = "position.y"
                    animation.fromValue = -videoTrack.naturalSize.height
                    animation.toValue = 2 * videoTrack.naturalSize.height
                    animation.duration = 3
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.isRemovedOnCompletion = false
                    blackLayer.add(animation, forKey: "basic")

                    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
                    fadeOutAnimation.fromValue = 1
                    fadeOutAnimation.toValue = 0
                    fadeOutAnimation.duration = 3
                    fadeOutAnimation.beginTime = CFTimeInterval(time[image])
                    fadeOutAnimation.isRemovedOnCompletion = false
                    blackLayer.add(fadeOutAnimation, forKey: "opacity")
                }
            }                 else{


                blackLayer.frame = CGRect(x: 0, y: 0, width: videoTrack.naturalSize.width, height: videoTrack.naturalSize.height)
                blackLayer.backgroundColor = UIColor.clear.cgColor

                let imageLayer = CALayer()
                imageLayer.frame = CGRect(x: x, y: y, width: newSize.width, height: newSize.height)
                imageLayer.contents = imgarray[image].cgImage
                blackLayer.addSublayer(imageLayer)

                if(image%2 == 0 ){
                    let animation = CABasicAnimation(keyPath: "transform.scale.x")
                    animation.fromValue = 1
                    animation.toValue = 2
                    animation.duration = 5
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.repeatCount = 1
                    blackLayer.add(animation, forKey: nil)

                }else{
                    let animation = CABasicAnimation(keyPath: "opacity")
                    animation.fromValue = 0
                    animation.toValue = 1
                    animation.duration = 5
                    animation.beginTime = CFTimeInterval(time[image])
                    animation.fillMode = kCAFillModeForwards
                    animation.repeatCount = 1
                    blackLayer.add(animation, forKey: nil)

                }

            }



            parentlayer.addSublayer(blackLayer)
        }


         self.playVideoInPlayer(animatedVideoURL:self.globalVideoURL as URL, rowIndexPath: 0)


    }


func playVideoInPlayer(animatedVideoURL:URL,rowIndexPath:Int){

            let newPlayerItem = AVPlayerItem.init(url:animatedVideoURL )
            self.player = AVPlayer.init(playerItem:newPlayerItem)


                //let fileURL =
                player = AVPlayer(url: self.globalVideoURL as URL)
                player.actionAtItemEnd = .none

                let videoLayer = AVPlayerLayer(player: player)
                videoLayer.frame = view.bounds
                videoLayer.videoGravity = .resizeAspectFill
                videoContainerView.layer.addSublayer(videoLayer)

                let synchronizedLayer = AVSynchronizedLayer(playerItem: newPlayerItem)
                synchronizedLayer.frame = UIScreen.main.bounds
                synchronizedLayer.addSublayer(parentlayer)
                playerLayer.addSublayer(synchronizedLayer)
                videoContainerView.layer.addSublayer(parentlayer)

                player.play()

    }

После этого кода анимация также не добавляется в проигрыватель. Если кто-то попробовал это, просим вас просмотреть код и помочь мне двигаться дальше. Любое руководство или поддержка в этом направлении будут заметны. Заранее спасибо!

...