利用 AVPlayerLooper 重覆播放音樂和影片

彼得潘很喜歡重覆聽同一首歌,重覆看同一部電影,所以接下來,就讓我們用 iOS 10 的 AVPlayerLooper 實現重覆播放的功能吧。

只能聽一次的音樂

從前彼得潘想聽歌時,會找 AVPlayer 幫忙。(聽歌還要寫程式,真累 !) 比方以下範例分別為 SwiftUI & UIKit App 畫面出現時播放音樂的範例。

SwiftUI 版本

import SwiftUI
import AVFoundation

import AVFoundationstruct ContentView: View {

let player = AVPlayer()

var body: some View {
Text("Hello, World!")
.onAppear {
let fileUrl = Bundle.main.url(forResource: "music", withExtension: "mp4")!
let playerItem = AVPlayerItem(url: fileUrl)
self.player.replaceCurrentItem(with: playerItem)
self.player.play()
}
}
}

UIKit 版本

import UIKit
import AVFoundation

import AVFoundationclass ViewController: UIViewController {

let player = AVPlayer()

override func viewDidLoad() {
super.viewDidLoad()

let fileUrl = Bundle.main.url(forResource: "music", withExtension: "mp4")!
let playerItem = AVPlayerItem(url: fileUrl)
player.replaceCurrentItem(with: playerItem)
player.play()
}}
}

值得注意的,以上範例的 player 要在 body 或 viewDidLoad 之前宣告,如果在 body 或viewDidLoad 裡宣告 player, body & viewDidLoad { } 的程式跑完時,player 就會被清掉,造成音樂無法播放。

重覆播放音樂

可惜以上的程式播放的音樂只能聽一次,播完後就進入可怕的無聲世界。一旦沒有音樂,彼得潘是無法寫程式的,因此讓我們趕緊加入讓音樂單曲循環的 AVPlayerLooper 。

SwiftUI 版本

import SwiftUI
import AVFoundation

struct ContentView: View {
@State var looper: AVPlayerLooper?

var body: some View {

Text("Hello, World!")
.onAppear {
let player = AVQueuePlayer()
let fileUrl = Bundle.main.url(forResource: "music", withExtension: "mp4")!
let item = AVPlayerItem(url: fileUrl)
self.looper = AVPlayerLooper(player: player, templateItem: item)
player.play()
}
}
}

UIKit 版本

import AVFoundation
import UIKit

class ViewController: UIViewController {
var looper: AVPlayerLooper?
override func viewDidLoad() {
super.viewDidLoad()
if let url = URL(string: "https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview118/v4/69/0e/98/690e98db-440d-cb0c-2bff-91b00a05bdda/mzaf_1674062311671795807.plus.aac.p.m4a") {
let player = AVQueuePlayer()
let item = AVPlayerItem(url: url)
looper = AVPlayerLooper(player: player, templateItem: item)
player.play()
}
}
}

說明

在 body 或 viewDidLoad 之前宣告讓我們重覆播放音樂的 AVPlayerLooper,原因和在 body 或 viewDidLoad 之前宣告 player 的範例一樣。利用 AVPlayerLooper 重覆播放音樂時,重點在以下三行程式。

let player = AVQueuePlayer()
let item = AVPlayerItem(url: url)
looper = AVPlayerLooper(player: player, templateItem: item)

生成 AVQueuePlayer 物件。

let player = AVQueuePlayer()

利用 AVPlayerItem 生成要播放的音樂。

let item = AVPlayerItem(url: url)

生成 AVPlayerLooper,傳入剛剛生成的 player & item。到時候 AVPlayerLooper 將讓 item 重覆播放。

looper = AVPlayerLooper(player: player, templateItem: item)

在背景播放音樂

重覆播放影片

重覆播放影片的方法和音樂差不多,只是我們必須另外生成 AVPlayerViewController 顯示影片。

UIKit 版本

import AVKit
import UIKit

class ViewController: UIViewController {
var looper: AVPlayerLooper?
@IBAction func play(_ sender: Any) {
if let url = URL(string: "https://video-ssl.itunes.apple.com/apple-assets-us-std-000001/Video128/v4/ac/7c/62/ac7c6274-60ea-5b7c-4c99-f08d78bfe574/mzvf_484000410198456586.640x352.h264lc.U.p.m4v") {
let item = AVPlayerItem(url: url)
let player = AVQueuePlayer()
looper = AVPlayerLooper(player: player, templateItem: item)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
present(playerViewController, animated: true, completion: {
playerViewController.player?.play()
})
}
}
}

SwiftUI 版本

從 SwiftUI 顯示 AVPlayerViewController 比較麻煩,必須利用 UIViewControllerRepresentable 將 controller 的畫面包裝成 SwiftUI view,有興趣的朋友可參考以下連結的說明。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com