Browse Source

Search Tags

master
marcoschmickler 4 years ago
parent
commit
adeb6fe5e4
  1. 2
      Podfile
  2. 2
      kplayer.xcodeproj/project.pbxproj
  3. 71
      kplayer/core/DatabaseManager.swift
  4. 9
      kplayer/core/MediaItem.swift
  5. 1
      kplayer/core/MediaModel.swift
  6. 7
      kplayer/core/NetworkManager.swift
  7. 10
      kplayer/detail/DetailViewController+Show.swift
  8. 13
      kplayer/detail/DetailViewController.swift
  9. 10
      kplayer/detail/ItemCell.swift
  10. 3
      kplayer/master/NetworkDelegate.swift
  11. 2
      kplayer/photo/PhotoController.swift
  12. 36
      kplayer/video/SVideoPlayer.swift

2
Podfile

@ -8,9 +8,7 @@ target 'kplayer' do
pod 'HanekeSwift', :git => 'https://github.com/Haneke/HanekeSwift.git' pod 'HanekeSwift', :git => 'https://github.com/Haneke/HanekeSwift.git'
pod 'Nimbus/Photos' pod 'Nimbus/Photos'
pod 'Nimbus/PagingScrollView' pod 'Nimbus/PagingScrollView'
# pod 'BMPlayer' #, '0.8.6'#
pod 'NVActivityIndicatorView' pod 'NVActivityIndicatorView'
pod 'SnapKit'
pod 'WebBrowser' pod 'WebBrowser'
pod 'FileBrowser' pod 'FileBrowser'
pod 'ZIPFoundation' pod 'ZIPFoundation'

2
kplayer.xcodeproj/project.pbxproj

@ -490,7 +490,6 @@
"${BUILT_PRODUCTS_DIR}/HanekeSwift/Haneke.framework", "${BUILT_PRODUCTS_DIR}/HanekeSwift/Haneke.framework",
"${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework", "${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework",
"${BUILT_PRODUCTS_DIR}/Nimbus/Nimbus.framework", "${BUILT_PRODUCTS_DIR}/Nimbus/Nimbus.framework",
"${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework",
"${BUILT_PRODUCTS_DIR}/WebBrowser/WebBrowser.framework", "${BUILT_PRODUCTS_DIR}/WebBrowser/WebBrowser.framework",
"${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework", "${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework",
); );
@ -501,7 +500,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Haneke.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Haneke.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimbus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimbus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebBrowser.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebBrowser.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZIPFoundation.framework",
); );

71
kplayer/core/DatabaseManager.swift

