VisionPro开发 – 基础视频播放


首页:漫游Apple Vision Pro

Code Repo: github.com/xuchi16/vis…

Project Path: github.com/xuchi16/vis…


基本概念

在 visionOS 中,视频播放框架仍然沿用了此前的框架并在此基础上进行了增强。

  • AVFoundation:处理视频播放的底层工作
  • AVKit:在 AVFoundation 基础上,结合 UIKit、RealityKit 等,为每个平台创建定制化的播放体验

VisionPro开发 - 基础视频播放

通过 AVKit 中的AVPlayerViewController,可以实现基本的媒体播放的功能。配合视频播放过程中的观察者(Observer)、插播(Interstitial)等功能,还可以实现更为丰富的展示和交互效果。

基本实现

简单播放器

实现一个有最基本播放功能的播放器应用步骤如下:

  1. 导入框架:导入 AVFoundation 和 AVKit 框架,这两个框架分别提供了视频播放的核心功能和用户界面组件。
  2. 创建 AVPlayerViewController:用于视频播放的主要视图控制器。
  3. 设置 AVPlayer:创建一个 AVPlayer 实例,并将其连接到 AVPlayerViewController。AVPlayer 是用于播放媒体内容的核心类。
  4. 创建播放器项:使用内容的 URL 创建一个新的播放器项,并将其设置在播放器上。这一步可以提高性能,因为播放器会在开始加载媒体之前了解如何显示它。
  5. 在 SwiftUI 中使用 AVPlayerViewController,将其包装在一个 UIViewControllerRepresentable 类中。
import SwiftUI
import AVFoundation
import AVKit

struct SimplePlayerView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> AVPlayerViewController {
        let controller = AVPlayerViewController()
        controller.player = AVPlayer()
        controller.player?.replaceCurrentItem(with:AVPlayerItem(url: URL(string: "VIDEO_PATH")!))
        return controller
    }
    
    func updateUIViewController(_:AVPlayerViewController,context:Context){
    }
}
  1. 创建一个名为 VideoPlaybackApp 的 SwiftUI 应用,并添加刚才定义的 SimplePlayerView。
 @main
struct VideoPlaybackApp: App {
    var body: some Scene {
        WindowGroup {
            SimplePlayerView()
        }
    }
}

足球视频

在最基本的视频播放功能外,我们可能希望提供额外的功能,如

  • 在视频播放过程中触发特殊效果:如足球视频在进球后触发“GOAL”的庆祝字幕,或在沉浸场景中触发烟花效果等

  • 在播放轨道特定位置标记事件:如足球比赛进球时间点

在播放轨道特定位置标记事件

插播(Interstitial)原本是用来在视频播放过程中插入广告等内容的,但也会在相应的时间点在播放时间轴上添加一个标记点。所以考虑使用 Interstitial。

  • 新建一个AVPlayerInterstitialEventController,并传入此前的AVPlayer
  • 为需要播放的视频在需要标记的时点添加相应的插播事件
  • 将上述插播事件传递给 controller
let interstitialController = AVPlayerInterstitialEventController(primaryPlayer: player)
var interstitialEvents: [AVPlayerInterstitialEvent] = []
if let times = currentVideo?.getEventTimesVal() {
    for time in times {
        interstitialEvents.append(AVPlayerInterstitialEvent(primaryItem: item!, time: time))
    }
}
interstitialController.events = interstitialEvents

VisionPro开发 - 基础视频播放

视频播放过程中触发特殊效果

想要定义一个进球的滚动字幕效果,当进球时,会有一个“GOAL”横幅添出现在视频上方。

  1. 首先定义滚动字幕的视图GoalView,渐变色,从左往右滚动
  2. 通过 ornament 将字幕视图添加到视频上方
struct ContentView: View {
    
    @Environment(PlayerModel.self) private var playerModel
    
    @State private var isGoalPanelVisible = Visibility.hidden
    
    var match: MatchModel
    
    var body: some View {
        Spacer()
        Text(match.getTitle())
            .font(.title)
        
        PlayerView()
            .onAppear() {
                playerModel.load(match.video)
            }
            .onChange(of: playerModel.goal) { _, newValue in
                if newValue {
                    isGoalPanelVisible = .visible
                } else {
                    isGoalPanelVisible = .hidden
                }
            }
            .ornament(visibility: isGoalPanelVisible,
                      attachmentAnchor: .scene(.top),
                      contentAlignment: .bottom) {
                GoalView()
            }
            // ...
    }
}
  1. player上使用addBoundaryTimeObserver(forTimes:queue:using:),在视频播放到特定的时间点时调用特定的逻辑,控制字幕 ornament 是否可见。
token = player.addBoundaryTimeObserver(forTimes: times, queue: .main) {
    // Callback function
}

VisionPro开发 - 基础视频播放

由于 visionOS 拥有无边画布,因此除了在进球时才展示的字幕外,我们还可以添加更多的窗口展示比赛相关的信息,同时不会影响视频的播放,如阵容、比赛数据等信息。

VisionPro开发 - 基础视频播放

最终效果

VisionPro开发 - 基础视频播放

原文链接:https://juejin.cn/post/7319689232841719859 作者:xChester

(0)
上一篇 2024年1月4日 上午10:17
下一篇 2024年1月4日 上午10:28

相关推荐

发表回复

登录后才能评论