marinofaggiana 3 years ago
parent
commit
707827101f

+ 1 - 0
Cartfile

@@ -5,6 +5,7 @@ github "FabrizioBrancati/Queuer"
 github "xmartlabs/XLForm" ~> 4.1
 github "AssistoLab/DropDown" "v2.3.13"
 
+github "https://github.com/marinofaggiana/KTVHTTPCache" "2.0.2"
 github "https://github.com/marinofaggiana/TOPasscodeViewController" "0.0.10"
 github "https://github.com/marinofaggiana/OpenSSL" "master"
 github "https://github.com/marinofaggiana/ChromaColorPicker" "master"

+ 12 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -34,6 +34,11 @@
 		F702F30125EE5D2C008F8E80 /* NYMnemonic.m in Sources */ = {isa = PBXBuildFile; fileRef = F702F2FD25EE5D2C008F8E80 /* NYMnemonic.m */; };
 		F702F30225EE5D2C008F8E80 /* english.txt in Resources */ = {isa = PBXBuildFile; fileRef = F702F2FF25EE5D2C008F8E80 /* english.txt */; };
 		F702F30825EE5D47008F8E80 /* NCPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F702F30725EE5D47008F8E80 /* NCPopupViewController.swift */; };
+		F703FFE6268CA52900FA1459 /* KTVHTTPCache.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = F70B86792642CF5300ED5349 /* KTVHTTPCache.xcframework */; };
+		F703FFE7268CA52900FA1459 /* KTVHTTPCache.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F70B86792642CF5300ED5349 /* KTVHTTPCache.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		F703FFE8268CA52900FA1459 /* KTVCocoaHTTPServer.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = F70B867E2642CF5400ED5349 /* KTVCocoaHTTPServer.xcframework */; };
+		F703FFE9268CA52900FA1459 /* KTVCocoaHTTPServer.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F70B867E2642CF5400ED5349 /* KTVCocoaHTTPServer.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		F703FFEB268CA60D00FA1459 /* NCKTVHTTPCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F703FFEA268CA60D00FA1459 /* NCKTVHTTPCache.swift */; };
 		F70460522499061800BB98A7 /* NotificationCenter+MainThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */; };
 		F70460532499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */; };
 		F70460542499095400BB98A7 /* NotificationCenter+MainThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */; };
