- AVPlayerとは
- 主な機能
- AVPlayerの基本的な使い方
- 応用的な使い方
- AVPlayerの主な特徴・メリット
- AVPlayer を使用する際の注意点
- まとめ
AVPlayerとは
AVPlayer は、iOS や macOS において 動画や音楽を再生 するためのフレームワークであるAVFoundation の主要なクラスの一つです。AVPlayer を使用すると、ローカルファイルやインターネット上のストリーミングコンテンツを簡単に再生できます。
AVPlayer は UIKit や SwiftUI で利用可能であり、特に 動画再生アプリ や 音楽プレイヤー の開発に適しています。
主な機能
- メディアの再生
- ローカルファイルやリモートURLからの動画・音声の再生
- シーク(特定の時間にジャンプ)
- 一時停止、再開、停止
- トリミングと時間管理
- 指定した開始時間(startTime)と終了時間(endTime)での再生
- 再生速度の調整
- ループ再生の実装
- バックグラウンド再生
- アプリがバックグラウンドに移行してもオーディオを継続再生
AVAudioSessionと組み合わせることで、他のアプリとの音の管理も可能
- 字幕と音声トラックの管理
- 外部字幕の追加・表示
- 音声トラックの選択
- HLS(HTTP Live Streaming)のサポート
- AppleのHTTPライブストリーミング技術に対応
- ネットワーク環境に応じた最適なビットレート選択
AVPlayerの基本的な使い方
以下は、AVPlayerを使用して動画を再生することが可能な最低限の実装になります。
import SwiftUI
import AVKit
struct VideoPlayerView: View {
private let player = AVPlayer(url: URL(string: "https://www.example.com/video.mp4")!)
var body: some View {
VideoPlayer(player: player)
.onAppear {
player.play()
}
.onDisappear {
player.pause()
}
}
}特定の時間にシークさせたい場合は、seek()をコールしてください。
let time = CMTime(seconds: 10, preferredTimescale: 600)
player.seek(to: time)再生速度の調整は、rateに値を設定してください。
player.rate = 1.5 // 1.5倍速で再生ループ再生させたい場合は、終了通知を受けてseek()で最初に戻ってplay()をコールすることでループ再生が可能となります。
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: .main) { _ in
player.seek(to: .zero)
player.play()
}応用的な使い方
バックグラウンドで音声を再生
Info.plist に “Background Modes” (UIBackgroundModes) を追加し、audio を有効にします。

