diff --git a/Aerial/Source/Controllers/CustomVideoController.swift b/Aerial/Source/Controllers/CustomVideoController.swift
index c0edd1e2..50ec9c9e 100644
--- a/Aerial/Source/Controllers/CustomVideoController.swift
+++ b/Aerial/Source/Controllers/CustomVideoController.swift
@@ -29,10 +29,17 @@ class CustomVideoController: NSWindowController, NSWindowDelegate {
@IBOutlet var addPoiPopover: NSPopover!
@IBOutlet var timeTextField: NSTextField!
+ @IBOutlet var timeTextStepper: NSStepper!
+ @IBOutlet var timeTextFormatter: NumberFormatter!
@IBOutlet var descriptionTextField: NSTextField!
+ @IBOutlet var durationLabel: NSTextField!
+ @IBOutlet var resolutionLabel: NSTextField!
+
var currentFolder: Folder?
var currentAsset: Asset?
+ var currentAssetDuration: Int?
+
var hasAwokenAlready = false
var sw: NSWindow?
var controller: PreferencesWindowController?
@@ -78,7 +85,7 @@ class CustomVideoController: NSWindowController, NSWindowDelegate {
manifestInstance.addCallback { manifestVideos in
if let contr = self.controller {
- contr.loaded(manifestVideos: manifestVideos)
+ contr.loaded(manifestVideos: [])
}
}
manifestInstance.loadManifestsFromLoadedFiles()
@@ -219,6 +226,18 @@ class CustomVideoController: NSWindowController, NSWindowDelegate {
}
}
+ @IBAction func timeStepperChange(_ sender: NSStepper) {
+ if let player = editPlayerView.player {
+ player.seek(to: CMTime(seconds: Double(sender.intValue), preferredTimescale: 1))
+ }
+ }
+
+ @IBAction func timeTextChange(_ sender: NSTextField) {
+ if let player = editPlayerView.player {
+ player.seek(to: CMTime(seconds: Double(sender.intValue), preferredTimescale: 1))
+ }
+ }
+
@IBAction func tableViewTimeField(_ sender: NSTextField) {
if let asset = currentAsset {
if poiTableView.selectedRow != -1 {
@@ -338,6 +357,20 @@ extension CustomVideoController: NSOutlineViewDelegate {
if let player = editPlayerView.player {
let localitem = AVPlayerItem(url: URL(fileURLWithPath: file.url))
+ currentAssetDuration = Int(localitem.asset.duration.convertScale(1, method: .default).value)
+ let currentResolution = getResolution(asset: localitem.asset)
+ let crString = String(Int(currentResolution.width)) + "x" + String(Int(currentResolution.height))
+
+ timeTextStepper.minValue = 0
+ timeTextStepper.maxValue = Double(currentAssetDuration!)
+ timeTextFormatter.minimum = 0
+ timeTextFormatter.maximum = NSNumber(value: currentAssetDuration!)
+ //timeTableFormatter.minimum = 0
+ //timeTableFormatter.maximum = NSNumber(value: currentAssetDuration!)
+
+ durationLabel.stringValue = String(currentAssetDuration!) + " seconds"
+ resolutionLabel.stringValue = crString
+
player.replaceCurrentItem(with: localitem)
}
@@ -350,6 +383,12 @@ extension CustomVideoController: NSOutlineViewDelegate {
return true
}
+
+ func getResolution(asset: AVAsset) -> CGSize {
+ guard let track = asset.tracks(withMediaType: AVMediaType.video).first else { return CGSize.zero }
+ let size = track.naturalSize.applying(track.preferredTransform)
+ return CGSize(width: abs(size.width), height: abs(size.height))
+ }
}
// MARK: - Extension for poi table view
diff --git a/Aerial/Source/Controllers/PreferencesWindowController.swift b/Aerial/Source/Controllers/PreferencesWindowController.swift
index ed14f0cb..2be22d43 100644
--- a/Aerial/Source/Controllers/PreferencesWindowController.swift
+++ b/Aerial/Source/Controllers/PreferencesWindowController.swift
@@ -1971,8 +1971,12 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo
var videos = [AerialVideo]()
var cities = [String: City]()
+ // Grab a fresh version, because our callback can be feeding us wrong data in CVC
+ let freshManifestVideos = ManifestLoader.instance.loadedManifest
+ //debugLog("freshManifestVideos count : \(freshManifestVideos.count)")
+
// First day, then night
- for video in manifestVideos {
+ for video in freshManifestVideos {
let name = video.name
if cities.keys.contains(name) == false {
@@ -2183,6 +2187,7 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo
case let video as AerialVideo:
player = AVPlayer()
playerView.player = player
+ player.isMuted = true
debugLog("Playing this preview \(video)")
// Workaround for cached videos generating online traffic
diff --git a/Aerial/Source/Models/CustomVideoFolders.swift b/Aerial/Source/Models/CustomVideoFolders.swift
index e9a36ef7..0ae7a27a 100644
--- a/Aerial/Source/Models/CustomVideoFolders.swift
+++ b/Aerial/Source/Models/CustomVideoFolders.swift
@@ -194,6 +194,7 @@ func newJSONDecoder() -> JSONDecoder {
func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
+ encoder.outputFormatting = .prettyPrinted
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
encoder.dateEncodingStrategy = .iso8601
}
diff --git a/Aerial/Source/Models/ManifestLoader.swift b/Aerial/Source/Models/ManifestLoader.swift
index 2a812aab..6741c284 100644
--- a/Aerial/Source/Models/ManifestLoader.swift
+++ b/Aerial/Source/Models/ManifestLoader.swift
@@ -9,6 +9,7 @@
import Foundation
import ScreenSaver
import GameplayKit
+import AVFoundation
typealias ManifestLoadCallback = ([AerialVideo]) -> Void
@@ -410,6 +411,7 @@ class ManifestLoader {
if let encodedData = try? cvf.jsonData() {
try encodedData.write(to: cacheFileUrl)
debugLog("customvideos.json saved successfully!")
+ loadedManifest.removeAll() // we remove our previously loaded manifest, it's invalid
}
} catch let error as NSError {
errorLog("customvideos.json could not be saved: \(error.localizedDescription)")
@@ -422,14 +424,24 @@ class ManifestLoader {
if let cvf = customVideoFolders {
for folder in cvf.folders {
for asset in folder.assets {
+ let avResolution = getResolution(asset: AVAsset(url: URL(fileURLWithPath: asset.url)))
+ var url1080p = ""
+ var url4K = ""
+
+ if avResolution.height > 1080 {
+ url4K = URL(fileURLWithPath: asset.url).absoluteString
+ } else {
+ url1080p = URL(fileURLWithPath: asset.url).absoluteString
+ }
+
let video = AerialVideo(id: asset.id,
name: folder.label,
secondaryName: asset.accessibilityLabel,
type: "video",
timeOfDay: asset.time,
- url1080pH264: URL(fileURLWithPath: asset.url).absoluteString,
+ url1080pH264: url1080p,
url1080pHEVC: "",
- url4KHEVC: "",
+ url4KHEVC: url4K,
manifest: .customVideos,
poi: [:],
communityPoi: asset.pointsOfInterest)
@@ -439,6 +451,12 @@ class ManifestLoader {
}
}
+ func getResolution(asset: AVAsset) -> CGSize {
+ guard let track = asset.tracks(withMediaType: AVMediaType.video).first else { return CGSize.zero }
+ let size = track.naturalSize.applying(track.preferredTransform)
+ return CGSize(width: abs(size.width), height: abs(size.height))
+ }
+
// MARK: - Periodically check for new videos
func checkIfShouldRedownloadFiles() {
let dateFormatter = DateFormatter()
@@ -641,7 +659,7 @@ class ManifestLoader {
}
}*/
- debugLog("Total videos processed : \(processedVideos.count)")
+ debugLog("Total videos processed : \(processedVideos.count) callbacks : \(callbacks.count)")
// callbacks
for callback in self.callbacks {
callback(self.loadedManifest)
diff --git a/Aerial/Source/Views/AerialView.swift b/Aerial/Source/Views/AerialView.swift
index 08eb4edd..f332dd71 100644
--- a/Aerial/Source/Views/AerialView.swift
+++ b/Aerial/Source/Views/AerialView.swift
@@ -549,6 +549,7 @@ final class AerialView: ScreenSaverView, CAAnimationDelegate {
// play another video
let oldPlayer = self.player
self.player = player
+ player.isMuted = true
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.new, context: nil)
self.playerLayer.player = self.player
diff --git a/Resources/CustomVideos.xib b/Resources/CustomVideos.xib
index 4a2ccdd1..a0af20bb 100644
--- a/Resources/CustomVideos.xib
+++ b/Resources/CustomVideos.xib
@@ -12,6 +12,7 @@
+
@@ -20,8 +21,11 @@
+
+
+
@@ -221,7 +225,6 @@
-
@@ -294,10 +297,6 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -477,9 +524,19 @@ DQ
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/Info.plist b/Resources/Info.plist
index 35b27f35..5097b15a 100644
--- a/Resources/Info.plist
+++ b/Resources/Info.plist
@@ -15,11 +15,11 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 1.4.99beta6
+ 1.4.99beta7
CFBundleSignature
????
CFBundleVersion
- 1.4.99beta6
+ 1.4.99beta7
LSApplicationCategoryType
LSMinimumSystemVersion