@@ -360,10 +365,12 @@
 			dstPath = "";
 			dstSubfolderSpec = 10;
 			files = (
+				F703FFE7268CA52900FA1459 /* KTVHTTPCache.xcframework in Embed Frameworks */,
 				F70B869A2642CF5800ED5349 /* FSCalendar.xcframework in Embed Frameworks */,
 				F70B868E2642CF5600ED5349 /* UICKeyChainStore.xcframework in Embed Frameworks */,
 				F70B86982642CF5700ED5349 /* TOPasscodeViewController.xcframework in Embed Frameworks */,
 				F70B86942642CF5700ED5349 /* OpenSSL.xcframework in Embed Frameworks */,
+				F703FFE9268CA52900FA1459 /* KTVCocoaHTTPServer.xcframework in Embed Frameworks */,
 				F70B868C2642CF5600ED5349 /* Queuer.xcframework in Embed Frameworks */,
 				F70B868A2642CF5600ED5349 /* XLForm.xcframework in Embed Frameworks */,
 				F70B869C2642CF5800ED5349 /* DropDown.xcframework in Embed Frameworks */,
@@ -417,6 +424,7 @@
 		F702F2FF25EE5D2C008F8E80 /* english.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = english.txt; sourceTree = "<group>"; };
 		F702F30025EE5D2C008F8E80 /* NYMnemonic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NYMnemonic.h; sourceTree = "<group>"; };
 		F702F30725EE5D47008F8E80 /* NCPopupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPopupViewController.swift; sourceTree = "<group>"; };
+		F703FFEA268CA60D00FA1459 /* NCKTVHTTPCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCKTVHTTPCache.swift; sourceTree = "<group>"; };
 		F70460512499061800BB98A7 /* NotificationCenter+MainThread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationCenter+MainThread.swift"; sourceTree = "<group>"; };
 		F704B5E22430AA6F00632F5F /* NCCreateFormUploadConflict.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCCreateFormUploadConflict.storyboard; sourceTree = "<group>"; };
 		F704B5E42430AA8000632F5F /* NCCreateFormUploadConflict.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadConflict.swift; sourceTree = "<group>"; };
@@ -797,6 +805,7 @@
 				F70B86892642CF5600ED5349 /* XLForm.xcframework in Frameworks */,
 				F770768E263A8C3400A1BA94 /* FloatingPanel in Frameworks */,
 				F786D58D253454BF00E3DD7B /* NCCommunication in Frameworks */,
+				F703FFE6268CA52900FA1459 /* KTVHTTPCache.xcframework in Frameworks */,
 				F70B868B2642CF5600ED5349 /* Queuer.xcframework in Frameworks */,
 				F782A57B25123694007BBABD /* Realm in Frameworks */,
 				F75E57BD25BF0EC1002B72C2 /* SVGKit in Frameworks */,
@@ -804,6 +813,7 @@
 				F70B86992642CF5800ED5349 /* FSCalendar.xcframework in Frameworks */,
 				F70B86762642CF5300ED5349 /* ChromaColorPicker.xcframework in Frameworks */,
 				F72DA9B425F53E4E00B87DB1 /* SwiftRichString in Frameworks */,
+				F703FFE8268CA52900FA1459 /* KTVCocoaHTTPServer.xcframework in Frameworks */,
 				F70B86932642CF5700ED5349 /* OpenSSL.xcframework in Frameworks */,
 				F73ADD1C265546890069EA0D /* SwiftEntryKit in Frameworks */,
 				F70B868D2642CF5600ED5349 /* UICKeyChainStore.xcframework in Frameworks */,
@@ -1224,6 +1234,7 @@
 		F7A5281B254834500039CA15 /* NCViewerVideo */ = {
 			isa = PBXGroup;
 			children = (
+				F703FFEA268CA60D00FA1459 /* NCKTVHTTPCache.swift */,
 				F752011C25480387000BF3A7 /* NCViewerVideo.swift */,
 			);
 			path = NCViewerVideo;
@@ -2097,6 +2108,7 @@
 				F72CD63A25C19EBF00F46F9A /* NCAutoUpload.swift in Sources */,
 				F7DFB7F0219C5B8000680748 /* NCCreateFormUploadAssets.swift in Sources */,
 				F73B422C2476764F00A30FD3 /* NCNotification.swift in Sources */,
+				F703FFEB268CA60D00FA1459 /* NCKTVHTTPCache.swift in Sources */,
 				371B5A2E23D0B04500FAFAE9 /* NCMenu.swift in Sources */,
 				F77444F8222816D5000D5EB0 /* NCPickerViewController.swift in Sources */,
 				F72A47EC2487B06B005AD489 /* NCOperationQueue.swift in Sources */,

+ 32 - 25
iOSClient/Viewer/NCViewerImage/NCViewerImage.swift

@@ -400,39 +400,45 @@ class NCViewerImage: UIViewController {
     
     func videoPlay(metadata: tableMetadata) {
            
-        NCNetworking.shared.getVideoUrl(metadata: metadata) { url in
+        NCKTVHTTPCache.shared.startProxy(user: appDelegate.user, password: appDelegate.password, metadata: metadata)
+        
+        func play(url: URL) {
             
-            if let url = url {
-                
-                self.player = AVPlayer(url: url)
-                self.player?.isMuted = CCUtility.getAudioMute()
-                self.videoLayer = AVPlayerLayer(player: self.player)
+            self.player = AVPlayer(url: url)
+            self.player?.isMuted = CCUtility.getAudioMute()
+            self.videoLayer = AVPlayerLayer(player: self.player)
+            
+            if self.videoLayer != nil && self.currentViewerImageZoom != nil {
+            
+                self.videoLayer!.frame = self.currentViewerImageZoom!.imageView.bounds
+                self.videoLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill
                 
-                if self.videoLayer != nil && self.currentViewerImageZoom != nil {
+                self.currentViewerImageZoom!.imageView.layer.addSublayer(self.videoLayer!)
                 
-                    self.videoLayer!.frame = self.currentViewerImageZoom!.imageView.bounds
-                    self.videoLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill
-                    
-                    self.currentViewerImageZoom!.imageView.layer.addSublayer(self.videoLayer!)
-                    
-                    // At end go back to start
-                    NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: .main) { (notification) in
-                        if let item = notification.object as? AVPlayerItem, let currentItem = self.player?.currentItem, item == currentItem {
-                            self.player?.seek(to: .zero)
-                            if !self.currentMetadata.livePhoto {
-                                NCManageDatabase.shared.deleteVideoTime(metadata: self.currentMetadata)
-                            }
+                // At end go back to start
+                NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: .main) { (notification) in
+                    if let item = notification.object as? AVPlayerItem, let currentItem = self.player?.currentItem, item == currentItem {
+                        self.player?.seek(to: .zero)
+                        if !self.currentMetadata.livePhoto {
+                            NCManageDatabase.shared.deleteVideoTime(metadata: self.currentMetadata)
                         }
                     }
-                                
-                    self.rateObserver = self.player?.addObserver(self, forKeyPath: "rate", options: [], context: nil)
-                    
-                    if self.pictureInPictureOcId != metadata.ocId {
-                        self.player?.play()
-                    }
+                }
+                            
+                self.rateObserver = self.player?.addObserver(self, forKeyPath: "rate", options: [], context: nil)
+                
+                if self.pictureInPictureOcId != metadata.ocId {
+                    self.player?.play()
                 }
             }
         }
+        
+        //NCNetworking.shared.getVideoUrl(metadata: metadata) { url in
+        //            if let url = url {
+
+        if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
+            play(url: url)
+        }
     }
     
     func videoStop() {
@@ -449,6 +455,7 @@ class NCViewerImage: UIViewController {
         if rateObserver != nil {
             player?.removeObserver(self, forKeyPath: "rate")
             NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
+            NCKTVHTTPCache.shared.stopProxy(metadata: currentMetadata)
             self.rateObserver = nil
         }
                

+ 129 - 0
iOSClient/Viewer/NCViewerVideo/NCKTVHTTPCache.swift

@@ -0,0 +1,129 @@
+//
+//  NCKTVHTTPCache.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 28/10/2020.
+//  Copyright © 2020 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import UIKit
+import KTVHTTPCache
+
+class NCKTVHTTPCache: NSObject {
+    @objc static let shared: NCKTVHTTPCache = {
+        let instance = NCKTVHTTPCache()
+        instance.setupHTTPCache()
+        return instance
+    }()
+    
+    func getVideoURL(metadata: tableMetadata) -> URL? {
+        
+        if CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) {
+            
+            return URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView))
+            
+        } else {
+            
+            guard let stringURL = (metadata.serverUrl + "/" + metadata.fileName).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return nil }
+            
+            return NCKTVHTTPCache.shared.getProxyURL(stringURL: stringURL)
+        }
+    }
+    
+    func startProxy(user: String, password: String, metadata: tableMetadata) {
+        
+        guard let authData = (user + ":" + password).data(using: .utf8) else { return }
+        
+        let authValue = "Basic " + authData.base64EncodedString(options: [])
+        KTVHTTPCache.downloadSetAdditionalHeaders(["Authorization":authValue, "User-Agent":CCUtility.getUserAgent()])
+        
+        if !KTVHTTPCache.proxyIsRunning() {
+            do {
+                try KTVHTTPCache.proxyStart()
+            } catch let error {
+                print("Proxy Start error : \(error)")
+            }
+        }        
+    }
+    
+    func stopProxy(metadata: tableMetadata) {
+        
+        if KTVHTTPCache.proxyIsRunning() {
+            KTVHTTPCache.proxyStop()
+        }
+        
+        saveCache(metadata: metadata)
+    }
+    
+    func getProxyURL(stringURL: String) -> URL {
+        
+        return KTVHTTPCache.proxyURL(withOriginalURL: URL(string: stringURL))
+    }
+    
+    func getCacheCompleteFileURL(videoURL: URL?) -> URL? {
+        
+        return KTVHTTPCache.cacheCompleteFileURL(with: videoURL)
+    }
+    
+    func deleteCache(videoURL: URL?) {
+        
+        KTVHTTPCache.cacheDelete(with: videoURL)
+    }
+    
+    func saveCache(metadata: tableMetadata) {
+        
+        if !CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView:metadata.fileNameView) {
+            
+            guard let stringURL = (metadata.serverUrl + "/" + metadata.fileName).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }
+            
+            let videoURL = URL(string: stringURL)
+            guard let url = KTVHTTPCache.cacheCompleteFileURL(with: videoURL) else { return }
+            
+            CCUtility.copyFile(atPath: url.path, toPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView))
+            NCManageDatabase.shared.addLocalFile(metadata: metadata)
+            KTVHTTPCache.cacheDelete(with: videoURL)
+            
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl])
+        }
+    }
+    
+    private func setupHTTPCache() {
+        
+        KTVHTTPCache.cacheSetMaxCacheLength(NCGlobal.shared.maxHTTPCache)
+        
+        if ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil {
+            KTVHTTPCache.logSetConsoleLogEnable(true)
+        }
+        
+        do {
+            try KTVHTTPCache.proxyStart()
+        } catch let error {
+            print("Proxy Start error : \(error)")
+        }
+        
+        KTVHTTPCache.encodeSetURLConverter { (url) -> URL? in
+            print("URL Filter reviced URL : " + String(describing: url))
+            return url
+        }
+        
+        KTVHTTPCache.downloadSetUnacceptableContentTypeDisposer { (url, contentType) -> Bool in
+            print("Unsupport Content-Type Filter reviced URL : " + String(describing: url) + " " + String(describing: contentType))
+            return false
+        }
+    }
+}

