macOS 从 .mov 文件创建自定义屏幕保护程序
macOS create custom screen saver from .mov file
我正在尝试使用 .mov 文件创建自定义屏幕保护程序。
Xcode - 新项目 - 屏幕保护程序
下面是使用 Swift 的代码。问题是没有任何反应 - AV 播放器没有做任何事情。
import Foundation
import AVFoundation
import AVKit
import ScreenSaver
class MoonView: ScreenSaverView {
private var player: AVPlayer!
override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
guard let path = Bundle.main.path(forResource: "moon", ofType:"mov") else {
fatalError("moon.mov not found")
}
player = AVPlayer(url: URL(fileURLWithPath: path))
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect) {
let playerLayerAV = AVPlayerLayer(player: player)
playerLayerAV.frame = rect
player.play()
}
override func animateOneFrame() {
super.animateOneFrame()
setNeedsDisplay(bounds)
}
}
几天后就能正常工作了
import Foundation
import ScreenSaver
import AVKit
class MoonView: ScreenSaverView {
private var player: AVPlayer!
private var playerLayer: AVPlayerLayer!
override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
animationTimeInterval = 1.0/30.0
wantsLayer = true
player = createAVPlayer()
playerLayer = createAVPlayerLayer(player: player)
self.layer = playerLayer
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func startAnimation() {
super.startAnimation()
player.play()
}
override func stopAnimation() {
super.stopAnimation()
player.pause()
}
func createAVPlayer() -> AVPlayer {
let moonBundle: Bundle = Bundle(for: MoonView.self)
guard let url = moonBundle.url(forResource: "moon", withExtension: "mov") else {
fatalError("moon.mov not found in \(moonBundle.bundlePath)")
}
let avPlayer = AVPlayer(url: url)
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: nil)
return avPlayer
}
func createAVPlayerLayer(player: AVPlayer) -> AVPlayerLayer {
let avPlayerLayer: AVPlayerLayer = AVPlayerLayer(player: player)
avPlayerLayer.frame = bounds
avPlayerLayer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
avPlayerLayer.needsDisplayOnBoundsChange = true
avPlayerLayer.contentsGravity = .resizeAspect
avPlayerLayer.backgroundColor = CGColor(red: 0.00, green: 0.01, blue: 0.00, alpha:1.0)
return avPlayerLayer
}
// Notification Handling
@objc func playerItemDidReachEnd(notification: NSNotification) {
player.seek(to: CMTime.zero)
player.play()
}
// Remove Observer
deinit {
NotificationCenter.default.removeObserver(self)
}
}
我正在尝试使用 .mov 文件创建自定义屏幕保护程序。
Xcode - 新项目 - 屏幕保护程序
下面是使用 Swift 的代码。问题是没有任何反应 - AV 播放器没有做任何事情。
import Foundation
import AVFoundation
import AVKit
import ScreenSaver
class MoonView: ScreenSaverView {
private var player: AVPlayer!
override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
guard let path = Bundle.main.path(forResource: "moon", ofType:"mov") else {
fatalError("moon.mov not found")
}
player = AVPlayer(url: URL(fileURLWithPath: path))
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect) {
let playerLayerAV = AVPlayerLayer(player: player)
playerLayerAV.frame = rect
player.play()
}
override func animateOneFrame() {
super.animateOneFrame()
setNeedsDisplay(bounds)
}
}
几天后就能正常工作了
import Foundation
import ScreenSaver
import AVKit
class MoonView: ScreenSaverView {
private var player: AVPlayer!
private var playerLayer: AVPlayerLayer!
override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
animationTimeInterval = 1.0/30.0
wantsLayer = true
player = createAVPlayer()
playerLayer = createAVPlayerLayer(player: player)
self.layer = playerLayer
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func startAnimation() {
super.startAnimation()
player.play()
}
override func stopAnimation() {
super.stopAnimation()
player.pause()
}
func createAVPlayer() -> AVPlayer {
let moonBundle: Bundle = Bundle(for: MoonView.self)
guard let url = moonBundle.url(forResource: "moon", withExtension: "mov") else {
fatalError("moon.mov not found in \(moonBundle.bundlePath)")
}
let avPlayer = AVPlayer(url: url)
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: nil)
return avPlayer
}
func createAVPlayerLayer(player: AVPlayer) -> AVPlayerLayer {
let avPlayerLayer: AVPlayerLayer = AVPlayerLayer(player: player)
avPlayerLayer.frame = bounds
avPlayerLayer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
avPlayerLayer.needsDisplayOnBoundsChange = true
avPlayerLayer.contentsGravity = .resizeAspect
avPlayerLayer.backgroundColor = CGColor(red: 0.00, green: 0.01, blue: 0.00, alpha:1.0)
return avPlayerLayer
}
// Notification Handling
@objc func playerItemDidReachEnd(notification: NSNotification) {
player.seek(to: CMTime.zero)
player.play()
}
// Remove Observer
deinit {
NotificationCenter.default.removeObserver(self)
}
}