@ -37,6 +37,7 @@ class DatabaseManager {
for c in item.children { for c in item.children {
if s.index == c.indexId { if s.index == c.indexId {
c.objectID = s.objectID
c.time = s.time c.time = s.time
c.length = s.length c.length = s.length
c.loop = s.loop c.loop = s.loop
@ -60,6 +61,17 @@ class DatabaseManager {
} }
func getKItem(_ item: MediaItem) -> KItem { func getKItem(_ item: MediaItem) -> KItem {
if let oid = item.objectID {
do {
let i = try managedObjectContext.existingObject(with: oid)
if i != nil {
return i as! KItem
}
} catch {
}
}
let fetchRequest = KItem.fetchRequest() let fetchRequest = KItem.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "name == %@ AND path == %@ AND root == %@", item.name, item.path, item.root) fetchRequest.predicate = NSPredicate(format: "name == %@ AND path == %@ AND root == %@", item.name, item.path, item.root)
@ -95,6 +107,22 @@ class DatabaseManager {
} }
func saveItemMetaData(_ item: MediaItem) { func saveItemMetaData(_ item: MediaItem) {
if (item.type == ItemType.SNAPSHOT) {
if let oid = item.objectID {
do {
let i = try managedObjectContext.existingObject(with: oid)
if i != nil {
let snap = i as! KSnapshot
updateSnapshot(snap: snap, c: item)
print("DB -- Update snapshot at \(item.indexId)")
}
} catch {
}
}
}
if (item.type == ItemType.VIDEO) { if (item.type == ItemType.VIDEO) {
let k = getKItem(item) let k = getKItem(item)
@ -112,17 +140,8 @@ class DatabaseManager {
for c in item.children { for c in item.children {
if !kstimes.contains(Int32(c.indexId)) { if !kstimes.contains(Int32(c.indexId)) {
let snap = KSnapshot(context: managedObjectContext) let snap = KSnapshot(context: managedObjectContext)
snap.time = c.time
snap.index = Int32(c.indexId) snap.index = Int32(c.indexId)
snap.length = c.length
snap.loop = c.loop
snap.offx = Int16(c.offset.x)
snap.offy = Int16(c.offset.y)
snap.sizex = Int16(c.size.width)
snap.sizey = Int16(c.size.height)
snap.scale = c.scale
snap.rating = Int16(c.rating)
snap.thumb = c.thumbUrl
updateSnapshot(snap: snap, c: c)
k.addToSnapshots(snap) k.addToSnapshots(snap)
print("DB -- Insert snapshot at \(c.indexId)") print("DB -- Insert snapshot at \(c.indexId)")
@ -130,6 +149,18 @@ class DatabaseManager {
else { else {
for snap in ksitems { for snap in ksitems {
if snap.index == c.indexId { if snap.index == c.indexId {
updateSnapshot(snap: snap, c: c)
print("DB -- Update snapshot at \(c.indexId)")
}
}
}
}
}
save()
}
private func updateSnapshot(snap: KSnapshot, c: MediaItem) {
snap.time = c.time snap.time = c.time
snap.length = c.length snap.length = c.length
snap.loop = c.loop snap.loop = c.loop
@ -139,6 +170,7 @@ class DatabaseManager {
snap.sizey = Int16(c.size.height) snap.sizey = Int16(c.size.height)
snap.scale = c.scale snap.scale = c.scale
snap.rating = Int16(c.rating) snap.rating = Int16(c.rating)
snap.thumb = c.thumbUrl snap.thumb = c.thumbUrl
var ct = [String](c.tags) var ct = [String](c.tags)
@ -158,14 +190,6 @@ class DatabaseManager {
print("add \(a)") print("add \(a)")
} }
print("DB -- Update snapshot at \(c.indexId)")
}
}
}
}
save()
}
} }
func createTag(_ answer: String) { func createTag(_ answer: String) {
@ -263,6 +287,8 @@ class DatabaseManager {
let i = s.item! let i = s.item!
let sitem = MediaItem(name: i.name!, path: i.path!, root: i.root!, type: ItemType.VIDEO) let sitem = MediaItem(name: i.name!, path: i.path!, root: i.root!, type: ItemType.VIDEO)
sitem.loaded = true sitem.loaded = true
sitem.compilation = true
sitem.objectID = i.objectID
let c = MediaItem(name: i.name!, path: i.path!, root: i.root!, type: ItemType.SNAPSHOT) let c = MediaItem(name: i.name!, path: i.path!, root: i.root!, type: ItemType.SNAPSHOT)
c.time = s.time c.time = s.time
@ -274,9 +300,18 @@ class DatabaseManager {
c.offset.y = CGFloat(s.offy) c.offset.y = CGFloat(s.offy)
c.scale = s.scale c.scale = s.scale
c.rating = Int(s.rating) c.rating = Int(s.rating)
if s.thumb != nil {
c.thumbUrl = s.thumb c.thumbUrl = s.thumb
}
else {
c.thumbUrl = c.snapshotDirPathForVideo + "\(s.index)_thumb.jpg"
print("Thumb " + c.thumbUrl!)
}
c.indexId = Int(s.index) c.indexId = Int(s.index)
c.parent = sitem c.parent = sitem
c.objectID = s.objectID
for t in s.tags as! Set<KTag> { for t in s.tags as! Set<KTag> {
c.tags.append(t.name!) c.tags.append(t.name!)

9
kplayer/core/MediaItem.swift

@ -6,6 +6,7 @@
import Foundation import Foundation
import UIKit import UIKit
import Combine import Combine
import CoreData
/** /**
Repräsentiert ein Item eines der festgelegten Typen. Repräsentiert ein Item eines der festgelegten Typen.
@ -77,6 +78,10 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable {
var favorite = false var favorite = false
var compilation = false
var objectID : NSManagedObjectID?
@Published @Published
var scale = 0.0 var scale = 0.0
@Published @Published
@ -101,6 +106,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable {
self.loaded = true self.loaded = true
self.local = true self.local = true
self.indexId = model.indexId self.indexId = model.indexId
self.tags = model.tags
for m in model.children { for m in model.children {
let item = MediaItem(model: m) let item = MediaItem(model: m)
@ -121,7 +127,6 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable {
} }
var model: MediaModel = MediaModel(name: name, path: path, root: root, children: c, type: type) var model: MediaModel = MediaModel(name: name, path: path, root: root, children: c, type: type)
model.time = time model.time = time
model.loop = loop model.loop = loop
model.length = length model.length = length
@ -132,6 +137,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable {
model.scale = scale model.scale = scale
model.favorite = favorite model.favorite = favorite
model.indexId = indexId model.indexId = indexId
model.tags = tags
return model return model
} }
@ -324,6 +330,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable {
func clone() -> MediaItem { func clone() -> MediaItem {
let m = MediaItem(model: toMediaModel()) let m = MediaItem(model: toMediaModel())
m.local = local m.local = local
m.compilation = compilation
for c in m.children { for c in m.children {
c.local = local c.local = local

1
kplayer/core/MediaModel.swift

@ -25,4 +25,5 @@ public struct MediaModel : Codable {
var children: [MediaModel] var children: [MediaModel]
let type: ItemType let type: ItemType
var tags = [String]()
} }

7
kplayer/core/NetworkManager.swift

@ -344,6 +344,7 @@ class NetworkManager {
func saveItem(_ item: MediaItem) { func saveItem(_ item: MediaItem) {
var ch = item.children var ch = item.children
// print(ch) // print(ch)
DatabaseManager.sharedInstance.saveItemMetaData(item)
if (item.local) { if (item.local) {
return return
@ -353,9 +354,7 @@ class NetworkManager {
return return
} }
DatabaseManager.sharedInstance.saveItemMetaData(item)
let url = baseurl + "/service/listfiles" + item.snapshotDirPathForVideo
let url = nodeurl + "listfiles" + item.snapshotDirPathForVideo
print(url) print(url)
@ -401,7 +400,7 @@ class NetworkManager {
func loadPicDetails(items: MediaItem, result: @escaping ([MediaItem]) -> () ) { func loadPicDetails(items: MediaItem, result: @escaping ([MediaItem]) -> () ) {
let len = items.root.count let len = items.root.count
let url = NetworkManager.sharedInstance.baseurl + "/service/listfiles" + items.fullPath
let url = nodeurl + "listfiles" + items.fullPath
print(items) print(items)
print(url) print(url)

10
kplayer/detail/DetailViewController+Show.swift

@ -64,6 +64,15 @@ extension DetailViewController {
baseItem = selectedItem.parent! baseItem = selectedItem.parent!
} }
if baseItem.compilation && mode {
baseItem.compilation = false
baseItem.children.removeAll()
baseItem.loaded = false
baseItem.parent = nil
NetworkManager.sharedInstance.loadItem(baseItem, index: 0)
return
}
children = baseItem.children children = baseItem.children
clonedChildren = baseItem.clone().children clonedChildren = baseItem.clone().children
@ -116,6 +125,7 @@ extension DetailViewController {
func showAllVideos(_ item: MediaItem) { func showAllVideos(_ item: MediaItem) {
let composition = MediaItem(name: item.name, path: item.path, root: item.root, type: ItemType.VIDEO) let composition = MediaItem(name: item.name, path: item.path, root: item.root, type: ItemType.VIDEO)
composition.compilation = true
for d in item.children { for d in item.children {
if d.children.isEmpty { if d.children.isEmpty {

13
kplayer/detail/DetailViewController.swift

@ -35,6 +35,9 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
var defaultItemSize = CGSize(width: (15 * 16) - 6, height: 15 * 9) var defaultItemSize = CGSize(width: (15 * 16) - 6, height: 15 * 9)
var modeButton: UIBarButtonItem?
var mode = false
var detailItem: MediaItem? { var detailItem: MediaItem? {
didSet { didSet {
// print(detailItem!.children) // print(detailItem!.children)
@ -88,11 +91,12 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
lpgr.delaysTouchesBegan = true lpgr.delaysTouchesBegan = true
self.collectionView.addGestureRecognizer(lpgr); self.collectionView.addGestureRecognizer(lpgr);
modeButton = UIBarButtonItem(barButtonSystemItem: .search , target: self, action: #selector(switchMode));
let settingsButton = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(settings)); let settingsButton = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(settings));
let overviewButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(overview)); let overviewButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(overview));
let favButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(favorites)); let favButton = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(favorites));
let browserButton = UIBarButtonItem(barButtonSystemItem: .organize, target: self, action: #selector(fileBrowser)); let browserButton = UIBarButtonItem(barButtonSystemItem: .organize, target: self, action: #selector(fileBrowser));
navigationItem.rightBarButtonItems = [settingsButton, favButton, overviewButton,browserButton]
navigationItem.rightBarButtonItems = [settingsButton, favButton, overviewButton,browserButton,modeButton!]
if detailItem != nil { if detailItem != nil {
if detailItem!.children != nil { if detailItem!.children != nil {
var d = detailItem!.children var d = detailItem!.children
@ -101,6 +105,13 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
} }
} }
@objc func switchMode() {
mode = !mode
if let b = modeButton {
b.isSelected = mode
}
}
// https://github.com/marmelroy/FileBrowser // https://github.com/marmelroy/FileBrowser
@objc func fileBrowser() { @objc func fileBrowser() {
let d = FileHelper.getDocumentsDirectory() let d = FileHelper.getDocumentsDirectory()

10
kplayer/detail/ItemCell.swift

@ -14,6 +14,7 @@ class ItemCell: UICollectionViewCell {
var image: UIImageView! var image: UIImageView!
var fav: UIImageView! var fav: UIImageView!
var loop: UIImageView!
var progress: UIProgressView! var progress: UIProgressView!
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
@ -34,6 +35,13 @@ class ItemCell: UICollectionViewCell {
image.addSubview(fav) image.addSubview(fav)
fav.isHidden = true fav.isHidden = true
let ci = UIImage(systemName: "repeat.circle")
loop = UIImageView(image: ci)
// fav.contentMode = UIView.ContentMode.scaleAspectFill
image.addSubview(loop)
loop.isHidden = true
progress = UIProgressView(progressViewStyle: .default) progress = UIProgressView(progressViewStyle: .default)
progress.progressTintColor = .red progress.progressTintColor = .red
progress.trackTintColor = .lightGray progress.trackTintColor = .lightGray
@ -61,6 +69,8 @@ class ItemCell: UICollectionViewCell {
fav.isHidden = !f fav.isHidden = !f
loop.isHidden = item.length == 0.0
if let _ = item.thumbUrl, let nsurl = URL(string: item.thumbUrlAbsolute) { if let _ = item.thumbUrl, let nsurl = URL(string: item.thumbUrlAbsolute) {
image.hnk_setImageFromURL(nsurl, placeholder: defaultImage) image.hnk_setImageFromURL(nsurl, placeholder: defaultImage)
} else { } else {

3
kplayer/master/NetworkDelegate.swift

@ -122,6 +122,9 @@ class NetworkDelegate: MasterDelegate, DetailDelegate {
if let name = item.externalURL { if let name = item.externalURL {
LocalManager.sharedInstance.saveFavDir(url: URL(string: name)!, item: item) LocalManager.sharedInstance.saveFavDir(url: URL(string: name)!, item: item)
} }
else {
DatabaseManager.sharedInstance.saveItemMetaData(item)
}
} }
else { else {
NetworkManager.sharedInstance.saveItem(selectedItem) NetworkManager.sharedInstance.saveItem(selectedItem)

2
kplayer/photo/PhotoController.swift

@ -169,7 +169,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
let items = currentItem let items = currentItem
let len = items.root.count let len = items.root.count
let url = NetworkManager.sharedInstance.baseurl + "/service/listfiles" + items.root + "/" + items.path + "/" + items.name
let url = NetworkManager.sharedInstance.nodeurl + "listfiles" + items.root + "/" + items.path + "/" + items.name
print(items) print(items)
print(url) print(url)

36
kplayer/video/SVideoPlayer.swift

@ -10,7 +10,6 @@ import AVKit
struct SVideoPlayer: View, EditItemDelegate { struct SVideoPlayer: View, EditItemDelegate {
// url: URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")! // url: URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")!
var player = AVQueuePlayer(items: [AVPlayerItem]()) var player = AVQueuePlayer(items: [AVPlayerItem]())
var secondPlayer = AVQueuePlayer(items: [AVPlayerItem]())
var playerLooper : AVPlayerLooper var playerLooper : AVPlayerLooper
var completionHandler: ((Bool) -> Void)? var completionHandler: ((Bool) -> Void)?
@ -135,12 +134,14 @@ struct SVideoPlayer: View, EditItemDelegate {
Spacer() Spacer()
Button(action: { model.edit = true }, label: {
Button(action: { model.edit.toggle() }, label: {
Text("edit") Text("edit")
}).buttonStyle(BorderlessButtonStyle()); }).buttonStyle(BorderlessButtonStyle());
if !model.baseItem.compilation {
Button(action: doSnapshot, label: { Button(action: doSnapshot, label: {
Text("snap") Text("snap")
}).buttonStyle(BorderlessButtonStyle()); }).buttonStyle(BorderlessButtonStyle());
}
}.frame(height: 50) }.frame(height: 50)
GeometryReader { geometry in GeometryReader { geometry in
@ -268,6 +269,22 @@ struct SVideoPlayer: View, EditItemDelegate {
} }
private func move(_ dragged: CGSize, start: CGPoint) -> Bool { private func move(_ dragged: CGSize, start: CGPoint) -> Bool {
if dragged.height > 100 {
if timeCounter == 0 {
if let i = model.allItems.index(where: { m in m === model.currentSnapshot }) {
if i + 1 < model.allItems.count {
gotoSnapshot(model.allItems[i+1])
}
else {
gotoSnapshot(model.allItems[0])
}
timeCounter = 15
print("jump")
}
}
return false
}
if model.paused { if model.paused {
if let time = getCurrentTime() { if let time = getCurrentTime() {
if smoothTime < 0 { if smoothTime < 0 {
@ -317,17 +334,6 @@ struct SVideoPlayer: View, EditItemDelegate {
// model.seeking = sk // model.seeking = sk
} }
if dragged.height > 100 && timeCounter == 0 {
if let i = model.allItems.index(where: { m in m === model.currentSnapshot }) {
if i + 1 < model.allItems.count {
gotoSnapshot(model.allItems[i+1])
}
else {
gotoSnapshot(model.allItems[0])
}
timeCounter = 20
}
}
return false return false
} }
@ -338,6 +344,10 @@ struct SVideoPlayer: View, EditItemDelegate {
func seekTime(_ time: Double) { func seekTime(_ time: Double) {
print("Seek \(time)") print("Seek \(time)")
if (time == 30.0) {
print("catch")
}
self.model.seeking = true self.model.seeking = true
player.pause() player.pause()
// player.cancelPendingPrerolls() // player.cancelPendingPrerolls()

Loading…
Cancel
Save