AVPlayer를 사용하면 로컬 MP3, MP4, HTTP 라이브 스트리밍 및 HTTP URL에서 비디오를 재생할 수 있습니다. 현재 재생 중인 동영상을 교체하려면 replaceCurrentItem(with:) 함수를 사용하세요. 단, 재생 시 1개의 영상만 재생 가능합니다.
여러 비디오를 추가한 경우 AVQueuePlayer를 통해 AVPlayerItems를 관리할 수 있습니다. 대기열의 속성을 가지므로 AVPlayerItem 비디오에 대해 삽입 및 제거와 같은 작업이 가능합니다.
AVPlayerViewController로 사용 가능. 화면을 변경하여 플레이어를 통해 동영상을 실행할 수 있지만 ContainerView(UIView와 같은 유형)를 선언하고 내부에 AVPlayer 및 AVPlayerLayer를 설정하여 여러 UIView가 있는 동영상을 한 화면에 표시할 수도 있습니다.
AVPlayer 및 AVPlayerLayer를 통해 비디오를 실행하는 것은 정말 쉽습니다.
var movieContainer: UIView!
var playerLayer: AVPlayerLayer!
정말 짧은 CALayer 설명
AVPlayer는 NSObject입니다. UIView가 아니기 때문에 view.addSubview를 추가할 수 없습니다. 따라서 온스크린 비디오 재생 레이아웃은 AVPlayerLayer에서 관리합니다. AVPlayerLayer는 CALayer의 하위 클래스이며 CALayer는 핵심 애니메이션 프레임워크입니다. UIView에도 CALayer가 있으며 그리기 및 애니메이션 관련 작업은 Core Animation에 위임됩니다. UIView는 CALayer를 둘러싼 래퍼입니다. 각 UIView에는 루트 CALayer가 있으며 여러 하위 계층을 포함할 수 있습니다….
요.. CALayer로 UIView의 하위 레이어에 추가하여 화면에 표시할 수 있다는 사실.
func makePlayer(urlString: String, completion: @escaping(Bool)->Void) {
guard let hasUrl = URL(string: urlString) else {
completion(false)
return
}
let asset = AVAsset(url: hasUrl)
let item = AVPlayerItem(asset: asset)
playerLayer = AVPlayerLayer(player: AVPlayer(playerItem: item))
setupPlayerLayers(playerLayer)
completion(true)
}
그리고 AVPlayer를 생성하는 기능을 설정합니다.
URL은 미디어 전용 모델인 AVAsset에서 관리합니다. QuickTime 영화, MP3 및 HTTP 라이브 스트리밍을 처리합니다. AVPlayer를 통해 하나 이상의 미디어 자산을 재생할 수 있습니다. 위에서 언급했지만 ReplaceCurrentItem(with:) 다른 미디어 콘텐츠를 재생할 수 있지만 한 번에 하나의 미디어 콘텐츠만 재생할 수 있습니다.
AVAsset은 동영상 재생과 관련된 모델은 아니지만 재생 기간 및 생성 날짜에 대한 정보를 담고 있습니다. 자산을 재생하려면 AVPlayerItem 인스턴스를 동적으로 생성해야 합니다. 이 객체는 타이밍, 게임의 프레젠테이션 상태 등을 확인하기 위한 모델입니다. (AVPlayer가 재생하는 자산의 상태와 관련됨)
AVPlayer의 상태는 계속 동적으로 변경됩니다. 따라서 AVPlayer 상태를 보는 방법에는 두 가지가 있습니다. (나중에… 우리는 이것으로 돌아올 것입니다.)
AVPlayerLayer는 사용자 지정 인터페이스를 만드는 데 사용됩니다. 위에서 아주 쉽게 언급했듯이 AVAsset -> AVPlayerItem을 통해 생성된 playerItem은 NSOBjcet인 AVPlayer에 추가될 수 있습니다. UIView가 아닌 보기에는 아무 것도 추가할 수 없습니다. 그러나 AVPlayerLayer를 통해 레이어 계층을 지정하여 추가할 수 있습니다. 작은 단점은 재생 컨트롤이 표시되지 않는다는 것입니다. (추가해야 합니다.) 자신이 속한 Container UIView의 특정 영역에만 비주얼 콘텐츠를 출력합니다.
func setupPlayerLayers(_ target: AVPlayerLayer) {
movieContainer.layer.addSublayer(target)
target.videoGravity = .resizeAspectFill
movieContainer.layer.shadowOffset = CGSize(width: 0, height: 10)
movieContainer.layer.shadowColor = UIColor.black.cgColor
movieContainer.layer.shadowOpacity = 0.23
}
내 코드에서 AVPlayerLayer의 컨테이너 보기는 movieContainer 변수입니다.
이 변수의 레이아웃을 설정하고 AVPlayerLayer를 movieContainer 수준의 하위 수준으로 추가합니다. 그리고
AVPlayerLayer의 VideoGravity를 지정해야 합니다.
1. AVLayerVideoGravity.resizeAspectFill
// 컨테이너에 맞게 확장합니다. (퇴마)
2. AVLayerVideoGravity.resizeAspect
// 기본값 == 원본
3. AVLayerVideoGravity.resize
AVPlayer의 동영상이 표시되지 않습니다.
var url: String! {
didSet {
makePlayer(urlString: url) {
guard $0 else {
print("url가 잘못됬거나 player 초기화가 잘못됨.")
// 동영상이 안 보여질 때 초록초록하게 해봄
self.movieContainer.backgroundColor = .systemGreen
return
}
self.playerLayer?.frame = self.movieContainer.bounds // x
self.playerLayer.player?.play()
}
}
}
URL을 얻은 후 movieContainer에서 비디오를 재생했습니다. 하지만 movieContainer의 배경만 보이고 영상의 오디오만 들리는 문제가 있었습니다. 볼 수 있었던 적도 있습니다. 그 원인은 playerLayer의 경계가 바뀔 수 있기 때문입니다.
이 경우 viewDldLayoutSubviews()를 재정의하여 모든 UIView 레이아웃 관련 메서드가 호출된 후(레이아웃이 결정된 후) 주어진 보기의 크기, 수준 등을 최종적으로 조정하는 데 사용됩니다. 이 기능을 통해 ViewController는 추가 레이아웃 변경을 알릴 수 있습니다.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
playerLayer?.frame = movieContainer.bounds
}