Browse Source

Images

master
marcoschmickler 4 years ago
parent
commit
7a63c0f981
  1. 1
      Podfile
  2. 2
      Pods/Nimbus/src/photos/src/NIPhotoScrollView.m
  3. 2
      Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift
  4. 10
      kplayer.xcodeproj/project.pbxproj
  5. 2
      kplayer/Info.plist
  6. 14
      kplayer/core/MediaItem.swift
  7. 5
      kplayer/core/MediaModel.swift
  8. 66
      kplayer/core/NetworkManager.swift
  9. 51
      kplayer/core/ThumbnailCache.swift
  10. 45
      kplayer/detail/BrowserController.swift
  11. 28
      kplayer/detail/DetailViewController.swift
  12. 4
      kplayer/detail/VideoController.swift
  13. 4
      kplayer/master/MasterViewController.swift
  14. 2
      kplayer/master/NetworkDelegate.swift
  15. 54
      kplayer/photo/PhotoController.swift
  16. 97
      kplayer/server/download.js
  17. 12
      kplayer/server/links.html
  18. 8
      kplayer/util/FileHelper.swift
  19. 11
      kplayer/util/ImageLoadOperation.swift

1
Podfile

@ -13,5 +13,6 @@ target 'kplayer' do
pod 'SnapKit'
pod 'WebBrowser'
pod 'FileBrowser'
pod 'ZIPFoundation'
end

2
Pods/Nimbus/src/photos/src/NIPhotoScrollView.m

