




영상을 넣을건데 유튜브에서 앞에 www.을 지우고 ss를 대신 써서 다운받는다.
swift로 동영상을 재생하는 소스를 작성해줘
레디언트
앗, 종133! 스위프트로 동영상 재생 소스가 필요하구나! ㅎㅎ 어렵지 않아~ 차근차근 알려줄게. iOS에서 동영상을 재생하려면 주로 AVKit과 AVFoundation 프레임워크를 사용해.
AVPlayer가 실제로 비디오를 재생하는 엔진이고, AVPlayerViewController는 그 비디오를 화면에 보여주는 UI 컨트롤러라고 생각하면 돼!
아래에 간단하게 비디오를 재생하는 예제 코드를 만들어 봤어. 이걸 너의 프로젝트에 그대로 복사해서 써도 되고, 필요한 부분만 바꿔서 사용해도 괜찮아!
swift
import UIKit // UI 관련 기능을 사용하기 위해 필요해.
import AVKit // 비디오 재생 UI를 제공하는 프레임워크야.
import AVFoundation // 비디오, 오디오 같은 미디어 데이터 작업을 할 때 쓰는 프레임워크!
// 이 ViewController는 비디오 재생 버튼 하나를 가지고 있고,
// 버튼을 누르면 전체 화면으로 비디오가 재생되는 예제야.
class VideoPlayerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white // 배경은 하얗게~
// 비디오 재생 버튼 만들기
let playButton = UIButton(type: .system)
playButton.setTitle("동영상 재생하기 ✨", for: .normal) // 버튼 제목
playButton.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: .bold) // 글씨는 좀 굵게!
playButton.addTarget(self, action: #selector(playVideoButtonTapped), for: .touchUpInside) // 버튼 눌리면 이 함수 실행!
playButton.translatesAutoresizingMaskIntoConstraints = false // 오토 레이아웃을 코드로 설정할 거라 이걸 false로 해줘야 해.
self.view.addSubview(playButton) // 화면에 버튼 추가!
// 버튼을 화면 정중앙에 배치하는 오토 레이아웃 설정
NSLayoutConstraint.activate([
playButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
playButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
// "동영상 재생하기" 버튼을 눌렀을 때 실행될 함수야.
@objc func playVideoButtonTapped() {
// 1. ⭐ 재생할 비디오의 URL을 가져와야 해! ⭐
// 여기서는 예시로 "sample_video.mp4"라는 이름의 비디오 파일이 앱 번들 안에 있다고 가정했어.
// 만약 인터넷에 있는 비디오(예: 유튜브 링크)를 재생하고 싶다면 아래처럼 하면 돼:
// let videoURL = URL(string: "https://devstreaming-cdn.apple.com/videos/wwdc/2019/501gb6s02z1a67x2l1b/501/501_full_keynote__wwdc19.mp4")
// 이런 식으로!
// 앱 번들 안에 있는 비디오 파일을 찾기!
guard let url = Bundle.main.url(forResource: "sample_video", withExtension: "mp4") else {
print("앗, 'sample_video.mp4' 파일을 찾을 수 없어 ㅠㅠ 프로젝트에 추가했는지 확인해봐!")
// 파일을 못 찾으면 사용자에게 오류 알림을 띄워주는 게 친절하겠지?
let alert = UIAlertController(title: "⚠️ 오류 발생", message: "재생할 비디오 파일을 찾을 수 없어요! 파일 이름이나 경로를 확인해주세요.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
return
}
// 2. AVPlayer 인스턴스를 만들고, 이 플레이어에 아까 찾은 비디오 URL을 연결해줘.
let player = AVPlayer(url: url)
// 3. AVPlayerViewController는 AVPlayer가 재생하는 비디오를 보여주는 UI 화면이야.
let playerViewController = AVPlayerViewController()
playerViewController.player = player // 플레이어를 이 컨트롤러에 연결!
// 4. 이제 비디오 플레이어 화면을 present(표시)하면 돼.
present(playerViewController, animated: true) {
player.play() // 화면이 뜨자마자 비디오 재생 시작!
}
}
}
⭐ 꼭 기억해야 할 것! ⭐
- 비디오 파일 추가: 위에 sample_video.mp4 파일을 사용한다고 되어있잖아? Xcode 프로젝트에 실제 MP4 파일을 추가해야 이 코드가 정상적으로 작동해!
- Xcode에서 프로젝트 내비게이터 (왼쪽 패널)를 열고, 프로젝트 이름(파란색 아이콘)을 클릭해.
- 타겟(Targets) 목록에서 너의 앱을 선택하고, "Build Phases" 탭으로 이동해.
- "Copy Bundle Resources" 섹션을 확장해서 + 버튼을 누르고, sample_video.mp4 파일을 추가해주면 돼.
- 만약 웹 URL에 있는 비디오를 재생한다면 이 과정은 필요 없어!
- 권한 설정 (선택 사항): 만약 사용자 갤러리나 다른 저장소에 있는 비디오를 가져와서 재생하고 싶다면, Info.plist 파일에 필요한 권한 (Privacy - Photo Library Usage Description 등)을 추가해줘야 해. 하지만 단순히 앱 번들 안의 비디오나 웹 URL 비디오를 재생하는 거면 별도 권한은 필요 없어!
내프로젝트에있는 동영상이름이 BMI.mp4파일이야 이 동영상을 재생하는 소스를 작성해줘
레디언트
아하, BMI.mp4 파일이구나! 좋아 좋아, 바로 수정해서 알려줄게. 걱정 마, 파일 이름만 바꿔주면 되니까 정말 간단해!
이전에 알려준 코드에서 비디오 파일 이름만 BMI.mp4로 딱 바꿔주면 돼. 아래 코드를 참고해 줘, 종133!
swift
import UIKit // UI 관련 기능을 사용하기 위해 필요해.
import AVKit // 비디오 재생 UI를 제공하는 프레임워크야.
import AVFoundation // 비디오, 오디오 같은 미디어 데이터 작업을 할 때 쓰는 프레임워크!
// 이 ViewController는 비디오 재생 버튼 하나를 가지고 있고,
// 버튼을 누르면 전체 화면으로 비디오가 재생되는 예제야.
class VideoPlayerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white // 배경은 하얗게~
// 비디오 재생 버튼 만들기
let playButton = UIButton(type: .system)
playButton.setTitle("BMI 동영상 재생하기 ✨", for: .normal) // 버튼 제목
playButton.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: .bold) // 글씨는 좀 굵게!
playButton.addTarget(self, action: #selector(playVideoButtonTapped), for: .touchUpInside) // 버튼 눌리면 이 함수 실행!
playButton.translatesAutoresizingMaskIntoConstraints = false // 오토 레이아웃을 코드로 설정할 거라 이걸 false로 해줘야 해.
self.view.addSubview(playButton) // 화면에 버튼 추가!
// 버튼을 화면 정중앙에 배치하는 오토 레이아웃 설정
NSLayoutConstraint.activate([
playButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
playButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
// "BMI 동영상 재생하기" 버튼을 눌렀을 때 실행될 함수야.
@objc func playVideoButtonTapped() {
// 1. ⭐ 재생할 비디오의 URL을 가져와야 해! ⭐
// 이번에는 네 프로젝트에 있는 "BMI.mp4" 파일을 찾아볼 거야!
guard let url = Bundle.main.url(forResource: "BMI", withExtension: "mp4") else {
print("앗, 'BMI.mp4' 파일을 찾을 수 없어 ㅠㅠ 프로젝트에 추가했는지 다시 한번 확인해봐!")
// 파일을 못 찾으면 사용자에게 오류 알림을 띄워주는 게 친절하겠지?
let alert = UIAlertController(title: "⚠️ 오류 발생", message: "재생할 'BMI.mp4' 파일을 찾을 수 없어요! 파일 이름이나 경로를 확인해주세요.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
return
}
// 2. AVPlayer 인스턴스를 만들고, 이 플레이어에 아까 찾은 비디오 URL을 연결해줘.
let player = AVPlayer(url: url)
// 3. AVPlayerViewController는 AVPlayer가 재생하는 비디오를 보여주는 UI 화면이야.
let playerViewController = AVPlayerViewController()
playerViewController.player = player // 플레이어를 이 컨트롤러에 연결!
// 4. 이제 비디오 플레이어 화면을 present(표시)하면 돼.
present(playerViewController, animated: true) {
player.play() // 화면이 뜨자마자 비디오 재생 시작!
}
}
}
⭐ 가장 중요한 거 다시 한번 강조! ⭐
- BMI.mp4 파일 추가: 이 코드가 잘 작동하려면 Xcode 프로젝트에 BMI.mp4 파일을 반드시 추가해야 해. 이 과정이 없으면 앱이 실행될 때 BMI.mp4 파일을 찾지 못해서 오류가 날 거야 ㅠㅠ
- Xcode에서 프로젝트 내비게이터 (왼쪽 패널)에서 프로젝트 이름(파란색 아이콘) 클릭!
- 타겟(Targets) 목록에서 너의 앱을 선택하고, "Build Phases" 탭으로 이동해.
- "Copy Bundle Resources" 섹션을 확장해서 + 버튼을 누르고, 너의 BMI.mp4 파일을 추가해주면 돼.


//
// VideoViewController.swift
// BMIA202208026
//
// Created by comsoft on 2025/11/18.
//
import UIKit
import AVKit// 비디오 재생 UI를 제공하는 프레임워크야.
import AVFoundation // 비디오, 오디오 같은 미디어 데이터 작업을 할 때 쓰는 프레임워크!
class VideoViewController: UIViewController {
@IBAction func playVideo(_ sender: UIButton) {
let videoPath = Bundle.main.path(forResource: "bmi", ofType: "mp4")
let videoURL = URL(filePath: videoPath!)
let player = AVPlayer(url: videoURL)
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true)
player.play()
}
override func viewDidLoad() {
super.viewDidLoad()
}
} 이소스를 한줄한줄 자세하게 설명해줘
레디언트
종133! 이 코드를 다시 한번 자세하게 설명해달라는 거지? ㅎㅎ 어쩐지 내 설명이 마음에 쏙 들었나? 기분 좋은걸! 😊
전에 아주 자세하게 설명해 줬지만, 혹시 더 헷갈리는 부분이 있었나 보네! 좋아! 그럼 이번에도 한 줄 한 줄 정성스럽게 다시 한번 설명해줄게. 잘 보고 또 잘 이해할 수 있을 거야! 걱정 마~ 같이 보자!
swift
//
// VideoViewController.swift
// BMIA202208026
//
// Created by comsoft on 2025/11/18.
//
- //: 이 기호 뒤에 나오는 내용은 주석이라고 해서, 코드를 읽는 사람에게 설명이나 메모를 남길 때 사용돼. 컴퓨터는 이 부분을 무시하고 지나가!
- VideoViewController.swift: 이 파일의 이름이 VideoViewController.swift라는 의미야. 스위프트(swift) 언어로 작성된 파일이지.
- BMIA202208026: 이 파일이 포함된 앱 프로젝트의 이름이야. 아마 종133의 BMI 앱 프로젝트인가 봐!
- Created by comsoft on 2025/11/18.: 이 코드를 누가(comsoft) 언제(2025년 11월 18일) 만들었는지 기록하는 부분이야.
swift
import UIKit // UI 관련 기능을 사용하기 위해 필요해.
import AVKit// 비디오 재생 UI를 제공하는 프레임워크야.
import AVFoundation // 비디오, 오디오 같은 미디어 데이터 작업을 할 때 쓰는 프레임워크!
- import: 이건 어떤 프레임워크 (특정 기능을 모아둔 라이브러리 같은 거야)를 내 코드에서 사용하겠다고 선언하는 부분이야.
- UIKit: 아이폰 앱의 화면을 만들고, 버튼이나 텍스트를 보여주고, 사용자의 터치 같은 것을 처리하는 가장 기본적인 기능을 제공해줘. 모든 iOS 앱 개발의 기본 중의 기본이라고 생각하면 돼!
- AVKit: Audio Video Kit의 줄임말인데, 비디오를 재생하는 **사용자 인터페이스(UI)**를 쉽게 만들어 주는 도구들을 제공해. 우리가 흔히 보는 재생/정지 버튼이나 진행바 같은 게 여기에 포함돼!
- AVFoundation: Audio Video Foundation이야. 이건 AVKit보다 더 깊이 들어가서, 실제로 비디오나 오디오 파일을 다루고, 재생하고, 편집하는 등의 핵심적인 미디어 처리 기능을 제공해.
swift
class VideoViewController: UIViewController {
- class VideoViewController: VideoViewController라는 이름의 클래스를 만드는 부분이야. 클래스는 특정 역할을 수행하는 객체를 만들기 위한 설계도라고 생각하면 돼. 이 VideoViewController는 비디오 재생 화면의 역할을 하게 될 거야.
- : UIViewController: VideoViewController가 UIViewController라는 또 다른 클래스의 기능을 상속받는다는 뜻이야. UIViewController는 iOS 앱에서 하나의 화면 전체를 관리하는 기본 기능을 가지고 있어. 이걸 상속받아야 우리 VideoViewController도 제대로 된 화면 역할을 할 수 있는 거지!
swift
@IBAction func playVideo(_ sender: UIButton) {
- @IBAction: 이건 스토리보드나 XIB 파일에서 버튼 같은 UI 요소와 코드 안에 있는 함수를 연결시켜주는 특별한 키워드야. 스토리보드에서 버튼을 눌렀을 때 특정 코드가 실행되도록 설정할 때 사용하지!
- func playVideo: playVideo라는 이름의 함수(특정 작업을 수행하는 코드 묶음)를 정의하는 부분이야. 이 함수 안의 코드들이 비디오를 재생하는 모든 과정을 담고 있어.
- (_ sender: UIButton): 이 함수가 호출될 때 sender라는 이름으로 UIButton 타입의 객체를 받는다는 뜻이야. 다시 말해, 어떤 버튼이 눌려서 이 함수가 실행되었는지 그 버튼 정보를 알려주는 매개변수라고 보면 돼!
swift
let videoPath = Bundle.main.path(forResource: "bmi", ofType: "mp4")
- let videoPath: videoPath라는 이름의 상수를 선언하고 있어. let은 한 번 값을 할당하면 그 값을 바꿀 수 없는 상수를 만들 때 사용해.
- Bundle.main: 우리 앱의 모든 파일(코드, 이미지, 사운드, 비디오 등)이 묶여 있는 곳을 번들이라고 하는데, Bundle.main은 그 중에서 앱이 실행될 때 사용되는 메인 번들을 의미해.
- .path(forResource: "bmi", ofType: "mp4"): Bundle.main에서 이름이 "bmi"이고 확장자가 "mp4"인 파일의 경로(예: 내 컴퓨터에서 파일이 어디에 있는지 알려주는 주소)를 찾아달라고 요청하는 거야. 이 명령이 성공하면 해당 파일의 전체 경로 문자열을 반환하고, 실패하면 아무것도 없는 nil을 반환해.
swift
let videoURL = URL(filePath: videoPath!)
- let videoURL: videoURL이라는 이름의 상수를 선언하고 있어. 이 상수는 비디오 파일의 인터넷 주소 또는 경로를 나타내는 URL 타입의 객체를 담을 거야.
- URL(filePath: videoPath!): videoPath로 찾은 문자열 경로를 URL이라는 형태로 만들어주는 부분이야. URL은 웹 주소(http://...)나 파일 경로(file://...) 같은 것들을 다룰 때 쓰는 객체거든.
- videoPath!: 여기에 붙은 !는 강제 언래핑이라는 건데, "야! 나는 videoPath가 절대 nil이 아니라는 걸 확실히 알아! 걱정 마!" 하고 컴파일러에게 알려주는 거야. 하지만 만약 bmi.mp4 파일이 앱에 없어서 videoPath가 정말로 nil이라면, 이 부분에서 앱이 갑자기 꺼져버릴 수도 있어. ㅠㅠ 그래서 실제 앱에서는 guard let이나 if let으로 안전하게 처리하는 습관을 들이는 게 좋아!
swift
let player = AVPlayer(url: videoURL)
- let player: player라는 상수를 만들고, 여기에 AVPlayer 객체를 저장할 거야.
- AVPlayer(url: videoURL): AVFoundation 프레임워크에 있는 AVPlayer라는 객체를 생성하는 부분이야. AVPlayer는 실제로 비디오를 재생하는 역할을 담당하는 핵심 객체야. videoURL을 넘겨줘서 어떤 비디오를 재생할 건지 알려주는 거지. 비디오를 틀어주는 엔진이라고 생각하면 딱 좋아!
swift
let playerController = AVPlayerViewController()
- let playerController: playerController라는 상수를 만들고, 여기에 AVPlayerViewController 객체를 저장할 거야.
- AVPlayerViewController(): AVKit 프레임워크에 있는 AVPlayerViewController라는 객체를 생성하는 부분이야. 이건 AVPlayer가 재생하는 비디오를 사용자에게 보여주는 화면(UI) 역할을 해. 재생/일시정지, 볼륨 조절, 전체 화면 보기 같은 편리한 컨트롤을 기본으로 제공해줘!
swift
playerController.player = player
- playerController.player = player: 방금 만든 AVPlayerViewController(playerController)에, 실제 비디오를 재생할 AVPlayer(player)를 연결해주는 부분이야. 이렇게 연결해야 playerController가 player를 통해 비디오 데이터를 받아 화면에 띄울 수 있어.
swift
present(playerController, animated: true)
- present(playerController, animated: true): 지금 화면(VideoViewController) 위에 playerController(비디오 재생 화면)를 새로운 화면으로 띄우는 명령어야. 마치 팝업창처럼 말이지.
- animated: true: 화면이 전환될 때 부드럽게 나타나는 애니메이션 효과를 줄 건지(true) 아니면 갑자기 짠 하고 나타나게 할 건지(false) 결정하는 거야.
swift
player.play()
- player.play(): AVPlayer 객체(player)에게 "이제 비디오를 재생해!" 하고 명령하는 부분이야. 이 코드가 실행되면서 playerController 화면에 비디오가 실제로 재생되기 시작할 거야.
swift
} // @IBAction func playVideo 함수 끝
override func viewDidLoad() {
super.viewDidLoad()
} // override func viewDidLoad 함수 끝
- override func viewDidLoad(): UIViewController가 가지고 있는 viewDidLoad()라는 특별한 함수를 다시 정의(재정의)하는 부분이야. 이 함수는 해당 화면(VideoViewController)이 처음으로 메모리에 로드되었을 때 딱 한 번 호출돼. 주로 화면의 초기 설정 같은 것들을 여기서 많이 해!
- super.viewDidLoad(): super는 부모 클래스인 UIViewController를 의미해. 부모 클래스의 viewDidLoad() 함수를 호출해서 부모가 해야 할 기본적인 초기화 작업을 먼저 수행하게 하는 아주 중요한 부분이야!
swift
} // class VideoViewController 끝
- 이 닫는 괄호(})는 VideoViewController 클래스 정의가 여기서 모두 끝났다는 것을 나타내!



1. if let (Conditional Binding)
- 어떤 역할?: "만약 값이 있다면(if let), 이 코드 블록 안에서만 그 값을 써!"
- 특징:
- 옵셔널 값이 있을 때만 중괄호 {} 안의 코드를 실행해.
- 언래핑된 값은 {} 블록 안에서만 사용할 수 있어.
- 값이 없어도 함수(function)는 계속 실행될 수 있어.
- 언제 사용하면 좋을까?:
- 어떤 값이 있으면 좋고 없어도 괜찮을 때, 즉 "이 값이 있다면 이걸 하고, 없으면 그냥 넘어가도 돼~" 하는 선택적인 처리를 할 때 좋아.
- 예를 들어, "사용자 프로필 이미지가 있다면 그걸 보여주고, 없으면 그냥 기본 이미지로 둬" 같은 상황에 적합해.
swift
func printNickname(userNickname: String?) {
if let nickname = userNickname {
print("사용자 닉네임은 \(nickname)이야!") // nickname은 여기서만 쓸 수 있어
}
// nickname이 nil 이어도 함수는 계속 진행돼.
print("환영합니다!")
}
2. guard let (Early Exit)
- 어떤 역할?: "이 값이 꼭 있어야만(guard let) 다음 코드를 진행할 수 있어! 없으면 여기서 함수 끝내!"
- 특징:
- 옵셔널 값이 없을 때 else 블록의 코드를 실행하고, 현재 실행 중인 함수나 루프를 바로 종료시켜 (return 또는 break, continue 등을 사용해야 해!).
- 언래핑된 값은 guard let 구문 아래부터 함수 끝까지 쭉 사용할 수 있어.
- 코드가 들여쓰기(indentation) 되는 걸 줄여줘서 더 읽기 좋게 만들어 줘. 이걸 "피라미드 오브 둠(Pyramid of Doom)"을 방지한다고도 해! 😉
- 언제 사용하면 좋을까?:
- 어떤 값이 필수적으로 존재해야만 다음 로직이 제대로 동작할 때! 즉, "이게 없으면 다음 단계로 진행하는 것 자체가 무의미해!" 할 때 좋아.
- 함수 시작 부분에서 유효성 검사(validation)를 할 때 많이 쓰여.
swift
func processOrder(orderId: String?) {
// orderId가 반드시 있어야만 주문 처리를 할 수 있어!
guard let id = orderId else {
print("앗, 주문 번호가 없어서 처리할 수 없어 ㅠㅠ")
return // 여기서 함수를 끝내버려!
}
// id는 guard let 아래부터 이 함수 끝까지 쭉 쓸 수 있어.
print("\(id)번 주문을 처리 중이야...")
// 다른 주문 처리 로직...
}
그럼 우리 VideoViewController 코드에서는 뭐가 더 좋을까?
종133의 playVideo 함수에서는 bmi.mp4 파일의 경로(videoPath)가 필수적으로 있어야만 동영상을 재생할 수 있어. 만약 videoPath가 없다면, AVPlayer도 못 만들고, AVPlayerViewController도 의미가 없잖아? 즉, videoPath가 없으면 더 이상 이 함수를 진행할 필요가 없는 상황이야.
이런 경우에는 guard let이 훨씬 더 좋은 선택이야! 👍
- 가독성(Readability): guard let은 "이 조건이 충족되어야만 다음으로 진행한다"는 의도를 명확히 보여줘. else { return } 패턴 덕분에 코드가 깔끔해지고, 필요한 조건을 미리 걸러내고 진행하니 메인 로직이 더 잘 보여.
- 흐름 제어(Flow Control): videoPath가 nil일 경우, else 블록을 실행하고 바로 함수를 return 시켜서 불필요한 후속 코드 실행을 막아줘. 앱이 엉뚱한 곳에서 오류나는 것을 방지할 수 있지!
- 값의 범위(Scope): guard let으로 언래핑한 videoPath는 guard let 아래부터 함수 끝까지 쭉 사용할 수 있으니, 코드 작성하기도 훨씬 편리해!
그래서 내가 전에 guard let으로 바꿔준 코드가 훨씬 더 안전하고, 읽기도 좋고, 유지보수하기도 좋은 코드가 되는 거야! 🥳
정리하자면,
- guard let: "필수 조건"을 확인하고, 아니면 바로 "퇴장!" (초기 검사, 유효성 검사에 👍)
- if let: "선택적인 조건"을 확인하고, 맞으면 "하고 싶은 일 하기!" (값이 있을 때만 특정 로직 수행에 ✨)

