Search code examples
iosswiftvideoavfoundationavplayerlayer

Playback Video in iOS inside a custom view


I am trying to build a simple app that allows me to record a video and then watch it. I am using two views, AVCamPreviewView on the left side of the screen (which displays a live video stream from the iPhone's camera) and AVPlayerLayerView on the right side of the screen (which is supposed to display the video once I have recorded and saved it to the app's document folder).

While the first part (displaying the livestream) works like a charm (I used Apple's AVCam-tutorial for reference), the latter does not: I can start the playback of the video that I have recorded: The Audio starts playing, but I cannot see anything, and I have no clue why that is.

Here is my AVPlayerLayerView-class:

//
//  AVPlayerLayerView.swift
//  AVCamSwift
//

import UIKit
import AVFoundation

class AVPlayerLayerView: UIView {
    var player: AVPlayer = AVPlayer()
    var avPlayerLayer: AVPlayerLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        print("AVPlayerLayerView -> init with frame")

        inits()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        print("AVPlayerLayerView -> init with coder")

        inits()
    }

    private func inits() {
        let rootLayer: CALayer = self.layer
        rootLayer.masksToBounds = true

        avPlayerLayer = AVPlayerLayer(player: player)
        rootLayer.insertSublayer(avPlayerLayer, atIndex: 0)
    }

    func setContentUrl(url: NSURL) {
        print("Setting up item: \(url)")
        let item = AVPlayerItem(URL: url)
        player.replaceCurrentItemWithPlayerItem(item)
    }

    func play() {
        if (player.currentItem != nil) {
            print("Starting playback!")
            player.play()
        }
    }

    func pause() {
        player.pause()
    }

    func rewind() {
        player.seekToTime(CMTime(seconds: 0, preferredTimescale: 1))
    }

    func stop() {
        pause()
        rewind()
    }
}

The video-playback should start when the corresponding button is tapped, and here is the code that starts the playback:

@IBAction func playVideoTap(sender: AnyObject) {
    if let rfp = recordingFilePath {
        playbackView.setContentUrl(rfp)
        playbackView.play()
    }
}

As mentioned before: Audio-Playback works, but I cannot see anything, thus I assume I have to reposition the AVPlayerLayer in my AVPlayerLayerView-Class or something like that. Any ideas?

And here's a snippet of the layout, just in case it helps... Layout

EDIT:

Thanks to Rajesh's response I am finally able to playback the video. However, the recorded video is not displayed inside the right, grey area of the screen, but instead inside a tiny square in the top-middle of the screen (see screenshot). Any ideas how to fix that? Also, aspect ratio is not the same as in the "recording view"...

Wrong location of AVPlayerLayer


Solution

  • You forgot setting bounds for the avplayer layer.

    private func inits() {
    
            //let rootLayer: CALayer = self.layer
           // rootLayer.masksToBounds = true
    
            avPlayerLayer = AVPlayerLayer(player: player)
            avPlayerLayer.bounds = self.bounds
           // avPlayerLayer.backgroundColor = UIColor.yellowColor().CGColor
            self.layer.insertSublayer(avPlayerLayer, atIndex: 0)
        }