31

The goal is to playback video file (*.mp4) inside a UIView without controls.

It will serve as a background/wallpaper on the ViewController and other controls, i.e. tableview, text fields, images will be shown over the view with video playedback.

What is the better way to do this? Thank you

Bogdan Laukhin
  • 1,454
  • 2
  • 17
  • 26
  • Is it Local Video or You Tube Video using URL? – Vidhyanand Feb 05 '16 at 14:41
  • it will be local file imported into the project. Actually there will be several files (videos) each for separate ViewController – Bogdan Laukhin Feb 05 '16 at 14:55
  • Refer http://stackoverflow.com/questions/17922017/display-video-inside-the-uiwebview-not-in-device-full-screen – Vidhyanand Feb 05 '16 at 15:04
  • As fas as I see `MPMoviePlayerController` is deprecated in iOS 9. The `AVPlayerViewController` class should be used instead. Question remains: how to display video in frame uiview without controls (not in webview)? – Bogdan Laukhin Feb 05 '16 at 17:13
  • Swift, shorter answers: [solution 1](https://stackoverflow.com/a/37354688/452436) [solution 2](https://stackoverflow.com/a/45070690/452436) – Mike Lee Feb 23 '18 at 11:08

2 Answers2

52

I've reached the goal with the native AVPlayer

1.Used AVFoundation:

#import <AVFoundation/AVFoundation.h>

2.Used property for player:

@property (nonatomic) AVPlayer *avPlayer;

3.Added video file into "Video" folder and added "Video" into project

4.Initialized the player

NSString *filepath = [[NSBundle mainBundle] pathForResource:@"shutterstock_v885172.mp4" ofType:nil inDirectory:@"Video"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
self.avPlayer = [AVPlayer playerWithURL:fileURL];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;

AVPlayerLayer *videoLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
videoLayer.frame = self.view.bounds;
videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:videoLayer];

[self.avPlayer play];

5.Subscribed for event - video did play to the end

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.avPlayer currentItem]]; 

6.Resumed video playing from the very start in related method

- (void)itemDidFinishPlaying:(NSNotification *)notification {
    AVPlayerItem *player = [notification object];
    [player seekToTime:kCMTimeZero];
}
Bogdan Laukhin
  • 1,454
  • 2
  • 17
  • 26
  • There is a gap of milliseconds when video starts playing again. How to fix that? – Shanu Singh Jan 13 '20 at 07:05
  • @ShanuSingh I'm not sure ho to do that. It might be that the seekToTime:kCMTimeZero takes some time to carry out. You might try to prepare video with similar frame at the very start and very end if this helps. – Bogdan Laukhin Jan 13 '20 at 19:07
  • @ShanuSingh have you find any solution for gap of milliseconds when video starts playing again. – Yogendra Patel May 15 '20 at 05:44
  • @YogendraPatel, No luck, I used gif instead of .mp4 but there is still a very minor repeated view. – Shanu Singh May 15 '20 at 05:52
  • Guys, there is a better way: player = AVQueuePlayer() playerItem = AVPlayerItem(url: url) playerLooper = AVPlayerLooper(player: player!, templateItem: playerItem!) – kakaiikaka Dec 23 '22 at 11:30
17

Swift

In Swift it is similar. Add the video to your resource bundle. My fuller answer is here.

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var player: AVPlayer?

    @IBOutlet weak var videoViewContainer: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        initializeVideoPlayerWithVideo()
    }

    func initializeVideoPlayerWithVideo() {

        // get the path string for the video from assets
        let videoString:String? = Bundle.main.path(forResource: "SampleVideo_360x240_1mb", ofType: "mp4")
        guard let unwrappedVideoPath = videoString else {return}

        // convert the path string to a url
        let videoUrl = URL(fileURLWithPath: unwrappedVideoPath)

        // initialize the video player with the url
        self.player = AVPlayer(url: videoUrl)

        // create a video layer for the player
        let layer: AVPlayerLayer = AVPlayerLayer(player: player)

        // make the layer the same size as the container view
        layer.frame = videoViewContainer.bounds

        // make the video fill the layer as much as possible while keeping its aspect size
        layer.videoGravity = AVLayerVideoGravity.resizeAspectFill

        // add the layer to the container view
        videoViewContainer.layer.addSublayer(layer)
    }

    @IBAction func playVideoButtonTapped(_ sender: UIButton) {
        // play the video if the player is initialized
        player?.play()
    }
}
Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393