AVPlayerViewController là bộ điều khiển trình phát video tích hợp trong hệ sinh thái Apple, được thiết kế để phát nội dung đa phương tiện trên iOS và tvOS. Nó cung cấp giao diện toàn màn hình với các điều khiển, hỗ trợ phụ đề và AirPlay mà không cần viết giao diện người dùng tùy chỉnh. Theo Tài liệu Apple Developer, 2026, AVPlayerViewController tích hợp chỉ với vài dòng mã và hỗ trợ HLS, MP4 và hầu hết các định dạng đa phương tiện.
Các điểm chính
AVPlayerViewController là một thành phần của framework AVKit cung cấp giao diện có sẵn để phát video trong các ứng dụng Apple. Nó giải phóng nhà phát triển khỏi việc phải tạo trình phát tùy chỉnh từ đầu, cung cấp các điều khiển tiêu chuẩn: phát/tạm dừng, tua, điều chỉnh âm lượng và chế độ toàn màn hình.
Không giống như AVPlayerLayer cấp thấp, yêu cầu xây dựng giao diện người dùng thủ công, AVPlayerViewController quản lý hoàn toàn vòng đời của trình phát. Bộ điều khiển tự động xử lý xoay màn hình, thích ứng với Vùng an toàn trên iPhone có tai thỏ và hỗ trợ đa nhiệm trên iPad.
Theo Tài liệu Apple (2026), AVPlayerViewController tương thích với AVPlayer và AVQueuePlayer, cho phép phát cả tệp đơn lẻ và danh sách phát. Các URL từ bộ nhớ cục bộ, luồng mạng HLS và nội dung FairPlay được mã hóa đều được hỗ trợ.
Thành phần này xuất hiện trong iOS 8 cùng với AVKit để thay thế cho MPMoviePlayerController đã lỗi thời. Trong iOS 11, hỗ trợ Picture in Picture và hiển thị phụ đề đã được thêm vào. Trong iOS 14, bộ điều khiển đã nhận được thanh vận chuyển có thể tùy chỉnh thông qua AVPlayerViewControllerDelegate. Bắt đầu từ iOS 16, hỗ trợ thay thế tệp đa phương tiện động mà không cần tạo lại trình phát đã được giới thiệu.
AVPlayerViewController hiện đại được tối ưu hóa cho màn hình ProMotion — tốc độ khung hình video tự động đồng bộ hóa với tốc độ làm mới màn hình. Trên tvOS, thành phần này thích ứng với giao diện tiêu điểm của Siri Remote và trên macOS với chế độ cửa sổ của QuickTime Player.
Cốt lõi của bộ điều khiển là sự kết hợp giữa AVPlayer và AVPlayerItem. AVPlayer là đối tượng phát lại quản lý dòng thời gian, tốc độ và trạng thái. AVPlayerItem là một trình bao bọc xung quanh một tệp đa phương tiện cụ thể, chứa siêu dữ liệu, rãnh và thông tin tải.
Khi được khởi tạo, AVPlayerViewController nhận tham chiếu đến AVPlayer và tự động tạo AVPlayerLayer để hiển thị video. Bộ điều khiển đăng ký thông báo KVO của AVPlayer về các thay đổi trạng thái như readyToPlay, lỗi tải và kết thúc phát lại.
Các điều khiển (thanh vận chuyển) được hiển thị khi chạm vào màn hình. Trên iOS 15+, chúng hỗ trợ tùy chỉnh thông qua AVPlayerViewControllerCustomizationDelegate, cho phép ẩn hoặc thay thế các nút tiêu chuẩn.
Sau khi tạo bộ điều khiển và gán AVPlayer, phương thức viewDidLoad được gọi, bắt đầu chuẩn bị luồng video. Khi AVPlayerItem chuyển sang trạng thái AVPlayerItemStatusReadyToPlay, trình phát đã sẵn sàng hiển thị khung hình. Khi phương thức play() được gọi, quá trình giải mã luồng video bắt đầu thông qua Video Toolbox.
Khi rời khỏi màn hình, bộ điều khiển tự động tạm dừng phát lại và giải phóng tài nguyên bộ giải mã. Trên iOS 13+, để duy trì phát lại khi ứng dụng được thu nhỏ, cần cấu hình Chế độ nền và Phiên âm thanh. Theo WWDC 2024, nên sử dụng AVPlayerPlaybackCoordinator để đồng bộ hóa với trung tâm đa phương tiện iOS.
Thành phần này cung cấp một bộ tính năng phong phú có sẵn, làm cho nó trở nên hấp dẫn đối với hầu hết các dự án. Dưới đây là các khả năng chính không yêu cầu mã bổ sung.
Thanh vận chuyển là phần dưới cùng của giao diện chứa các nút điều khiển chính. Theo mặc định, thanh này ẩn sau 3 giây không hoạt động của người dùng và xuất hiện khi chạm. Trên iOS 16+, delegate có thể được sử dụng để kiểm soát khả năng hiển thị của từng phần tử.
Trong chế độ gỡ lỗi, thanh vận chuyển có thể được buộc hiển thị bằng cách sử dụng thuộc tính AVPlayerViewController.requiresLinearPlayback, thuộc tính này cũng ngăn video bị tạm dừng. Điều này hữu ích cho các quảng cáo xen giữa và nội dung giáo dục.
Tích hợp cơ bản của bộ điều khiển không mất quá 10 dòng mã. Đầu tiên, tạo một phiên bản AVPlayer với URL của tệp đa phương tiện, sau đó chuyển nó cho AVPlayerViewController và hiển thị bộ điều khiển trên màn hình.
import AVKit
let player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
player.play()
}
Sau khi gọi present, bộ điều khiển hiển thị toàn màn hình. Video bắt đầu tải từ mạng và khi bộ đệm đạt đến ngưỡng readyToPlay, quá trình phát lại tự động bắt đầu sau khi gọi play().
let asset = AVAsset(url: videoURL)
let item = AVPlayerItem(asset: asset)
let metadata = AVMutableMetadataItem()
metadata.key = AVMetadataKey.commonKeyTitle
metadata.value = "Video Của Tôi"
item.addMetadata(metadata)
let player = AVPlayer(playerItem: item)
let playerVC = AVPlayerViewController()
playerVC.player = player
Sử dụng AVPlayerItem cho phép bạn kiểm soát siêu dữ liệu, mã thời gian, lựa chọn rãnh âm thanh và phụ đề. Thông qua AVPlayerItem, bạn cũng có thể theo dõi tiến trình tải, bộ đệm và lỗi mạng bằng KVO trên thuộc tính status.
Bắt đầu từ iOS 11, nhà phát triển có thể tùy chỉnh thanh vận chuyển thông qua giao thức AVPlayerViewControllerDelegate. Phương thức playerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:) được gọi trước khi vào chế độ toàn màn hình và cho phép chuẩn bị giao diện người dùng.
Để ẩn các nút riêng lẻ, sử dụng thuộc tính AVPlayerViewController.showsPlaybackControls. Nếu đặt thành false, thanh vận chuyển biến mất hoàn toàn, chỉ còn lại luồng video. Hữu ích cho các phần tử lớp phủ tùy chỉnh.
class CustomPlayerViewController: UIViewController {
private let playerVC = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
playerVC.delegate = self
playerVC.showsPlaybackControls = true
playerVC.entersFullScreenWhenPlaybackBegins = true
}
}
extension CustomPlayerViewController: AVPlayerViewControllerDelegate {
func playerViewController(
_ playerViewController: AVPlayerViewController,
willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
) {
// Thêm nút lớp phủ
}
func playerViewController(
_ playerViewController: AVPlayerViewController,
didUpdate legibleMediaSelection: AVMediaSelectionGroup
) {
print("Đã chọn ngôn ngữ phụ đề mới")
}
}
Delegate cho phép chặn các sự kiện thay đổi phụ đề, vào và ra khỏi chế độ toàn màn hình, cũng như bắt đầu và kết thúc Picture in Picture. Tại WWDC 2024, Apple khuyến nghị sử dụng delegate để phân tích — ghi lại mỗi lần chuyển đổi trong vòng 100 ms.
AVPlayerViewController tự động hiển thị tất cả phụ đề và rãnh âm thanh có sẵn nếu chúng được nhúng trong tệp đa phương tiện hoặc được chỉ định trong tệp kê khai HLS. Người dùng có thể chuyển đổi chúng thông qua menu xuất hiện khi chạm vào biểu tượng phụ đề trong thanh vận chuyển.
Đối với luồng HLS, tệp kê khai M3U8 chứa danh sách các biến thể ngôn ngữ có sẵn. AVPlayer tải các đoạn phụ đề WebVTT tương ứng và chuyển chúng đến AVPlayerLayer để hiển thị. iOS 16+ đã giới thiệu hỗ trợ tạo kiểu phụ đề thông qua AVTextStyleRule.
func selectAudioTrack(languageCode: String) {
guard let group = player.currentItem?
.asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible)
else { return }
for option in group.options {
if option.extendedLanguageTag?.hasPrefix(languageCode) == true {
player.currentItem?.select(option, in: group)
}
}
}
Phương thức selectAudioTrack tìm kiếm trong số các tùy chọn âm thanh của nhóm audible biến thể có extendedLanguageTag khớp với mã ngôn ngữ mong muốn. Điều này cho phép triển khai tính năng “Âm thanh gốc” trong các ứng dụng có nội dung đa ngôn ngữ.
Chế độ Picture in Picture (PiP) cho phép hiển thị video trong cửa sổ nổi trên các ứng dụng khác. Trên iPad, tính năng này đã có sẵn từ iOS 9, trên iPhone từ iOS 14. AVPlayerViewController tự động thêm nút PiP vào thanh vận chuyển khi đăng ký UIBackgroundModes.
Để kích hoạt PiP, thêm khóa UIBackgroundModes với các giá trị audio và airplay vào Info.plist. Sau đó, nút PiP xuất hiện trong bộ điều khiển và khi chạm vào, video thu nhỏ thành cửa sổ nổi có kích thước 192x108 điểm.
Các sự kiện PiP được xử lý thông qua delegate: playerViewController(_:willStartPictureInPictureFromFullScreen:) và playerViewController(_:didStopPictureInPicture:). Theo Apple HIG, kích thước tối thiểu của cửa sổ PiP phải ít nhất là 120x68 điểm để duy trì khả năng đọc nội dung.
Câu hỏi thường gặp
Không, video YouTube yêu cầu sử dụng chế độ xem web WKWebView hoặc thư viện YouTube iOS Helper vì YouTube sử dụng hệ thống DRM riêng. AVPlayerViewController được thiết kế cho các luồng đa phương tiện trực tiếp qua URL.
Đặt thuộc tính showsPlaybackControls thành false. Sau đó, màn hình sẽ trống — chỉ còn luồng video. Để khôi phục các nút tùy chỉnh, thêm lớp phủ qua addSubview lên trên bộ điều khiển.
Có, bộ điều khiển hỗ trợ đầy đủ HLS Live. Thanh vận chuyển hiển thị chỉ báo Trực tiếp thay vì thanh trượt tiến trình. Độ trễ phụ thuộc vào cấu hình HLS — tối thiểu 6 giây với cài đặt độ trễ thấp.
Đăng ký KVO trên thuộc tính AVPlayerItem.status. Khi có lỗi, trạng thái chuyển thành .failed. Lấy chi tiết thông qua thuộc tính error của AVPlayerItem và hiển thị cảnh báo cho người dùng giải thích vấn đề — thường là sự cố mạng hoặc URL không hợp lệ.
Có, sử dụng AVAsset với AVAssetResourceLoader tùy chỉnh để cung cấp dữ liệu từ RAM. Triển khai AVAssetResourceLoaderDelegate và trả về byte từ bộ đệm thay vì đọc từ đĩa.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm