В SwiftUI, как я могу добавить видео на l oop в качестве полноэкранного фонового изображения? - PullRequest
0 голосов
/ 27 января 2020

У меня есть видео продолжительностью около 10 секунд, которое я хотел бы воспроизвести на всех oop в качестве полноэкранного фонового изображения в одном из моих просмотров SwiftUI. Как я могу реализовать это?

Первая идея работала с import AVFoundation Swift, но не уверен, что это правильный путь.

Ответы [ 2 ]

1 голос
/ 28 января 2020

Вы можете использовать семейство фреймворков AV и UIViewRepresentable, чтобы сделать это:

import SwiftUI
import AVKit
import AVFoundation

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

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

Чтобы видео показывало l oop, я добавил наблюдателя и установил actionAtItemEnd до .none для поддержки зацикливания.

Когда видео подходит к концу, оно выполняет метод playerItemDidReachEnd(...), выполняет поиск в начале видео и продолжает зацикливание.

Примеры указывают на URL удаленного видео. Если вы хотите указать на файл в вашем приложении, вы можете использовать вместо этого Bundle.main.url:

if let fileURL = Bundle.main.url(forResource: "IMG_2770", withExtension: "MOV") {
    let player = AVPlayer(url: fileURL)
    // ...
}

class PlayerUIView: UIView {
    private let playerLayer = AVPlayerLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)

        let url = URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
        let player = AVPlayer(url: url)
        player.actionAtItemEnd = .none
        player.play()

        playerLayer.player = player
        playerLayer.videoGravity = .resizeAspectFill

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(playerItemDidReachEnd(notification:)),
                                               name: .AVPlayerItemDidPlayToEndTime,
                                               object: player.currentItem)

        layer.addSublayer(playerLayer)
    }

    @objc func playerItemDidReachEnd(notification: Notification) {
        if let playerItem = notification.object as? AVPlayerItem {
            playerItem.seek(to: .zero, completionHandler: nil)
        }
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer.frame = bounds
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                PlayerView()
                    .edgesIgnoringSafeArea(.all)
            }
        }
    }
}
0 голосов
/ 28 апреля 2020

SwiftUI

Как кто-то совершенно новый для Swift и для тех, кто не хочет часами отлаживать это, как я. Мой вариант использования пытался создать экран входа в систему с видео, играющим в фоновом режиме. Я боролся с неработающим циклом, а затем с остановкой видео через несколько секунд и возобновлением через некоторое время. Это работает для меня.

Добавить новый вид:

import SwiftUI
import AVKit
import AVFoundation

struct WelcomeVideo: View {
    var body: some View {
        WelcomeVideoController()
    }
}

struct WelcomeVideo_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeVideo()
    }
}

final class WelcomeVideoController : UIViewControllerRepresentable {
    var playerLooper: AVPlayerLooper?

    func makeUIViewController(context: UIViewControllerRepresentableContext<WelcomeVideoController>) ->
        AVPlayerViewController {
            let controller = AVPlayerViewController()

            guard let path = Bundle.main.path(forResource: "welcome", ofType:"mp4") else {
                debugPrint("welcome.mp4 not found")
                return controller
            }

            let asset = AVAsset(url: URL(fileURLWithPath: path))
            let playerItem = AVPlayerItem(asset: asset)
            let queuePlayer = AVQueuePlayer()
            // OR let queuePlayer = AVQueuePlayer(items: [playerItem]) to pass in items

            playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)
            queuePlayer.play()
            controller.player = queuePlayer

            return controller
        }

    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<WelcomeVideoController>) {
    }
}

Затем присоедините его к фону вида:

.background(WelcomeVideo())

ПРИМЕЧАНИЕ:

  1. Убедитесь, что ваше видео импортировано в ваш проект
  2. Обновите название видео до необходимого или немного измените рефакторинг, чтобы передать его в

Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...