+ 11 - 1
iOSClient/Viewer/NCViewerVideo/NCViewerVideo.swift

@@ -50,6 +50,8 @@ class NCViewerVideo: AVPlayerViewController {
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         
+        NCKTVHTTPCache.shared.startProxy(user: appDelegate.user, password: appDelegate.password, metadata: metadata)
+        
         func play(url: URL) {
             
             player = AVPlayer(url: url)
@@ -99,12 +101,19 @@ class NCViewerVideo: AVPlayerViewController {
             
         } else {
             
+            /*
             NCCommunication.shared.getDirectDownload(fileId: metadata.fileId) { account, url, errorCode, errorDescription in
                 
                 if let url = URL(string: url) {
                     play(url: url)
                 }
             }
+            */
+            
+            if let url = NCKTVHTTPCache.shared.getVideoURL(metadata: metadata) {
+                play(url: url)
+            }
+            
         }
     }
     
@@ -123,6 +132,7 @@ class NCViewerVideo: AVPlayerViewController {
             if rateObserverToken != nil {
                 player?.removeObserver(self, forKeyPath: "rate")
                 NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
+                NCKTVHTTPCache.shared.stopProxy(metadata: metadata)
                 self.rateObserverToken = nil
             }
         }
@@ -131,7 +141,7 @@ class NCViewerVideo: AVPlayerViewController {
     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
         
         if keyPath != nil && keyPath == "rate" {
-           // NCKTVHTTPCache.shared.saveCache(metadata: metadata)
+           NCKTVHTTPCache.shared.saveCache(metadata: metadata)
         }
     }
 }