質問:windowDidLoad()
に挿入すると、このコードが機能しないのはなぜですか?
loadMovieWithURL(whichView: AVPlayerView1,
url: URL(fileURLWithPath: "/Users/joeblogs/Desktop/my.mp4"))
しかし、ダイアログピッカーを使用して同じパスで同じファイルを開くことができます(その後、呼び出された場合、ワンライナーは機能します)? URL または AVPlayerView について何か不足していますか? NSWindowController の目に見えないキャッシング? たぶん、私が見ることができないコーディングエラーですか?
設計:デフォルトでは、 を押すと、テキスト フィールドloadButton
から AVPlayerView を読み込もうとします。hardCodedPath
デフォルトの (ただし編集可能な) パス文字列 (例: /Users/joeblogs/Desktop/my.mp4) は、IB でハードコーディングされています。チェックボックスがオフの場合、useHardCodedFlag
代わりにファイル ピッカー ダイアログが使用されます。
テスト:
起動後、がオンのときにを
loadButton
押すと、URL を作成するために使用されます - を参照してください。デフォルトの URL パスが適切であることを確認しますが、AVPlayerView にはムービーの代わりにプレースホルダー (スラッシュ付きのムービー再生アイコン) が表示されるだけです。useHardCodedFlag
hardCodedPath
loadMovies()
useHardCodedFlag
次に、ファイル ピッカー ダイアログで同じファイルを無効にしてから選択すると、ムービーが完全に開き、選択した URL のパスが元のハードコードされたパスと同じであるとアプリが報告します。その時点で
useHardCodedFlag
、テキスト フィールドから AVPlayerView を有効にして読み込みます。元のウィンドウが既に閉じていても、新しいウィンドウでも正しく動作するようになりました。別の有効なパスをピッカーで最初に開くまで、別の有効なパスを貼り付けても失敗します (同じウィンドウまたは新規)。hardCodedPath
異なるムービーを持つ 2 つのウィンドウから始めて、コンテンツを交換することでムービーを交換し、各ウィンドウを有効にして
hardCodedPath
ヒットすることができます(少なくともウィンドウ レベルでは) キャッシュはありません。loadButton
useHardCodedFlag
概要:パス文字列から構築された URL を使用して AVPlayerView にムービーを読み込むことができますが、モーダル ダイアログ ピッカーからの URL を使用して (アプリケーションの起動後) 最初に開いた場合に限ります。なんで?
コアの ~ ダース行はfunc loadMovies()
一番上にありますが、見やすいように、WindowController 全体を含めます。これは定型的な macOS ドキュメント テンプレートに基づいて構築されており、他の機能 (開く、保存など) は追加されていません。
import Cocoa
import AVKit
import AVFoundation
class WindowController: NSWindowController {
@IBOutlet weak var AVPlayerView1: AVPlayerView!
@IBOutlet weak var loadButton: NSButton!
@IBOutlet weak var useHardCodedFlag: NSButton! //checkbox
@IBOutlet weak var hardCodedPath: NSTextField!
//action of loadButton
@IBAction func loadMovies(_ sender: Any) {
var url: URL?
// set url from text field or picker
// depending on hardCodeFlag control value
if Bool(useHardCodedFlag.intValue) == true {
url = URL(fileURLWithPath: hardCodedPath.stringValue)
} else {
let originalPath = hardCodedPath.stringValue //debug
url = pickFile()
// refresh text field with new value
hardCodedPath.stringValue = url?.path ?? "no string found"
compareURLstrings(s1: originalPath, s2: hardCodedPath.stringValue)
}
// sanity check on the url
guard let url = url, //not nil
FileManager.default //exists
.fileExists(atPath: url.path) == true
else {
print ("File URL \(String(describing: url?.path)) is nil or missing")
return
}
print("The URL is good: \(url.path)")
loadMovieWithURL(whichView: AVPlayerView1, url: url)
}
func loadMovieWithURL(whichView: AVPlayerView, url: URL){
let player = AVPlayer(url: url)
whichView.player = player
player.volume = 0.1
}
func pickFile()->URL?{
let dialog = NSOpenPanel();
dialog.title = "Choose a Movie";
dialog.showsResizeIndicator = true;
dialog.showsHiddenFiles = false;
dialog.allowsMultipleSelection = false;
dialog.canChooseDirectories = false;
dialog.allowedFileTypes = ["mov", "mp4"];
if (dialog.runModal() == NSApplication.ModalResponse.OK) {
return dialog.url
}
// "Cancel"
return nil
}
override func windowDidLoad() {
super.windowDidLoad()
// just an experiment to see if seeding bad urls initially
// might allow subsequent reloads from text field to work ... it doesn't
//let url = URL(string:"/")
//loadMovieWithURL(whichView: AVPlayerView1, url: url!)
}
}
func compareURLstrings(s1: String, s2: String){ //debugging only
s1 == s2 ?
print("The URLs are identical") :
print("The URLs are different")
}
extension Bool{
init(_ fromInt32: Int32){
fromInt32 == 0 ? self = false : self == true
}
}