上記設定後、play()コール前に以下の処理を実行します。
do {
let session = AVAudioSession.sharedInstance()
// setCategoryにて`.playback`を設定することでバックグラウンド再生可能
// mode、optionは任意。今回はmodeに.default、optionなし
try session.setCategory(.playback, mode: .default, options: [])
try session.setActive(true)
print("Audio session is set for background playback")
} catch {
print("Audio session setup failed: \(error)")
}
以下、バックグラウンド再生するための実装例です。
struct ContentView: View {
@State private var player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
var body: some View {
VideoPlayer(player: player)
.onAppear {
setupAudioSession() // ① AudioSession を設定
player.play() // ② バックグラウンド再生可能
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
try? AVAudioSession.sharedInstance().setActive(true)
}
}
}
// AudioSession を設定
func setupAudioSession() {
do {
let session = AVAudioSession.sharedInstance()
// setCategoryにて`.playback`を設定することでバックグラウンド再生可能
try session.setCategory(.playback, mode: .default, options: [])
try session.setActive(true)
print("Audio session is set for background playback")
} catch {
print("Audio session setup failed: \(error)")
}
}レイアウトをカスタマイズ
SwiftUI の Slider を使って、シークバーを手動で操作できる UI を作りました。
// AVPlayerのインスタンスを作成(指定したURLの動画をロード)
@State private var player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
@State private var currentTime: Double = 0 // 現在の再生時間(秒単位)
@State private var duration: Double = 1 // 動画の長さ(秒単位)
var body: some View {
VStack {
// 動画プレイヤーの表示
VideoPlayer(player: player)
.frame(height: 300)
// シークバー(スライダー)
Slider(value: $currentTime, in: 0...duration, onEditingChanged: { isDragging in
if !isDragging { // ドラッグが終わった時にシーク
let time = CMTime(seconds: currentTime, preferredTimescale: 600)
player.seek(to: time) // 指定した時間へジャンプ
}
})
.padding()
// コントロールボタン(巻き戻し、再生、停止、早送り)
HStack {
// 先頭へ戻る
Button(action: { player.seek(to: CMTime(seconds: 0, preferredTimescale: 600)) }) {
Image(systemName: "backward.fill")
.font(.title)
}
Spacer()
// 再生
Button(action: { player.play() }) {
Image(systemName: "play.fill")
.font(.title)
}
Spacer()
// 一時停止
Button(action: { player.pause() }) {
Image(systemName: "pause.fill")
.font(.title)
}
Spacer()
// 10秒進む
Button(action: {
let newTime = CMTime(seconds: currentTime + 10, preferredTimescale: 600)
player.seek(to: newTime)
}) {
Image(systemName: "forward.fill")
.font(.title)
}
}
.padding()
}
.onAppear {
setupPlayerObserver() // 動画の長さと現在の再生時間を監視
player.play() // 画面表示時に自動再生
}
}
// 動画の長さと現在の再生時間を監視
private func setupPlayerObserver() {
guard let duration = player.currentItem?.asset.duration.seconds, duration.isFinite else { return }
self.duration = duration // 動画の長さを取得
// 1秒ごとに再生時間を更新
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 600), queue: .main) { time in
self.currentTime = time.seconds
}
}AVPlayerの主な特徴・メリット
- シンプルなAPI設計
動画の再生やシークなどの操作が簡単に行えます。 - バックグラウンド再生に対応
適切な設定をすれば、アプリを閉じた状態でも音楽や動画を再生できます。 - カスタマイズ性が高い
AVPlayerLayer を使用することで、自由にレイアウトやアニメーションを追加できます。 - HLS(HTTP Live Streaming)のサポート
AppleのHTTPライブストリーミング技術に対応でき、ネットワーク環境に応じた最適なビットレートを選択することができます。
AVPlayer を使用する際の注意点
メインスレッドで UI の更新を行う
AVPlayer の状態変化を監視する際、UI の更新は必ず メインスレッド (DispatchQueueとかTask) で実装します。
// DispatchQueue使用の場合
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 600), queue: .main) { time in
DispatchQueue.main.async {
self.currentTime = time.seconds // UIを更新(メインスレッドで実行)
}
}
// Task使用の場合
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 600), queue: .main) { time in
Task { @MainActor in
self.currentTime = time.seconds // UIを更新(メインスレッドで実行)
}
}メモリ管理に注意
AVPlayerLooper を使うとメモリリークの原因になりやすいので、不要になったら invalidate() を呼んでください。
looper?.disableLooping()
looper = nilremoveTimeObserverでobserverを解放します。
合わせて、replaceCurrentItemにnilを設定することでPlayerItemを解放しましょう。
let observer = player.currentItem?.observe(\.status, options: [.new]) { item, _ in
if item.status == .failed {
print("動画の読み込みに失敗しました: \(String(describing: item.error))")
}
}
// observerとPlayerItem解放
player.removeTimeObserver(observer)
player.pause()
player.replaceCurrentItem(with: nil)まとめ
AVPlayerは、AVFoundationフレームワークの主要なクラスの一つであり、iOSアプリでの動画や音楽再生に最適なAPIです。
シンプルな API で操作しやすく、ストリーミングやカスタマイズ性にも優れています。
今回紹介した基本的な使い方を活用し、より高度なプレイヤー機能を実装してみましょう。
