Swift UIKit, SwiftUI: AVPlayerViewController에서 재생중인 비디오의 강제 풀스크린 전환 및 반복 재생
Swift UIKit, SwiftUI: AVPlayerViewController에서 재생중인 비디오의 강제 풀스크린 전환 및 반복 재생
소개
AVPlayerViewController는 처음에 풀 스크린으로 바로 시작할 수 없는 옵션도 없고, 반복 재생 옵션도 없습니다. AVPlayerViewController에서 강제 풀스크린 전환 및 반복 재생하는 방법입니다.
포스트 하단에 SwiftUI를 위한 UIViewControllerRepresentable을 첨부합니다.
시작시 강제 풀스크린 전환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let controller = AVPlayerViewController()
let player = AVPlayer(url: url)
controller.player = player
let selectorToForceFullScreenMode = NSSelectorFromString("_transitionToFullScreenAnimated:interactive:completionHandler:")
player.play()
// 강제 풀스크린 전환
// asyncAfter는 전체화면에서 컨트롤 요소가 나오지 않을 떄에만 사용
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(10)) {
if controller.responds(to: selectorToForceFullScreenMode) {
controller.perform(selectorToForceFullScreenMode, with: true, with: nil)
}
}
// parentVC.present(...)로 AVPlayerViewController 나오게 하기
- 내부 메서드를 셀렉터 함수 형태로 추가합니다.
- 해당 셀렉터 함수를 강제적으로 실행시켜 컨트롤러가 나올 때 자동으로 풀스크린 모드가 되도록 합니다.
- 만약 풀스크린 모드에서 컨트롤 요소가 나오지 않는 경우
asyncAfter로 약간 늦게 실행되도록 합니다.
- 만약 풀스크린 모드에서 컨트롤 요소가 나오지 않는 경우
반복(Loop) 재생
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func loopVideo() {
NotificationCenter.default.removeObserver(self, name: AVPlayerItem.didPlayToEndTimeNotification, object: nil)
// Be sure to specify the object as the AVPlayer's player item if you have multiple players. https://stackoverflow.com/a/40396824
NotificationCenter.default.addObserver(forName: AVPlayerItem.didPlayToEndTimeNotification, object: self.player.currentItem, queue: .main) { _ in
player.seek(to: CMTime.zero)
player.play()
}
}
// ... //
player.play()
loopVideo()
// ... //
NotificationCenter를 이용해 비디오의 플레이가 끝나면 자동으로 시작점으로 되돌린 후 다시 재생되도록 합니다.
SwiftUI Representable 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//
// FullScreenVideoPlayer.swift
// study-WidgetExample
//
// Created by 윤범태 on 6/20/24.
//
import SwiftUI
import AVKit
struct FullScreenVideoPlayerRepresentedView: UIViewControllerRepresentable {
let url: URL
let player = AVPlayer()
func makeUIViewController(context: Context) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
player.replaceCurrentItem(with: .init(url: url))
let selectorToForceFullScreenMode = NSSelectorFromString("_transitionToFullScreenAnimated:interactive:completionHandler:")
player.play()
loopVideo()
// 강제 풀스크린 전환
// asyncAfter는 전체화면에서 컨트롤 요소가 나오지 않을 떄에만 사용
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(10)) {
if controller.responds(to: selectorToForceFullScreenMode) {
controller.perform(selectorToForceFullScreenMode, with: true, with: nil)
}
}
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
}
func loopVideo() {
NotificationCenter.default.removeObserver(self, name: AVPlayerItem.didPlayToEndTimeNotification, object: nil)
// Be sure to specify the object as the AVPlayer's player item if you have multiple players. https://stackoverflow.com/a/40396824
NotificationCenter.default.addObserver(forName: AVPlayerItem.didPlayToEndTimeNotification, object: self.player.currentItem, queue: .main) { _ in
player.seek(to: CMTime.zero)
player.play()
}
}
}
#Preview {
FullScreenVideoPlayerRepresentedView(url: URL(string: "https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_2mb.mp4")!)
}
출처
This post is licensed under
CC BY 4.0
by the author.