How to Play, Record and Merge Videos in iOS and Swift

Learn the basics of working with videos on iOS with AV Foundation in this tutorial. You’ll play, record and even do some light video editing! By Owen L Brown.

4.3 (20) · 3 Reviews

Download materials
Save for later
Share
Update note: Owen Brown updated this tutorial to iOS 13 and Swift 5. Abdul Azeem wrote the original tutorial, and Joseph Neuman made fixes and clarifications.

Recording videos and playing around with them programmatically is one of the coolest things you can do with your phone. However, not nearly enough apps offer this ability, which you can easily add using the AV Foundation framework.

AV Foundation has been a part of macOS since OS X Lion (10.7) and iOS since iOS 4 in 2010. It’s grown considerably since then, with well over 100 classes to date.

This tutorial gets you started with AV Foundation by covering media playback and some light editing. In particular, you’ll learn how to:

  • Select and play a video from the media library.
  • Record and save a video to the media library.
  • Merge multiple clips into a single, combined video complete with a custom soundtrack.

Avoid running the code in this tutorial on the simulator because you’ll have no way to capture video. Plus, you’ll need to figure out a way to add videos to the media library manually. In other words, you really need to test this code on a device!

To do that, you’ll need to be a registered Apple developer. A free account will work just fine for this tutorial.

Ready? Lights, cameras, action!

Getting Started

Download the project materials by clicking the Download Materials button at the top or bottom of the tutorial.

Open the starter project and look around. This project contains a storyboard and several view controllers with the UI for a simple video playback and recording app.

The main screen contains the three buttons below, which segue to other view controllers:

  • Select and Play Video
  • Record and Save Video
  • Merge Video

Build and run and test the buttons. Only the three buttons in the initial scene do anything, but you’ll change that soon!

Main screen of the project

Selecting and Playing Video

The Select and Play Video button on the main screen segues to PlayVideoController. In this section of the tutorial, you’ll add the code to select a video file and play it.

Start by opening PlayVideoViewController.swift and add the following import statements at the top of the file:

import AVKit
import MobileCoreServices

Importing AVKit gives you access to AVPlayer, which plays the selected video. MobileCoreServices contains predefined constants such as kUTTypeMovie, which you’ll need later on.

Next, add the following class extensions at the end of the file. Make sure you add these to the very bottom of the file, outside the curly braces of the class declaration:

// MARK: - UIImagePickerControllerDelegate
extension PlayVideoViewController: UIImagePickerControllerDelegate {
}

// MARK: - UINavigationControllerDelegate
extension PlayVideoViewController: UINavigationControllerDelegate {
}

These extensions set up PlayVideoViewController to adopt the UIImagePickerControllerDelegate and UINavigationControllerDelegate protocols.

You’ll use the system-provided UIImagePickerController to let the user browse videos in the photo library. That class communicates back to your app through these delegate protocols. Although the class is named “image picker”, rest assured it works with videos too!

Next, head back to PlayVideoViewController‘s main class definition and add the following code to playVideo(_:):

VideoHelper.startMediaBrowser(delegate: self, sourceType: .savedPhotosAlbum)

This is a call to a helper method called startMediaBrowser(delegate:sourceType:) from VideoHelper. This call will open the image picker, setting the delegate to self. The source type of .savedPhotosAlbum opts to choose an image from the camera roll. Later, you’ll add helper tools of your own in VideoHelper.

To see what’s under the hood of this method, open VideoHelper.swift. It does the following:

  1. Checks if the source is available on the device. Sources include the camera roll, the camera itself and the full photo library. This check is essential whenever you use UIImagePickerController to pick media. If you don’t do it, you might try to pick media from a non-existent source, which will usually result in a crash.
  2. If the source you want is available, it creates a UIImagePickerController and sets its source and media type. Since you only want to select videos, the code restricts the type to kUTTypeMovie.
  3. Finally, it presents UIImagePickerController modally.

Now, you’re ready to give your project another whirl! Build and run. Tap Select and Play Video on the first screen, then tap Play Video on the second screen. The camera roll will pop up like this:

Screen where you can select a video to play

Once you see the list of videos, select one. You’ll proceed to another screen that shows the video in detail, along with buttons to Cancel, Play and Choose. Tap the Play button and, unsurprisingly, the video will play.

If you tap the Choose button, however, the app just returns to the Play Video screen! This is because you haven’t implemented any delegate methods to handle choosing a video from the picker.

Back in Xcode open PlayVideoViewController.swift again and find the UIImagePickerControllerDelegate extension. Then add the following delegate method implementation:

func imagePickerController(
  _ picker: UIImagePickerController,
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]
) {
  // 1
  guard
    let mediaType = info[UIImagePickerController.InfoKey.mediaType] as? String,
    mediaType == (kUTTypeMovie as String),
    let url = info[UIImagePickerController.InfoKey.mediaURL] as? URL
    else { return }
  
  // 2
  dismiss(animated: true) {
    //3
    let player = AVPlayer(url: url)
    let vcPlayer = AVPlayerViewController()
    vcPlayer.player = player
    self.present(vcPlayer, animated: true, completion: nil)
  }
}

Here’s what you’re doing in this method:

  1. You get the media type of the selected media and URL and ensure it’s a video.
  2. Next, you dismiss the image picker.
  3. In the completion block, you create an AVPlayerViewController to play the media.

Build and run. Tap Select and Play Video, then Play Video and choose a video from the list. The video will play in the media player.

The selected video playing in the media player

Recording Video

Now that you have video playback working, it’s time to record a video using the device’s camera and save it to the media library.

Open RecordVideoViewController.swift and add the following import:

import MobileCoreServices

Then, add the following to the end of the file:

// MARK: - UIImagePickerControllerDelegate
extension RecordVideoViewController: UIImagePickerControllerDelegate {
}

// MARK: - UINavigationControllerDelegate
extension RecordVideoViewController: UINavigationControllerDelegate {
}

This adopts the same protocols as PlayVideoViewController.

Next, add the following code to record(_:):

VideoHelper.startMediaBrowser(delegate: self, sourceType: .camera)

It uses the same helper method as in PlayVideoViewController, except that it accesses .camera to instruct the image picker to open in the built in camera mode.

Build and run to see what you have so far.

Go to the Record screen and tap Record Video. Instead of the Photo Gallery, the camera UI opens. When the alert dialog asks for camera permissions and microphone permissions, click OK.

Finally, start recording a video by tapping the red record button at the bottom of the screen; tap it again when you’re done recording.

The Record screen

Now, you have two options: use the recorded video or do a retake. Tap Use Video. You’ll notice that it just dismisses the view controller. That’s because — you guessed it — you haven’t implemented an appropriate delegate method to save the recorded video to the media library.