fading video over swift spritkit scene

后端 未结 1 1291
半阙折子戏
半阙折子戏 2021-01-24 03:24

I am porting a showroom application from as3/starling to a native swift iPad app.

I have 2 questions:

  1. How can I fade a video over my spritekit content (

1条回答
  •  说谎
    说谎 (楼主)
    2021-01-24 04:14

    My first answer answers your initial question, and this answer is tailored to the subsequent questions that were posted in the comments. I feel that both answers are useful to the community, instead of combining into just one which I think would be confusing.

    Here I implement a volume slider and a scrubbing slider that controls the VideoNode's AVPlayer object.. you get the full power of the AVPlayer but with the convenience of the SKVideoNode. Also, the volume for playing video is controlled without having to adjust the system volume and subsequent gray sound box pop-up:

    import SpriteKit
    import MediaPlayer
    
    
    class GameScene: SKScene {
    
      let seekSlider = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))
      let volSlider  = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))
    
      // Because it takes time for us to load the video, we don't know it's duration,
      // hence we don't know what the `.maximumValue` should be for the seekSlider
      let defaultMax = Float(0.123456789)
    
      var player: AVPlayer!
      var videoNode: SKVideoNode!
    
      func seekSliderChangedValue(sender: UISlider) {
        // Wait for file to finish loading so we can get accurate end duration:
          if sender.maximumValue == defaultMax {
          if CMTimeGetSeconds(player.currentItem!.duration).isNaN { return }
          else { sender.maximumValue = Float(CMTimeGetSeconds(player.currentItem!.duration)) }
        }
    
        let value = CMTimeMake(Int64(seekSlider.value), 1)
        player.seek(to: value)
        player.play()
      }
    
      func volSliderChangedValue(sender: UISlider) {
        player.volume = sender.value
      }
    
      override func didMove(to view: SKView) {
        removeAllChildren()  // Delete this in your actual project.
    
        // Add some labels:
        let seekLabel = SKLabelNode(text: "Seek")
        seekLabel.setScale(3)
        seekLabel.verticalAlignmentMode = .center
        seekLabel.position = CGPoint(x: frame.minX + seekLabel.frame.width/2,
                                     y: frame.maxY - seekLabel.frame.height)
        let volLabel  = SKLabelNode(text: "Volume")
        volLabel.setScale(3)
        volLabel.verticalAlignmentMode = .center
        volLabel.position = CGPoint(x: frame.minX + volLabel.frame.width/2,
                                    y: frame.minY + volLabel.frame.height + volSlider.frame.height)
    
        // Make player and node:
        let url = Bundle.main.url(forResource: "sample", withExtension: "mp4")!
        player = AVPlayer(url: url)
        videoNode = SKVideoNode(avPlayer: player!)
    
        //Configure seek slider:
        seekSlider.addTarget(self, action: #selector(seekSliderChangedValue), for: UIControlEvents.valueChanged)
        seekSlider.maximumValue = defaultMax
        let seekOrigin = convertPoint(toView: CGPoint(x: seekLabel.frame.minX, y: seekLabel.frame.minY))
        seekSlider.frame = CGRect(origin: seekOrigin, size: CGSize(width: 200, height: 15))
    
        //Configure vol slider:
        volSlider.addTarget(self, action: #selector(volSliderChangedValue), for: UIControlEvents.valueChanged)
        volSlider.value = 1
        let volOrigin = convertPoint(toView: CGPoint(x: volLabel.frame.minX, y: volLabel.frame.minY))
        volSlider.frame = CGRect(origin: volOrigin, size: CGSize(width: 200, height: 15))
    
        //Scene stuff:
        view.addSubview(seekSlider)
        view.addSubview(volSlider)
        addChild(seekLabel)
        addChild(volLabel)
        addChild(videoNode)
    
        // Start video and animation:
        videoNode.alpha = 0
        videoNode.play()
        videoNode.run(.fadeIn(withDuration: 5))
      }
    }
    

    0 讨论(0)
提交回复
热议问题