MBH
MBH

Reputation: 16619

iPhone splash screen as a short mp4 video swift ios

I am trying to make a short .mp4 video as a splash screen to show it when starting the app.

is there any example for that ?

Upvotes: 6

Views: 20022

Answers (4)

ZAY
ZAY

Reputation: 5015

In my App I have such a scenario. I'll post the individual steps here. As an information to the video (YourLogoVideo.mov): It should be stored in the root of the project, same location as i.Ex the Main.storyboard is located. And its format should be QuickTime in the .mov format.

Required Framework:

import AVKit

Define this in your GameViewController (no need to be static):

static var videoPlayer                  : AVPlayer!
static var videoView                    : AVPlayerViewController!

Here is the Setup Function - call it in viewDidLoad (at the very end of viewDidLoad):

func setupLogoVideoSequence() {
    
    // Logo Video
    let filePath    = Bundle.main.path(forResource: "YourLogoVideo", ofType: "mov") // Video duration 10.0 sec
    let fileURL     = URL.init(fileURLWithPath: filePath!)
    GameViewController.videoPlayer                                              = AVPlayer(url: fileURL) // Init Player
    GameViewController.videoView                                                = AVPlayerViewController() // Init View
    GameViewController.videoView.player                                         = GameViewController.videoPlayer
    GameViewController.videoView.player?.isMuted                                = false
    GameViewController.videoView.player?.volume                                 = 0.25
    GameViewController.videoView.player?.automaticallyWaitsToMinimizeStalling   = true
    GameViewController.videoView.player?.actionAtItemEnd                        = .none
    GameViewController.videoView.view.frame                                     = view.frame
    GameViewController.videoView.showsPlaybackControls                          = false
    GameViewController.videoView.videoGravity                                   = .resizeAspectFill

    // Add the VideoView to the View like so
    view.addSubview(GameViewController.videoView.view)
    
    // Schedule Cleanup of Video Stuff using observer
    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: GameViewController.videoPlayer.currentItem, queue: .main) { _ in self.deinitLogoVideo() }
    
}

Here is the Video deinit function:

func deinitLogoVideo() {
    
    guard isAppStartUp else { return }
    
    DispatchQueue.main.async {
        if GameViewController.videoView != nil {
            GameViewController.videoView.view.removeFromSuperview()
            GameViewController.videoView    = nil
            print("Logo Video deinitialized - videoView")
        }
        
        if GameViewController.videoPlayer != nil {
            GameViewController.videoPlayer.replaceCurrentItem(with: nil)
            GameViewController.videoPlayer  = nil
            print("Logo Video deinitialized - videoPlayer")
        }
    }
    
}

Here comes the moment to play the Video. Call it like from viewDidAppear:

DispatchQueue.main.async { GameViewController.videoView.player?.play() }

Make sure no other view covers the videoView!

Hope this will help someone.

Upvotes: 1

Fattie
Fattie

Reputation: 12648

The answer of @AnaLlera is so good that, here is the same answer with all modern syntax. (2023)

Simply use it on your first or main screen. Naturally, delay all processing in your app until the video is complete.

class SplashVidView: UIIView {
    
    var playerRef: AVPlayer?
    
    private lazy var pl: AVPlayerLayer = {
        
        //prevent background music woes courtesy @AnaLlera ...
        do {
            try AVAudioSession.sharedInstance().setCategory(.ambient)
        } catch { }
        
        let path = Bundle.main.path(forResource: "name", ofType: "mp4")!
        let plr = AVPlayer(url: URL(filePath: path))

        let playerLayer = AVPlayerLayer(player: plr)
        playerLayer.videoGravity = .resizeAspectFill
        playerLayer.zPosition = -1
        layer.addSublayer(playerLayer)
        
        plr.seek(to: CMTime.zero)
        plr.play()
        playerRef = plr
        return playerLayer
    }()
    
    override func layoutSubviews() {
        
        backgroundColor = .clear
        super.layoutSubviews()
        pl.frame = bounds
    }
}

Upvotes: 2

Ana Llera
Ana Llera

Reputation: 1916

You can create a custom ViewController for "Main Interface" and use it after the LaunchScreen with use AVPlayer inside. In swift will be something like this:

var player: AVPlayer?

override func viewDidLoad() {
    super.viewDidLoad()

    loadVideo()
}

private func loadVideo() {

    //this line is important to prevent background music stop
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
    } catch { }

    let path = NSBundle.mainBundle().pathForResource("your path", ofType:"mp4")

    player = AVPlayer(URL: NSURL(fileURLWithPath: path!))
    let playerLayer = AVPlayerLayer(player: player)

    playerLayer.frame = self.view.frame
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    playerLayer.zPosition = -1

    self.view.layer.addSublayer(playerLayer)

    player?.seekToTime(kCMTimeZero)
    player?.play()
}

Upvotes: 4

marchiore
marchiore

Reputation: 598

See the answer below by DarkDust in Emulating splash video in iOS application.

I Think one solution for you is show a Splash (IMG) and than you play the video you like.

To play videos in swift use AV Foundation https://developer.apple.com/av-foundation/

You cannot get rid of the static splash image. While it is shown, the OS is loading the application and instantiating stuff until it is ready to call your UIApplicationDelegate. So all you can do is either use no splash (black screen for a few seconds) or make your movie start exactly with the shown splash screen so it looks like the static image would suddenly animate.

To get rid of the black screen while the movie loads, you can try to make the player transparent and have an UIImageView behind the player that shows the splash image. The behavior would be this:

Splash screen is shown (static image). Application is loaded. You see the UIImageView, also showing the splash screen. On top of it is the transparent movie player. Movie player finally has loaded the move and starts playing it. At least in theory, this should cause the effect that the static image suddenly starts animating.

But if you don't use a splash screen at all (a lot of games do that), then it doesn't matter that the movie player is showing a black screen at first, you wouldn't notice.

Regarding showing the splash screen in an UIImageView: unfortunately, you have to test the interface rotation and load the image manually, there's no way to query which splash screen was shown. If you only support one interface orientation (again, a lot of games do this) you don't have this problem, of course.

Upvotes: 11

Related Questions