浏览代码

Merge pull request #2409 from nextcloud/viewerMedia

Viewer media
Marino Faggiana 1 年之前
父节点
当前提交
0409f11bed

+ 1 - 1
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -144,7 +144,7 @@ extension tableMetadata {
         sharePermissionsCollaborationServices == NCGlobal.shared.permissionReadShare && classFile == NKCommon.TypeClassFile.document.rawValue
     }
 
-    var isMediaPlay: Bool {
+    var isMovie: Bool {
         return classFile == NKCommon.TypeClassFile.audio.rawValue || classFile == NKCommon.TypeClassFile.video.rawValue
     }
 

+ 2 - 2
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -1342,10 +1342,10 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             
             let imageIcon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag))
 
-            if metadata.isImage || metadata.isMediaPlay {
+            if metadata.isImage || metadata.isMovie {
                 var metadatas: [tableMetadata] = []
                 for metadata in metadataSourceForAllSections {
-                    if metadata.isImage || metadata.isMediaPlay {
+                    if metadata.isImage || metadata.isMovie {
                         metadatas.append(metadata)
                     }
                 }

+ 40 - 12
iOSClient/Main/NCPickerViewController.swift

@@ -125,15 +125,20 @@ class customPhotoPickerViewController: TLPhotosPickerViewController {
 class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate {
 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    var isViewerMedia: Bool
+    var viewController: UIViewController?
 
     @discardableResult
-    init (tabBarController: UITabBarController) {
+    init (tabBarController: UITabBarController, supportedTypes: [UTType], isViewerMedia: Bool, allowsMultipleSelection: Bool, viewController: UIViewController? = nil) {
+
+        self.isViewerMedia = isViewerMedia
+        self.viewController = viewController
         super.init()
 
-        let documentProviderMenu = UIDocumentPickerViewController(documentTypes: ["public.data"], in: .import)
+        let documentProviderMenu = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes)
 
         documentProviderMenu.modalPresentationStyle = .formSheet
-        documentProviderMenu.allowsMultipleSelection = true
+        documentProviderMenu.allowsMultipleSelection = allowsMultipleSelection
         documentProviderMenu.popoverPresentationController?.sourceView = tabBarController.tabBar
         documentProviderMenu.popoverPresentationController?.sourceRect = tabBarController.tabBar.bounds
         documentProviderMenu.delegate = self
@@ -143,15 +148,28 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate {
 
     func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
 
-        for url in urls {
+        let ocId = NSUUID().uuidString
+
+        if isViewerMedia,
+            let urlIn = urls.first,
+            let url = self.copySecurityScopedResource(url: urlIn, urlOut: FileManager.default.temporaryDirectory.appendingPathComponent(urlIn.lastPathComponent)),
+            let viewController = self.viewController {
 
             let fileName = url.lastPathComponent
-            let serverUrl = appDelegate.activeServerUrl
-            let ocId = NSUUID().uuidString
-            let atPath = url.path
-            let toPath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)!
+            let metadata = NCManageDatabase.shared.createMetadata(account: appDelegate.account, user: appDelegate.user, userId: appDelegate.userId, fileName: fileName, fileNameView: fileName, ocId: ocId, serverUrl: "", urlBase: appDelegate.urlBase, url: url.path, contentType: "")
+            NCManageDatabase.shared.addMetadata(metadata)
+            NCViewer.shared.view(viewController: viewController, metadata: metadata, metadatas: [metadata], imageIcon: nil)
+
+        } else {
+
+            for urlIn in urls {
+
+                let fileName = urlIn.lastPathComponent
+                let toPath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)!
+                let urlOut = URL(fileURLWithPath: toPath)
+                let serverUrl = appDelegate.activeServerUrl
 
-            if NCUtilityFileSystem.shared.copyFile(atPath: atPath, toPath: toPath) {
+                guard let url = self.copySecurityScopedResource(url: urlIn, urlOut: urlOut) else { continue }
 
                 let metadataForUpload = NCManageDatabase.shared.createMetadata(account: appDelegate.account, user: appDelegate.user, userId: appDelegate.userId, fileName: fileName, fileNameView: fileName, ocId: ocId, serverUrl: serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "")
 
@@ -174,11 +192,21 @@ class NCDocumentPickerViewController: NSObject, UIDocumentPickerDelegate {
                 } else {
                     NCNetworkingProcessUpload.shared.createProcessUploads(metadatas: [metadataForUpload], completion: { _ in })
                 }
+            }
+        }
+    }
+
+    func copySecurityScopedResource(url: URL, urlOut: URL) -> URL? {
 
-            } else {
-                let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_read_file_error_")
-                NCContentPresenter.shared.showError(error: error)
+        try? FileManager.default.removeItem(at: urlOut)
+        if url.startAccessingSecurityScopedResource() {
+            do {
+                try FileManager.default.copyItem(at: url, to: urlOut)
+                url.stopAccessingSecurityScopedResource()
+                return urlOut
+            } catch {
             }
         }
+        return nil
     }
 }

+ 2 - 1
iOSClient/Media/NCMedia.swift

@@ -31,6 +31,7 @@ class NCMedia: UIViewController, NCEmptyDataSetDelegate, NCSelectDelegate {
     private var emptyDataSet: NCEmptyDataSet?
     private var mediaCommandView: NCMediaCommandView?
     private var gridLayout: NCGridMediaLayout!
+    internal var documentPickerViewController: NCDocumentPickerViewController?
 
     internal let appDelegate = UIApplication.shared.delegate as! AppDelegate
 
@@ -393,7 +394,7 @@ extension NCMedia: UICollectionViewDataSource {
             cell.fileObjectId = metadata.ocId
             cell.fileUser = metadata.ownerId
 
-            if metadata.isMediaPlay {
+            if metadata.isMovie {
                 cell.imageStatus.image = cacheImages.cellPlayImage
             } else if metadata.livePhoto && livePhoto {
                 cell.imageStatus.image = cacheImages.cellLivePhotoImage

+ 1 - 1
iOSClient/Menu/AppDelegate+Menu.swift

@@ -57,7 +57,7 @@ extension AppDelegate {
             NCMenuAction(
                 title: NSLocalizedString("_upload_file_", comment: ""), icon: UIImage(named: "file")!.image(color: UIColor.systemGray, size: 50), action: { _ in
                     if let tabBarController = self.window?.rootViewController as? UITabBarController {
-                        self.documentPickerViewController = NCDocumentPickerViewController(tabBarController: tabBarController)
+                        self.documentPickerViewController = NCDocumentPickerViewController(tabBarController: tabBarController, supportedTypes: [UTType.data], isViewerMedia: false, allowsMultipleSelection: true)
                     }
                 }
             )

+ 43 - 0
iOSClient/Menu/NCMedia+Menu.swift

@@ -96,6 +96,49 @@ extension NCMedia {
                 )
             )
 
+            actions.append(.seperator(order: 0))
+
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_play_from_files_", comment: ""),
+                    icon: NCUtility.shared.loadImage(named: "play.circle"),
+                    action: { _ in
+                        if let tabBarController =  self.appDelegate.window?.rootViewController as? UITabBarController {
+                            self.documentPickerViewController = NCDocumentPickerViewController(tabBarController: tabBarController, supportedTypes: [UTType.movie], isViewerMedia: true, allowsMultipleSelection: false, viewController: self)
+                        }
+                    }
+                )
+            )
+
+            actions.append(
+                NCMenuAction(
+                    title: NSLocalizedString("_play_from_url_", comment: ""),
+                    icon: NCUtility.shared.loadImage(named: "network"),
+                    action: { _ in
+
+                        let alert = UIAlertController(title: NSLocalizedString("_valid_video_url_", comment: ""), message: nil, preferredStyle: .alert)
+                        alert.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel, handler: nil))
+
+                        alert.addTextField(configurationHandler: { textField in
+                            textField.placeholder = "http://myserver.com/movie.mkv"
+                        })
+
+                        alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in
+                            guard let stringUrl = alert.textFields?.first?.text, !stringUrl.isEmpty, let url = URL(string: stringUrl) else { return }
+                            let fileName = url.lastPathComponent
+                            let metadata = NCManageDatabase.shared.createMetadata(account: self.appDelegate.account, user: self.appDelegate.user, userId: self.appDelegate.userId, fileName: fileName, fileNameView: fileName, ocId: NSUUID().uuidString, serverUrl: "", urlBase: self.appDelegate.urlBase, url: stringUrl, contentType: "")
+                            NCManageDatabase.shared.addMetadata(metadata)
+                            NCViewer.shared.view(viewController: self, metadata: metadata, metadatas: [metadata], imageIcon: nil)
+                        }))
+
+                        self.present(alert, animated: true)
+
+                    }
+                )
+            )
+
+            actions.append(.seperator(order: 0))
+
             actions.append(
                 NCMenuAction(
                     title: NSLocalizedString("_media_by_modified_date_", comment: ""),

+ 12 - 6
iOSClient/Networking/NCNetworking.swift

@@ -1535,20 +1535,26 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     // MARK: - Direct Download
 
-    func getVideoUrl(metadata: tableMetadata, completition: @escaping (_ url: URL?) -> Void) {
+    func getVideoUrl(metadata: tableMetadata, completition: @escaping (_ url: URL?, _ autoplay: Bool) -> Void) {
 
-        if CCUtility.fileProviderStorageExists(metadata) {
-            completition(URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)))
+        if !metadata.url.isEmpty {
+            if metadata.url.hasPrefix("/") {
+                completition(URL(fileURLWithPath: metadata.url), true)
+            } else {
+                completition(URL(string: metadata.url), true)
+            }
+        } else if CCUtility.fileProviderStorageExists(metadata) {
+            completition(URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)), false)
         } else {
             NextcloudKit.shared.getDirectDownload(fileId: metadata.fileId) { account, url, data, error in
                 if error == .success && url != nil {
                     if let url = URL(string: url!) {
-                        completition(url)
+                        completition(url, false)
                     } else {
-                        completition(nil)
+                        completition(nil, false)
                     }
                 } else {
-                    completition(nil)
+                    completition(nil, false)
                 }
             }
         }

+ 3 - 1
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -939,7 +939,9 @@
 "_creation_"                = "Creation";
 "_modified_"                = "Modified";
 "_group_folders_"           = "Group folders";
-
+"_play_from_files_"         = "Play movie by Files";
+"_play_from_url_"           = "Play movie by URL";
+"_valid_video_url_"         = "Insert a valid URL";
 
 // Video
 "_select_trace_"            = "Select the trace";

+ 1 - 1
iOSClient/Viewer/NCViewer.swift

@@ -69,7 +69,7 @@ class NCViewer: NSObject {
         }
 
         // IMAGE AUDIO VIDEO
-        if metadata.isImage || metadata.isMediaPlay {
+        if metadata.isImage || metadata.isMovie {
 
             if let navigationController = viewController.navigationController {
 

+ 4 - 2
iOSClient/Viewer/NCViewerMedia/NCPlayer/NCPlayer.swift

@@ -66,7 +66,7 @@ class NCPlayer: NSObject {
         NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidEnterBackground), object: nil)
     }
 
-    func openAVPlayer(url: URL) {
+    func openAVPlayer(url: URL, autoplay: Bool = false) {
 
         let userAgent = CCUtility.getUserAgent()!
         var positionSliderToolBar: Float = 0
@@ -98,7 +98,9 @@ class NCPlayer: NSObject {
         playerToolBar?.setBarPlayer(ncplayer: self, position: positionSliderToolBar, metadata: metadata, viewerMediaPage: viewerMediaPage)
 
         player?.play()
-        player?.pause()
+        if !autoplay {
+            player?.pause()
+        }
 
         NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterApplicationDidEnterBackground), object: nil)
     }

+ 5 - 5
iOSClient/Viewer/NCViewerMedia/NCViewerMedia.swift

@@ -88,7 +88,7 @@ class NCViewerMedia: UIViewController {
             statusLabel.text = ""
         }
         
-        if metadata.isMediaPlay {
+        if metadata.isMovie {
 
             playerToolBar = Bundle.main.loadNibNamed("NCPlayerToolBar", owner: self, options: nil)?.first as? NCPlayerToolBar
             if let playerToolBar = playerToolBar {
@@ -145,7 +145,7 @@ class NCViewerMedia: UIViewController {
 
             viewerMediaPage?.navigationController?.setNavigationBarHidden(false, animated: true)
 
-            if metadata.isMediaPlay {
+            if metadata.isMovie {
                 viewerMediaPage?.view.backgroundColor = .black
                 viewerMediaPage?.textColor = .white
             } else {
@@ -171,14 +171,14 @@ class NCViewerMedia: UIViewController {
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
 
-        if metadata.isMediaPlay {
+        if metadata.isMovie {
 
             if let ncplayer = self.ncplayer {
 
                 if ncplayer.url == nil {
-                    NCNetworking.shared.getVideoUrl(metadata: metadata) { url in
+                    NCNetworking.shared.getVideoUrl(metadata: metadata) { url, autoplay in
                         if let url = url {
-                            ncplayer.openAVPlayer(url: url)
+                            ncplayer.openAVPlayer(url: url, autoplay: autoplay)
                             self.viewerMediaPage?.updateCommandCenter(ncplayer: ncplayer, metadata: self.metadata)
                         }
                     }

+ 11 - 7
iOSClient/Viewer/NCViewerMedia/NCViewerMediaPage.swift

@@ -93,7 +93,11 @@ class NCViewerMediaPage: UIViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
 
-        navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "more")!.image(color: .label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
+        if metadatas.count == 1, let metadata = metadatas.first, !metadata.url.isEmpty {
+            // it's a video from URL
+        } else {
+            navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "more")!.image(color: .label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
+        }
 
         singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSingleTapWith(gestureRecognizer:)))
         panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didPanWith(gestureRecognizer:)))
@@ -214,7 +218,7 @@ class NCViewerMediaPage: UIViewController {
             hideStatusBar = false
             progressView.isHidden = false
 
-            if metadatas[currentIndex].isMediaPlay {
+            if metadatas[currentIndex].isMovie {
                 currentViewController.playerToolBar?.show()
                 view.backgroundColor = .black
                 textColor = .white
@@ -231,7 +235,7 @@ class NCViewerMediaPage: UIViewController {
             hideStatusBar = true
             progressView.isHidden = true
 
-            if metadatas[currentIndex].isMediaPlay {
+            if metadatas[currentIndex].isMovie {
                 currentViewController.playerToolBar?.hide()
             }
 
@@ -256,7 +260,7 @@ class NCViewerMediaPage: UIViewController {
 
     @objc func autoHide() {
 
-        if metadatas[currentIndex].isMediaPlay, viewerMediaScreenMode == .normal {
+        if metadatas[currentIndex].isMovie, viewerMediaScreenMode == .normal {
             changeScreenMode(mode: .full)
         }
     }
@@ -275,7 +279,7 @@ class NCViewerMediaPage: UIViewController {
         let metadata = metadatas[currentIndex]
 
         if metadata.ocId == ocId,
-           metadata.isMediaPlay,
+           metadata.isMovie,
            CCUtility.fileProviderStorageExists(metadata),
            let ncplayer = currentViewController.ncplayer {
             let url = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!)
@@ -430,8 +434,8 @@ class NCViewerMediaPage: UIViewController {
             return .commandFailed
         }
 
-        // VIDEO / AUDIO () ()
-        if metadata.isMediaPlay {
+        // VIDEO AUDIO () ()
+        if metadata.isMovie {
 
             MPRemoteCommandCenter.shared().skipForwardCommand.isEnabled = true
             skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { event in

+ 1 - 1
iOSClient/Viewer/NCViewerProviderContextMenu.swift

@@ -100,7 +100,7 @@ class NCViewerProviderContextMenu: UIViewController {
             }
 
             // AUTO DOWNLOAD VIDEO / AUDIO
-            if !CCUtility.fileProviderStorageExists(metadata) && metadata.isMediaPlay {
+            if !CCUtility.fileProviderStorageExists(metadata) && metadata.isMovie {
 
                 var maxDownload: UInt64 = 0