简体   繁体   中英

iOS swift , video output not centering inside the UIView

So I got this video playing inside a sublayer of the view , but the video keeps popping underneath the UIView not inside of it any solution ?

import UIKit
import AVKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController {

    var player : AVPlayer? = nil
    var playerLayer : AVPlayerLayer? = nil
    var asset : AVAsset? = nil
    var playerItem: AVPlayerItem? = nil

    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let videoURLWithPath = "http://selevision9890-i.akamaihd.net/hls/live/219323/98906/1.m3u8"
        let videoURL = NSURL(string: videoURLWithPath)
        asset = AVAsset(URL: videoURL!) as AVAsset
        playerItem = AVPlayerItem(asset: asset!)
        videoView.frame = self.view.frame
        player = AVPlayer(playerItem: self.playerItem!)
        playerLayer = AVPlayerLayer(player: self.player)
        playerLayer!.frame = videoView.frame
        videoView.layer.addSublayer(self.playerLayer!)

        player!.play()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

normal view:

截屏

(from here: http://prnt.sc/e33dhf )

rotated view:

截屏

(from here: http://prnt.sc/e33djs )

Move this code into viewDidAppear or viewWillAppear - in viewDidLoad the frames are not correct yet. The view is resized to fit the screen size after viewDidLoad .

i had to ditch avplayer and use avplayerviewcontroller and it worked fine thank you all

import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController {

    let avPlayerViewController = AVPlayerViewController()
    var avPlayer:AVPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let movieUrl:NSURL? = NSURL( string :"http://selevision9890-i.akamaihd.net/hls/live/219323/98906/1.m3u8")

        if let url = movieUrl{
            self.avPlayer = AVPlayer(URL : url )
            self.avPlayerViewController.player = self.avPlayer
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func play(sender: AnyObject) {
        self.presentViewController(self.avPlayerViewController, animated: true) { 
            self.avPlayerViewController.player?.play()
        }
    }
}

My solution is to have your view like a canvas and basically draw the AVPlayerViewController on top of it:

@IBOutlet weak var layerVideoView: UIImageView!
guard let url = Bundle.main.path(forResource: "santana", ofType: "mp4") else { return debugPrint("video not found") }
let path = URL(fileURLWithPath: url)

let player = AVPlayer(url: path)
let playerController = AVPlayerViewController()
playerController.player = player
playerController.view.frame = CGRect(x: layerVideoView.frame.origin.x, y: layerVideoView.frame.origin.y, width: layerVideoView.frame.width, height: layerVideoView.frame.height)
self.addChild(playerController)
self.view.addSubview(playerController.view)

LayerVideoView is an image view, but you can use just a UIView if that suits. Its is important to add constraints in the Storyboard to your View because your Video Player will mimic the shape of your View.

Set PlayerLayer videogravity

let videoURLWithPath = "http://selevision9890-i.akamaihd.net/hls/live/219323/98906/1.m3u8"
let videoURL = NSURL(string: videoURLWithPath)
playerItem = AVPlayerItem(url: videoURL! as URL)
player = AVPlayer(playerItem: self.playerItem!)
playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame =  videoView.frame
playerLayer.backgroundColor = UIColor.black.cgColor
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
videoView.layer.addSublayer(self.playerLayer!)
player!.play()

I had similiar problem. I went with subclassing UIView like this:

import UIKit

class VideoPlayerView: UIView {
var playerLayer: CALayer?

override func layoutSublayersOfLayer(layer: CALayer) {
    super.layoutSublayersOfLayer(layer)
    playerLayer?.frame = self.bounds
  }
}

and use it for setting up a video like this:

@IBOutlet weak var videoPlayer: VideoPlayerView!

func setupVideoOnView() {
    var player = AVPlayer(URL: mediaURL! as NSURL)
    let playerLayer = AVPlayerLayer(player: player)

    playerLayer.frame = self.videoPlayer.bounds
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    self.videoPlayer.layer.addSublayer(playerLayer)
    self.videoPlayer.playerLayer = playerLayer

}

That did a trick with wrong frame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM