利用 SwiftUI 在 iOS 15 建立一個重複播放的影片背景


本篇原文(標題:How to Create a Looping Video Background in SwiftUI for iOS 15)刊登於作者 Medium,由 Mirhat Rama 所著,並授權翻譯及轉載。

在撰寫本文時,我們還沒有一種直接的方法,可以在 SwiftUI 製作影片背景 (video background) 或影片播放器 (video player)。幸好,Apple 有提供 AVKit 和 AVFoundation,我們還是可以利用一個比較麻煩的方法來達到這個目的。

看完這篇教學後,你會得到以下的結果:

swiftui-looping-video-background-demo
影片來源:Anna Shvets – Pexels

讓我們開始吧!

首先,打開你的專案,或是創建一個新的專案。為你的專案命名,並選擇 SwiftUI 為界面 (interface)。另外,我們還要指定一個以 com.<herecomesyourtext> 開頭的 Organization Identifier。

new-project

然後,你可以建立一個新的 Swift 檔案,或是打開一個現在的 Swift 檔案。在這個範例中,我們會使用以下這個已經設置好的  ContentView.swift 檔案。

import SwiftUI
struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

我們需要 import AVKitAVFoundation,來設置和播放影片。我們可以在基本的 import SwiftUI 下直接 import:

set-up

設置好之後,讓我們建立 UIViewRepresentable 型別的 PlayerView

struct PlayerView: UIViewRepresentable {
    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
    }

    func makeUIView(context: Context) -> UIView {
        return LoopingPlayerUIView(frame: .zero)
    }
}

複製上面的程式碼到你的 ContentView 結構。

現在我們已經設置好 PlayerView,接下來,我們要做的就是用影片「填滿」這個視圖,並重複播放!

PlayerView 結構下,讓我們創建 UIView 型別的 LoopingPlayerUIView 類型。以下是類別的完整程式碼:

class LoopingPlayerUIView: UIView {
    private let playerLayer = AVPlayerLayer()
    private var playerLooper: AVPlayerLooper?
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        // Load the resource -> h
        let fileUrl = Bundle.main.url(forResource: "NAME OF VIDEO", withExtension: "TYPE OF VIDEO")!
        let asset = AVAsset(url: fileUrl)
        let item = AVPlayerItem(asset: asset)
        // Setup the player
        let player = AVQueuePlayer()
        playerLayer.player = player
        playerLayer.videoGravity = .resizeAspectFill
        layer.addSublayer(playerLayer)
        // Create a new player looper with the queue player and template item
        playerLooper = AVPlayerLooper(player: player, templateItem: item)
        // Start the movie
        player.play()
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}

在尋找及添加影片和影片的型別前,讓我們先把 PlayerView 添加到 ContentView 吧!

在 ContentView 中,刪走 Text(“Hello World”),並添加以下程式碼:

GeometryReader{ geo in
    PlayerView()
        .aspectRatio(contentMode: .fill)
        .frame(width: geo.size.width, height: geo.size.height+100)
        .edgesIgnoringSafeArea(.all)
        .overlay(Color.black.opacity(0.2))
        .blur(radius: 1)
        .edgesIgnoringSafeArea(.all)
}

在上面的程式碼中,我們添加了一個 GeometryReader,讓設定可以適用於不同裝置,並填滿螢幕。我們也為影片添加了一個 overlay 和模糊效果 (blur),讓使用者可以分辨影片和影片上的其他內容。

如你所見,我們在這裡用了 .edgesIgnoreSafeArea(.all) 修飾符 (modifier)。如果我們不用這個修飾符,影片的四邊就會留有 safe area。這樣可能是你想要的效果,但在這個範例中,我們想影片覆蓋整個螢幕。不過,你可以隨意試試 PlayerView() 的修飾符。

接下來,我們需要找一段影片作背景。在這個範例中,我在 Pexels 尋找縱向拍攝的視頻,選擇了這一段碰紅酒杯的影片來用於 App 內!

下載影片,然後拖放到我們的專案內,並設定 Add to targets:

adding-video

留意影片的名稱和型別:

name-and-extension-of-video

回到類別中尋找 fileUrl,然後把 forResource 改成影片的名稱,withExtension 就改為影片的型別。以我們的範例來說,程式碼應該會是這樣:

<strong>let</strong> fileUrl = Bundle.main.url(forResource: "demoVideo", withExtension: "mp4")!

現在讓我們預覽內容,就可以看到我們的影片在播放,而且會自動重播!

如果你填錯了 fileUrl,預覽就可能會出錯。如果是這樣,可以檢查影片的名稱和型別有沒有填錯,也要留意 Apple 是否支援影片的型別。

swiftui-looping-video-background-demo
Tadaa! We have a looping video background!!

完成了!最後,我們可以把播放器添加到 ZStack 內。如此一來,就可以在播放器上加入其他內容:

struct ContentView: View {
    var body: some View {

        GeometryReader{ geo in
            ZStack {
                PlayerView()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: geo.size.width, height: geo.size.height+100)
                    .overlay(Color.black.opacity(0.2))
                    .blur(radius: 1)
                    .edgesIgnoringSafeArea(.all)

                VStack{
                    Text("Hello World")
                        .font(.title)
                        .foregroundColor(.white)
                    Spacer()
                }
            }
        }

    }
}

結果:

final-result

恭喜你完成了這篇教學!希望你可以利用新知識來建構更好的東西!

你可以在 GitHub 下載完整程式碼和專案。

本篇原文(標題:How to Create a Looping Video Background in SwiftUI for iOS 15)刊登於作者 Medium,由 Mirhat Rama 所著,並授權翻譯及轉載。

作者簡介:Mirhat Rama,白天是顧問,晚上是程式設計師,現在開始在寫作領域發展,主要寫關於科技和編程的題目。同時,也是一個為兒子感到驕傲的爸爸。

譯者簡介:Kelly Chan-AppCoda 編輯小姐。


此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。

blog comments powered by Disqus
Shares
Share This