이 튜토리얼에서는 반복해서 비디오 배경이 재생되는 iOS 스위프트에서 ViewController를 만드는 방법을 보여줄 것입니다.
목차
아래 예시는 도쿄의 밤 장면을 반복 재생하는 배경 비디오가 있는 간단한 메뉴를 보여줍니다:
장단점
먼저 이것을 왜 하고 싶은지 탐구해 보겠습니다. 하지만 코드로 바로 가고 싶다면, [여기]를 클릭하세요.
장점
미적 매력: 비디오 배경은 앱을 더 역동적이고 매력적으로 만들어 사용자의 시각적 경험을 향상시킬 수 있습니다.
브랜드 표현: 앱 내에서 브랜드 정체성을 전달하거나 특정 분위기를 조성하는 데 효과적인 방법이 될 수 있습니다.
사용자 참여: 잘 선택된 비디오는 사용자의 관심과 참여를 증가시켜, 잠재적으로 더 긴 세션 시간으로 이어질 수 있습니다.
스토리텔링: 비디오는 정지 이미지나 텍스트보다 더 몰입감 있게 이야기를 전달하거나 정보를 전달하는 데 사용될 수 있습니다.
맥락 정보: 경우에 따라 비디오 배경은 앱의 내용이나 기능과 관련된 유용한 맥락이나 정보를 제공할 수 있습니다.
단점
성능 영향: 비디오 재생은 리소스를 많이 사용할 수 있으며, 배터리 소모 증가 및 앱 성능 감소로 이어질 수 있습니다.
앱 크기 증가: 비디오 파일을 포함하면 앱의 크기가 크게 증가할 수 있으며, 저장 공간이 제한된 사용자에게 문제가 될 수 있습니다.
산만함: 주의 깊게 사용하지 않으면 비디오 배경은 사용자에게 산만할 수 있으며, 중요한 내용이나 기능에 집중하기 어렵게 만들 수 있습니다.
데이터 사용: 비디오가 인터넷에서 스트리밍되거나 다운로드될 경우 상당한 양의 데이터를 사용할 수 있으며, 데이터 요금제가 제한된 사용자에게 이상적이지 않을 수 있습니다.
접근성 문제: 특히 깜박거리거나 빠르게 움직이는 요소가 있는 비디오는 특정 장애나 민감성이 있는 사용자에게 문제가 될 수 있습니다.
로딩 시간: 비디오를 통합하면 특히 모바일 사용에 최적화되지 않은 비디오의 경우 뷰 컨트롤러의 로딩 시간이 증가할 수 있습니다.
모범 사례
성능 및 로딩 문제를 최소화하기 위해 비디오가 모바일 기기에 적절하게 최적화되어 있는지 확인합니다.
간단한 인터페이스를 선호하거나 배터리/데이터를 절약해야 하는 사용자를 위해 비디오 배경을 비활성화하는 옵션을 제공하는 것을 고려합니다.
비디오 콘텐츠를 사용할 수 없는 사용자를 위한 대체 콘텐츠를 제공하는 등 접근성 지침을 준수하는 것이 중요합니다.
비디오 콘텐츠를 앱의 목적과 관련 있게 유지하고 사용자 경험을 향상시키는 것이 중요합니다.
요약하자면, 비디오 배경은 시각적으로 눈에 띄고 매력적일 수 있지만, 성능, 접근성 및 사용자 경험과 관련된 잠재적 단점과 이점을 균형 있게 고려하는 것이 중요합니다.
단계별 비디오뷰컨트롤러
1. 필요한 프레임워크 가져오기
import UIKit
import AVKit
import AVFoundation
필요한 프레임워크를 가져오기 시작합니다:
UIKit: 이것은 iOS 인터페이스를 구축하기 위한 기본 프레임워크입니다.
AVKit 및 AVFoundation: 이들은 비디오 재생에 필수적인 오디오-비주얼 미디어를 처리하는 데 사용됩니다.
2. 비디오뷰컨트롤러 클래스 정의
class VideoViewController: UIViewController {
var videoName: String
여기서 UIViewController에서 상속받는 새로운 클래스 VideoViewController를 정의합니다. 또한 비디오 파일의 이름을 저장할 변수 videoName을 선언합니다.
3. 비디오 재생을 위한 속성 정의
fileprivate var queuePlayer: AVQueuePlayer?
fileprivate var playerLayer: AVPlayerLayer?
fileprivate var playbackLooper: AVPlayerLooper?
queuePlayer: 재생 큐를 관리하기 위한 AVQueuePlayer 객체.
playerLayer: 뷰의 레이어에 비디오 콘텐츠를 표시하는 AVPlayerLayer.
playbackLooper: 비디오의 원활한 루핑을 용이하게 하는 AVPlayerLooper.
4. 컨트롤러 초기화
init(videoName: String) {
self.videoName = videoName
super.init(nibName: nil, bundle: nil)
}
이 초기화 함수는 videoName 속성을 설정하고 상위 클래스의 초기화 함수를 호출합니다. 올바른 파일을 재생하기 위해 비디오 이름이 필요하기 때문에 이 사용자 지정 init이 필요합니다.
5. viewDidLoad 오버라이드
override func viewDidLoad() {
super.viewDidLoad()
playBackgroundVideo()
}
viewDidLoad 메소드에서 playBackgroundVideo()를 호출합니다. 이 메소드는 뷰 컨트롤러의 뷰가 메모리에 로드될 때 실행됩니다.
6. 비디오 파일 찾기
guard let path = Bundle.main.path(forResource: videoName, ofType: "mp4") else {
return
}
여기서 앱 번들에서 비디오 파일의 경로를 찾으려고 합니다. 만약 그것이 존재하지 않으면, 함수는 일찍 반환합니다.
7. 플레이어 설정
let playerItem = AVPlayerItem(url: URL(fileURLWithPath: path))
self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
비디오 URL을 가진 AVPlayerItem을 생성한 다음, 그것으로 queuePlayer와 playerLayer를 초기화합니다.
8. 루핑 및 레이어 구성
guard let playerLayer = self.playerLayer else { return }
guard let queuePlayer = self.queuePlayer else { return }
self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
playerLayer.videoGravity = .resizeAspectFill
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
비디오를 루핑하기 위해 playbackLooper를 구성합니다.
videoGravity를 resizeAspectFill로 설정하여 비디오가 종횡비를 유지하지 않고 전체 뷰 영역을 커버하도록 합니다.
playerLayer의 프레임을 뷰의 경계에 맞게 설정합니다.
playerLayer를 뷰의 레이어의 하위 레이어로 추가합니다.
9. 비디오 재생 시작
queuePlayer.play()
마지막으로, 비디오를 재생합니다.
이 코드는 무한히 반복되는 전체 화면 비디오 배경이 있는 뷰 컨트롤러를 생성합니다. 비디오 파일은 앱 번들에 포함되어야 하며 VideoViewController 인스턴스를 생성할 때 그 이름으로 지정되어야 합니다.
VideoViewController:
import UIKit
import AVKit
import AVFoundation
class VideoViewController: UIViewController {
var videoName: String
fileprivate var queuePlayer: AVQueuePlayer?
fileprivate var playerLayer: AVPlayerLayer?
fileprivate var playbackLooper: AVPlayerLooper?
init(videoName: String) {
self.videoName = videoName
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
playBackgroundVideo()
}
func playBackgroundVideo() {
guard let path = Bundle.main.path(forResource: videoName, ofType: "mp4") else {
return
}
let playerItem = AVPlayerItem(url: URL(fileURLWithPath: path))
self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
guard let playerLayer = self.playerLayer else { return }
guard let queuePlayer = self.queuePlayer else { return }
self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
playerLayer.videoGravity = .resizeAspectFill
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
queuePlayer.play()
}
}
예시 사용, 메뉴뷰컨트롤러:
import UIKit
class MenuViewController: VideoViewController {
init() {
super.init(videoName: "MenuVideo")
}
required init?(coder: NSCoder) {
super.init(videoName: "MenuVideo")
}
override func viewDidLoad() {
super.viewDidLoad()
setUpButtons()
}
fileprivate func setUpButtons() {
let playGameButton = UIButton()
playGameButton.translatesAutoresizingMaskIntoConstraints = false
playGameButton.setTitle("Play Game", for: .normal)
playGameButton.setTitleColor(.black, for: .normal)
playGameButton.backgroundColor = .white
playGameButton.addTarget(self, action: #selector(playGameButtonTapped), for: .touchUpInside)
self.view.addSubview(playGameButton)
let optionsButton = UIButton()
optionsButton.translatesAutoresizingMaskIntoConstraints = false
optionsButton.setTitle("Options", for: .normal)
optionsButton.setTitleColor(.black, for: .normal)
optionsButton.backgroundColor = .white
optionsButton.addTarget(self, action: #selector(optionsButtonTapped), for: .touchUpInside)
self.view.addSubview(optionsButton)
NSLayoutConstraint.activate([
playGameButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
playGameButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -30),
playGameButton.widthAnchor.constraint(equalToConstant: 200),
playGameButton.heightAnchor.constraint(equalToConstant: 50),
optionsButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
optionsButton.topAnchor.constraint(equalTo: playGameButton.bottomAnchor, constant: 20),
optionsButton.widthAnchor.constraint(equalToConstant: 200),
optionsButton.heightAnchor.constraint(equalToConstant: 50)
])
}
@objc func playGameButtonTapped() {
print("Play Game button pressed")
}
@objc func optionsButtonTapped() {
print("Options button pressed")
}
}