@ -189,6 +189,8 @@
BOOL didZoomIn;
_scrollView.scrollEnabled = true;
if (isCompletelyZoomedIn) {
// Zoom the photo back out.
[_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES];

2
Pods/WebBrowser/WebBrowser/WebBrowserViewController.swift

@ -282,7 +282,7 @@ extension WebBrowserViewController {
extension WebBrowserViewController {
// MARK: - Tool bar
fileprivate func updateToolBarState() {
public func updateToolBarState() {
backButton.isEnabled = webView.canGoBack
forwardButton.isEnabled = webView.canGoForward

10
kplayer.xcodeproj/project.pbxproj

@ -18,6 +18,7 @@
1C736503B656C999E5E12081 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7365B06FA66294E99AC2D3 /* NetworkManager.swift */; };
1C73654C9EA6D255CFC039C5 /* NetworkHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73620D01687FB4F1811C5C /* NetworkHelper.swift */; };
1C7365885FAF292F2221ED44 /* PhotoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73673DC671535E3A049F54 /* PhotoController.swift */; };
1C736662E43C6E8FFED11AC4 /* download.js in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C1368E0DE89BAA2DF60 /* download.js */; };
1C7366A0CFD2B55BF8C3BAF0 /* NetworkDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */; };
1C7366DAC06047DE335EFC37 /* BMPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736927EA28AFBEB25D7487 /* BMPlayer.swift */; };
1C73671FC2CCCACAA2FFC153 /* ThumbnailCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736EA15A11AF7D57F85824 /* ThumbnailCache.swift */; };
@ -32,6 +33,7 @@
1C73691A9C7174E0C6B57267 /* stringutil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736B794396F2E50387B8F2 /* stringutil.swift */; };
1C73693A1334A7792856FC58 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73611D226B48C24DB37535 /* MasterViewController.swift */; };
1C736953BDBBAFC40884132A /* BrowserController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73602350ACE2436736F981 /* BrowserController.swift */; };
1C73696E4C0353053BF98031 /* links.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C73615FFA2AA98BD1C56CD4 /* links.html */; };
1C7369ABC44CFB530EA71FB6 /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */; };
1C736A06A2AD75B8C14EEBBE /* HtmlParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736DBB6986A8B62963FBB3 /* HtmlParser.swift */; };
1C736A5FA5BA53B2597F2ED7 /* Kirschkeks-256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = 1C736059262A57AADE6AB761 /* Kirschkeks-256x256.png */; };
@ -77,6 +79,7 @@
1C7360D6580FB5D09C2BBCCB /* BMPlayerManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BMPlayerManager.swift; sourceTree = "<group>"; };
1C73610B997EBA367C806C1B /* BMPlayerCompositionResourceDefinition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BMPlayerCompositionResourceDefinition.swift; sourceTree = "<group>"; };
1C73611D226B48C24DB37535 /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = "<group>"; };
1C73615FFA2AA98BD1C56CD4 /* links.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = links.html; sourceTree = "<group>"; };
1C73620D01687FB4F1811C5C /* NetworkHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkHelper.swift; sourceTree = "<group>"; };
1C73625012D50E457D18A785 /* kplayer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = kplayer.js; sourceTree = "<group>"; };
1C736253AB7A95EA41B605B7 /* ItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemModel.swift; sourceTree = "<group>"; };
@ -101,6 +104,7 @@
1C736B41C6AC33F3FA592C63 /* MediaModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaModel.swift; sourceTree = "<group>"; };
1C736B794396F2E50387B8F2 /* stringutil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = stringutil.swift; sourceTree = "<group>"; };
1C736BC4450890C45F8FBC63 /* LayoutTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutTools.swift; sourceTree = "<group>"; };
1C736C1368E0DE89BAA2DF60 /* download.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = download.js; sourceTree = "<group>"; };
1C736C7FFBDAC665AE04CB65 /* VideoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoController.swift; sourceTree = "<group>"; };
1C736D9BB5498E7E8F11C754 /* HeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = "<group>"; };
1C736DBB6986A8B62963FBB3 /* HtmlParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HtmlParser.swift; sourceTree = "<group>"; };
@ -160,6 +164,8 @@
isa = PBXGroup;
children = (
1C73625012D50E457D18A785 /* kplayer.js */,
1C736C1368E0DE89BAA2DF60 /* download.js */,
1C73615FFA2AA98BD1C56CD4 /* links.html */,
);
path = server;
sourceTree = "<group>";
@ -409,6 +415,7 @@
C98AF5E41B124D6A00D196CC /* LaunchScreen.xib in Resources */,
C98AF5E11B124D6A00D196CC /* Images.xcassets in Resources */,
1C736A5FA5BA53B2597F2ED7 /* Kirschkeks-256x256.png in Resources */,
1C73696E4C0353053BF98031 /* links.html in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -436,6 +443,7 @@
"${BUILT_PRODUCTS_DIR}/Nimbus/Nimbus.framework",
"${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework",
"${BUILT_PRODUCTS_DIR}/WebBrowser/WebBrowser.framework",
"${BUILT_PRODUCTS_DIR}/ZIPFoundation/ZIPFoundation.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
@ -446,6 +454,7 @@
"${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}/ZIPFoundation.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@ -518,6 +527,7 @@
1C736A06A2AD75B8C14EEBBE /* HtmlParser.swift in Sources */,
1C736048BFA120F5C7D36874 /* readme.md in Sources */,
1C736771C503FB0D52AEB8F7 /* kplayer.js in Sources */,
1C736662E43C6E8FFED11AC4 /* download.js in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

2
kplayer/Info.plist

@ -55,6 +55,8 @@
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>NSFaceIDUsageDescription</key>
<string>cool</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>

14
kplayer/core/MediaItem.swift

@ -47,6 +47,10 @@ class MediaItem: CustomDebugStringConvertible {
var leaf = false
var cancelled = false
var scale = 0.0
var offset = CGPoint()
var size = CGSize()
convenience init(model: MediaModel) {
self.init(name: model.name, path: model.path, root: model.root, type: model.type)
@ -54,6 +58,9 @@ class MediaItem: CustomDebugStringConvertible {
self.length = model.length
self.loop = model.loop
self.thumbUrl = model.thumbURL
self.scale = model.scale
self.offset = model.offset
self.size = model.size
for m in model.children {
let item = MediaItem(model: m)
@ -77,6 +84,9 @@ class MediaItem: CustomDebugStringConvertible {
model.loop = loop
model.length = length ?? 0
model.thumbURL = thumbUrl
model.size = size
model.offset = offset
model.scale = scale
return model
}
@ -153,6 +163,10 @@ class MediaItem: CustomDebugStringConvertible {
Absolute URL, unter der das Image des Items abgerufen werden kann.
*/
var imageUrlAbsolute: String {
if thumbUrl!.starts(with: "file:") {
return thumbUrl!
}
var imageUrl = thumbUrl!.replacingOccurrences(of: "_thumb.", with: ".")
imageUrl = imageUrl.replacingOccurrences(of: "?preview=true", with: "")
imageUrl = imageUrl.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!

5
kplayer/core/MediaModel.swift

@ -4,6 +4,7 @@
//
import Foundation
import UIKit
public struct MediaModel : Codable {
let name: String
@ -15,6 +16,10 @@ public struct MediaModel : Codable {
var loop = false
var thumbURL : String?
var scale = 0.0
var offset = CGPoint()
var size = CGSize()
var children: [MediaModel]
let type: ItemType
}

66
kplayer/core/NetworkManager.swift

@ -46,12 +46,73 @@ class NetworkManager {
func loadFavDirs(_ rootParam: String, completionHandler: @escaping Weiter) -> Void {
var res = [MediaItem]()
var itemsMap = Dictionary<String, MediaItem>()
let fi = MediaItem(name: "images", path: "", root: "fav", type: ItemType.DETAILS)
fi.local = true
fi.loaded = true
res.append(fi)
let url = FileHelper.getDocumentsDirectory()
if let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) {
for case let fileURL as URL in enumerator {
do {
let fileAttributes = try fileURL.resourceValues(forKeys:[.isRegularFileKey])
if fileAttributes.isRegularFile! {
if (fileURL.pathExtension == "jpg" && fileURL.absoluteString.contains("/images/")) {
let p = fileURL.absoluteString.substringAfter("/Documents")
var path = p.substringBefore("/")
let fp = fileURL.absoluteString.substringAfter("/Documents/images/")
var fpath = fp.substringBefore("/")
var folder = itemsMap[fpath]
if folder == nil {
let f = MediaItem(name: fpath, path: "images", root: "fav", type: ItemType.PICS)
f.local = true
f.loaded = true
folder = f
itemsMap[fpath] = folder!
fi.children.append(f)
}
let m = MediaItem(name: fileURL.lastPathComponent, path: path, root: "fav", type: ItemType.PICS)
m.local = true
m.loaded = true
m.thumbUrl = fileURL.absoluteString
let jsonURL = fileURL.absoluteString.replacingOccurrences(of: ".jpg", with: ".json")
do {
let jsonData = try Data(contentsOf: URL(string: jsonURL)!)
let item = try JSONDecoder().decode(MediaModel.self, from: jsonData)
m.scale = item.scale
m.offset = item.offset
m.size = item.size
}
catch {
}
// var folder = itemsMap[path]
//
// if folder == nil {
// folder = MediaItem(name: item.path, path: item.path, root: item.root, type: ItemType.FOLDER)
// folder!.loaded = true
// folder!.local = item.local
// itemsMap[path] = folder!
// items.append(folder!)
// }
folder!.children.append(m)
print(fileURL.absoluteString)
}
if (fileURL.pathExtension == "mp4") {
print(fileURL.absoluteString)
@ -533,13 +594,13 @@ class NetworkManager {
}
}
func download(url: URL) {
func download(url: URL, path: String, result: @escaping (URL) -> () ) {
UIApplication.shared.isIdleTimerDisabled = true
let destination: DownloadRequest.Destination = {temporaryURL, response in
if let suggestedFileName = response.suggestedFilename {
do {
let directory = try FileHelper.createDir(name: "download")
let directory = try FileHelper.createDir(name: path)
let downloadedFilePath = directory.appendingPathComponent(suggestedFileName)
// if downloadedFilePath.exists { try self.downloadedFilePath?.deleteFile() }
return (downloadedFilePath, [.removePreviousFile, .createIntermediateDirectories])
@ -580,6 +641,7 @@ class NetworkManager {
NetworkManager.sharedInstance.currentDownloads.removeValue(forKey: url.lastPathComponent)
print("Success: \(statusCode)")
}
result(destinationUrl)
}
}
}

51
kplayer/core/ThumbnailCache.swift

@ -107,9 +107,20 @@ class ThumbnailCache {
return
}
var file = false
for k in start ..< end {
let tu = items[k].thumbUrl!.replacingOccurrences(of: "?preview=true", with: "")
preview += "\(tu);"
if items[k].thumbUrl!.starts(with:"file::") {
file = true
let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in }
loadThumbnail(thumbnailIndex: k, thumbnail: thumbnail)
}
else {
let tu = items[k].thumbUrl!.replacingOccurrences(of: "?preview=true", with: "")
preview += "\(tu);"
}
}
if (file) {
return
}
preview = preview.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
@ -153,6 +164,32 @@ class ThumbnailCache {
return nil
}
func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
let size = image.size
let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height
// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}
// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(origin: .zero, size: newSize)
// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
func loadThumbnail(thumbnailIndex: Int, thumbnail: @escaping (UIImage, Int) -> ()) -> UIImage? {
var image: UIImage?
let newItem = items[thumbnailIndex]
@ -163,12 +200,16 @@ class ThumbnailCache {
image = imageCache.object(forKey: URL.absoluteString as AnyObject) as? UIImage
if (image == nil && (!loading||thumbnailIndex == 0)) {
let task: URLSessionDataTask = urlSession!.dataTask(with: URL) {
let task: URLSessionDataTask = urlSession!.dataTask(with: URL) { [self]
(da, response, error) in
if let d = da {
if let i = UIImage(data: d) {
// println("thumb image loaded \(newItem.thumbUrlAbsolute)")
if var i = UIImage(data: d) {
if d.count > 500000 {
i = resizeImage(image: i, targetSize: CGSize(width: 1200, height: 1200))!
}
print("thumb image loaded \(newItem.thumbUrlAbsolute)")
let imageRef = i.cgImage;
self.imageCache.setObject(i, forKey: newItem.thumbUrlAbsolute as AnyObject, cost: d.count)

45
kplayer/detail/BrowserController.swift

@ -85,6 +85,8 @@ class BrowserController : UIViewController, ItemController, WebBrowserDelegate,
self.completionHandler!()
//self.navigationController?.popViewController(animated: true)
}
let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(BrowserController.back(_:)))
webBrowserViewController.navigationItem.leftBarButtonItems = [backButton]
let reviewButton = UIBarButtonItem(title:"download", style:UIBarButtonItem.Style.plain, target: self, action: #selector(BrowserController.doDownload(_:)))
@ -99,6 +101,16 @@ class BrowserController : UIViewController, ItemController, WebBrowserDelegate,
executeDocumentDownloadScript(webView: web!.getWKWebView(), forAbsoluteUrl: "hello")
}
@IBAction func back(_ sender: AnyObject) {
if (web!.getWKWebView().canGoBack) {
web!.getWKWebView().goBack()
web!.updateToolBarState()
}
else {
completionHandler!()
}
}
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
debugPrint("did receive message \(message.name)")
@ -154,8 +166,21 @@ class BrowserController : UIViewController, ItemController, WebBrowserDelegate,
}
func preview(url: String) {
let url2 = URL(string: url)!
if (url2.pathExtension == "zip") {
downloadZip(url2, path: "download")
return
}
if (url2.pathExtension == "jpg") {
downloadZip(url2, path: "images/new")
return
}
let name = url2.lastPathComponent
let vc = VideoController()
let name = URL(string: url)!.lastPathComponent
let hostcomp = currentItem!.name.split(separator: ".")
let site = String(hostcomp[hostcomp.count-2])
@ -179,6 +204,12 @@ class BrowserController : UIViewController, ItemController, WebBrowserDelegate,
self.present(navController, animated: false, completion: nil)
}
private func downloadZip(_ url: URL, path: String) {
NetworkManager.sharedInstance.download(url: url, path: path) { url in
self.showAlert(title: url.lastPathComponent, message: "ready")
}
}
func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) {
print(url?.absoluteString)
}
@ -231,4 +262,16 @@ print(url?.absoluteString)
}
}
func showAlert(title:String, message:String ) {
let alertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alertVC.addAction(okAction)
DispatchQueue.main.async() { () -> Void in
self.present(alertVC, animated: true, completion: nil)
}
}
}

28
kplayer/detail/DetailViewController.swift

@ -10,6 +10,7 @@ import UIKit
import Alamofire
import FileBrowser
import AVFoundation
import ZIPFoundation
protocol DetailDelegate {
func loadDetails(selectedItem: MediaItem, completionHandler: @escaping () -> Void)
@ -105,13 +106,38 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
let files = FileHelper.listFiles(name: "")
for f in files {
if f.pathExtension == "mp4" {
try FileManager.default.moveItem(at: f, to: i.appendingPathComponent(f.lastPathComponent))
var dest = i.appendingPathComponent(f.lastPathComponent)
try FileManager.default.moveItem(at: f, to: dest)
try FileHelper.setExcludeFromiCloudBackup(&dest, isExcluded: true)
}
}
} catch {
}
do {
let i = try FileHelper.createDir(name: "images")
let files = FileHelper.listFiles(name: "download")
for f in files {
print(f)
if f.pathExtension == "zip" {
var dest = i.appendingPathComponent(f.lastPathComponent)
do {
try FileManager.default.createDirectory(at: dest, withIntermediateDirectories: true, attributes: nil)
try FileManager.default.unzipItem(at: f, to: dest)
} catch {
print("Extraction of ZIP archive failed with error:\(error)")
}
try FileManager.default.removeItem(at: f)
try FileHelper.setExcludeFromiCloudBackup(&dest, isExcluded: true)
}
}
} catch {
}
let fileBrowser = FileBrowser(initialPath: d, allowEditing: true)
fileBrowser.modalPresentationStyle = .fullScreen
present(fileBrowser, animated: true, completion: nil)
}

4
kplayer/detail/VideoController.swift

@ -161,7 +161,9 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate {
let downloadAction = UIAlertAction(title: "Download to fav", style: .default) { (action) in
let url = self.currentItem!.playerURL
NetworkManager.sharedInstance.download(url: url!)
NetworkManager.sharedInstance.download(url: url!, path: "download") { url in
self.showAlert(title: url.lastPathComponent, message: "ready")
}
}
let url = self.currentItem!.playerURL

4
kplayer/master/MasterViewController.swift

@ -296,11 +296,13 @@ class MasterViewController: UITableViewController, UISearchResultsUpdating, UITa
m.local = true
let at = m.playerURL!
m.path = destinationItem.path
let to = m.playerURL!
var to = m.playerURL!
print(destinationItem.name)
do {
try FileManager.default.moveItem(at: at, to: to)
try FileHelper.setExcludeFromiCloudBackup(&to, isExcluded: true)
try FileManager.default.moveItem(at: at.appendingPathExtension("json"), to: to.appendingPathExtension("json"))
do {
try FileManager.default.moveItem(at: at.appendingPathExtension("jpg"), to: to.appendingPathExtension("jpg"))

2
kplayer/master/NetworkDelegate.swift

@ -66,7 +66,7 @@ class NetworkDelegate: MasterDelegate, DetailDelegate {
func loadDetails(selectedItem: MediaItem, completionHandler: @escaping () -> ()) {
if selectedItem.isPic() {
if selectedItem.isPic() && !selectedItem.local {
NetworkManager.sharedInstance.loadPicDetails(items: selectedItem, result: { (im: [MediaItem]) in
selectedItem.children = im
completionHandler()

54
kplayer/photo/PhotoController.swift

@ -87,12 +87,41 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
let currentItem = items[photoAlbumView.centerPageIndex]
var imageUrl = currentItem.thumbUrl!.replacingOccurrences(of: "_thumb.jpg", with: ".jpg")
imageUrl = imageUrl.replacingOccurrences(of: "?preview=true", with: "")
let url = NetworkManager.sharedInstance.baseurl + "/service/linkfavpic" + imageUrl
print(url)
AF.request(url).responseString {
(result) in
print("ok")
if imageUrl.starts(with: "file://") {
let pages = photoAlbumView.visiblePages()!
for case let page as NIPhotoScrollView in pages {
if (page.pageIndex == photoAlbumView.centerPageIndex) {
let scroll = page.value(forKey: "scrollView") as! UIScrollView
if scroll.isScrollEnabled {
currentItem.scale = Double(scroll.zoomScale)
currentItem.offset = scroll.contentOffset
currentItem.size = scroll.contentSize
let jsonFile = currentItem.path + "/" + currentItem.name.replacingOccurrences(of: ".jpg", with: ".json")
NetworkManager.sharedInstance.saveFavDir(name: jsonFile, item: currentItem)
// print(currentItem.toJSON())
scroll.isScrollEnabled = false
}
else {
scroll.isScrollEnabled = true
}
}
}
}
else {
let url = NetworkManager.sharedInstance.baseurl + "/service/linkfavpic" + imageUrl
print(url)
AF.request(url).responseString {
(result) in
print("ok")
}
}
}
@ -288,6 +317,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
}
let view2 = photoAlbumView.centerPageView() as! NIPhotoScrollView
restoreScrollState(currentIndex: currentIndex, view: view2)
if view2.photoSize() != NIPhotoScrollViewPhotoSizeOriginal {
if nextImage != nil && currentIndex == nextImageIndex {
@ -299,6 +329,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
i in
// self.photoAlbumView.isZoomingAboveOriginalSizeEnabled = max(i.size.height, i.size.width) <= 6000;
self.photoAlbumView.didLoadPhoto(i, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal)
self.restoreScrollState(currentIndex: currentIndex, view: view2)
}, index: currentIndex)
loadOriginal = op2
op2.qualityOfService = QualityOfService.userInitiated
@ -346,6 +377,19 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
}
private func restoreScrollState(currentIndex: Int, view: NIPhotoScrollView) {
let item = items[currentIndex]
if item.scale > 0.0 {
// view.setValue(false, forKey: "zoomingIsEnabled")
let scroll = view.value(forKey: "scrollView") as! UIScrollView
scroll.zoomScale = CGFloat(item.scale)
scroll.contentSize = item.size
scroll.contentOffset = item.offset
scroll.isScrollEnabled = false
}
}
func numberOfPages(in pagingScrollView: NIPagingScrollView) -> Int {
let c = items.count
return c

97
kplayer/server/download.js

@ -0,0 +1,97 @@
(async function download() {
try {
window.webkit.messageHandlers.jsError.postMessage(document.cookie)
window.webkit.messageHandlers.jsError.postMessage(window.location.hostname)
var links = []
var linkname = "href"
window.kplayerUrls = []
if (window.location.hostname.endsWith("hegre.com")) {
links = document.querySelectorAll('a[class="members-only"], a[class="image-download"]')
linkname = "href"
}
else if (window.location.hostname == "www.kink.com") {
links = document.querySelectorAll('span[data-resolution="720"], span[data-resolution="1080"]')
linkname = "data-url"
}
else if (window.location.hostname.endsWith("xhamster.com")) {
var lnks = document.querySelectorAll('link[rel="preload"]')
for (var i=0; i<lnks.length; ++i) {
var u = lnks[i].href
if (u.indexOf(".m3u8")>0) {
var base = u.split('/').slice(0,3).join('/')
window.webkit.messageHandlers.jsError.postMessage('base: ' + base)
window.webkit.messageHandlers.jsError.postMessage('url: ' + u)
var r = await fetch(u)
var data = await r.text()
// Do something with your data
var lines = data.split('\n')
for (let l of lines) {
if (!l.startsWith("#")) {
window.webkit.messageHandlers.jsError.postMessage('l: ' + base + l)
window.kplayerUrls.push(base + l)
}
}
}
}
}
else if (window.location.hostname.endsWith("xvideos.com")) {
if (html5player) {
if (html5player.url_hls) {
var u = html5player.url_hls
window.webkit.messageHandlers.jsError.postMessage(u)
if (u.indexOf("hls.m3u8")>0) {
var base = u.split('/').slice(0,-1).join('/')
var r = await fetch(u)
var data = await r.text()
// Do something with your data
var lines = data.split('\n')
for (let l of lines) {
if (!l.startsWith("#")) {
window.kplayerUrls.push(base + "/" + l)
}
}
}
window.webkit.messageHandlers.jsError.postMessage(JSON.stringify(window.kplayerUrls))
window.kplayerUrls.push(u)
}
}
}
links.forEach(
function(currentValue, currentIndex, listObj) {
window.webkit.messageHandlers.jsError.postMessage(JSON.stringify(currentValue))
window.kplayerUrls.push(currentValue.getAttribute(linkname))
},
'myThisArg'
);
window.webkit.messageHandlers.openDocument.postMessage(JSON.stringify(window.kplayerUrls));
// window.webkit.messageHandlers.jsError.postMessage("k"+links);
// we use a second try block here to have more detailed error information
// because of the nature of JS the outer try-catch doesn't know anything where the error happended
let res;
try {
} catch (err) {
window.webkit.messageHandlers.jsError.postMessage('fetch threw, error: '+ err );
return;
}
} catch (err) {
window.webkit.messageHandlers.jsError.postMessage('fetch threw, error: '+ err);
return;
}
})();
// null is needed here as this eval returns the last statement and we can't return a promise
null;

12
kplayer/server/links.html

@ -0,0 +1,12 @@
<html>
<body>
<a href="https://www.google.de">Google</a>
<a href="https://www.xvideos.com">XVID</a>
<a href="https://www.xhamster.com">XVID</a>
<a href="https://www.letsdoeit.com">XVID</a>
<a href="https://www.debt4k.com">XVID</a>
<a href="https://www.kink.com">XVID</a>
<a href="https://www.hegre.com">XVID</a>
</body>
</html>

8
kplayer/util/FileHelper.swift

@ -35,7 +35,7 @@ print(url)
static func listFiles(name: String)-> [URL] {
let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] //.appendingPathComponent(name)
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(name)
print (documentsURL)
do {
let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
@ -46,4 +46,10 @@ print(url)
}
return []
}
static func setExcludeFromiCloudBackup(_ fileOrDirectoryURL: inout URL, isExcluded: Bool) throws {
var values = URLResourceValues()
values.isExcludedFromBackup = isExcluded
try fileOrDirectoryURL.setResourceValues(values)
}
}

11
kplayer/util/ImageLoadOperation.swift

@ -24,6 +24,10 @@ public class ImageLoadOperation: Operation {
}
override public func main() {
if imageURL.isFileURL {
usleep(100000)
}
if self.isCancelled {
return
}
@ -32,10 +36,15 @@ public class ImageLoadOperation: Operation {
if let data = try? Data(contentsOf: imageURL) {
// print("lazy fetch image ready \(imageURL)")
if self.isCancelled {
// print("Decoding 1 cancelled")
return
}
if let img = UIImage(data: data, scale: 1) {
if imageURL.isFileURL {
DispatchQueue.main.async {
self.succeeder(img)
}
return
}
if let decodedImg = img.decodeImage() {
if self.isCancelled {
// print("Decoding 2 cancelled")

Loading…
Cancel
Save