From 46d18b95b697ecf2ce65d5e048b5ba90121fd6c0 Mon Sep 17 00:00:00 2001 From: marcoschmickler Date: Fri, 19 Nov 2021 20:33:33 +0100 Subject: [PATCH] Local Files extern --- kplayer.xcodeproj/project.pbxproj | 4 ++ kplayer/core/MediaItem.swift | 1 - kplayer/detail/EditItemView.swift | 69 +++++++++++++--------- kplayer/detail/VideoController.swift | 88 +++++++++++++++------------- kplayer/video/BMPlayer.swift | 4 ++ 5 files changed, 96 insertions(+), 70 deletions(-) diff --git a/kplayer.xcodeproj/project.pbxproj b/kplayer.xcodeproj/project.pbxproj index 1581f6e..f6f6b53 100644 --- a/kplayer.xcodeproj/project.pbxproj +++ b/kplayer.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ 1C736F6A223D4ADB2E1BA733 /* ItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736069C214E9522BB1BD97 /* ItemCell.swift */; }; 1C736FAE5D3E5D3BA3C1FAE5 /* links.html in Resources */ = {isa = PBXBuildFile; fileRef = 1C73645DBD6499A726D34973 /* links.html */; }; 1C736FB92B19FE17E4357C85 /* MediaItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73688DAB88F9360FB62A49 /* MediaItem.swift */; }; + 1C736FF8FF423F01F880F94D /* SVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73624617102E0DEB001C25 /* SVideoPlayer.swift */; }; AA74B07A01F0E99E6DEC7D1B /* Pods_kplayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B75159FFCD5A882E6F167FE /* Pods_kplayer.framework */; }; C98AF5D51B124D6A00D196CC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D41B124D6A00D196CC /* AppDelegate.swift */; }; C98AF5D81B124D6A00D196CC /* kplayer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = C98AF5D61B124D6A00D196CC /* kplayer.xcdatamodeld */; }; @@ -97,6 +98,7 @@ 1C73615FFA2AA98BD1C56CD4 /* links.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = links.html; sourceTree = ""; }; 1C7361C26ED27AB54594317D /* CenterLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CenterLine.swift; path = timeline/CenterLine.swift; sourceTree = ""; }; 1C73620D01687FB4F1811C5C /* NetworkHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkHelper.swift; sourceTree = ""; }; + 1C73624617102E0DEB001C25 /* SVideoPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SVideoPlayer.swift; path = svideo/SVideoPlayer.swift; sourceTree = ""; }; 1C73625012D50E457D18A785 /* kplayer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = kplayer.js; sourceTree = ""; }; 1C736253AB7A95EA41B605B7 /* ItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemModel.swift; sourceTree = ""; }; 1C736260E748CF136FF37EA7 /* UploadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadOperation.swift; sourceTree = ""; }; @@ -338,6 +340,7 @@ 1C736362946D7A8585B0D875 /* TimelineScroller.swift */, 1C73661561AD069C92FE3B15 /* TimelineView.swift */, 1C736ABA0E14A51ACAC84AB5 /* TrimView.swift */, + 1C73624617102E0DEB001C25 /* SVideoPlayer.swift */, ); path = kplayer; sourceTree = ""; @@ -588,6 +591,7 @@ 1C73613562EB375F53A0BD03 /* ServerDownloadDelegate.swift in Sources */, 1C736EC45EE7DA5F7FCE63DA /* LocalManager.swift in Sources */, 1C736A78C1F8F41E2AEEF278 /* KVideoPlayer.swift in Sources */, + 1C736FF8FF423F01F880F94D /* SVideoPlayer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/kplayer/core/MediaItem.swift b/kplayer/core/MediaItem.swift index 98edee4..f124756 100644 --- a/kplayer/core/MediaItem.swift +++ b/kplayer/core/MediaItem.swift @@ -132,7 +132,6 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject { children = [MediaItem]() sortName = computeSortName(name) - length = 5.0 } fileprivate func computeSortName(_ sname: String) -> String { diff --git a/kplayer/detail/EditItemView.swift b/kplayer/detail/EditItemView.swift index fa65936..faeea4f 100644 --- a/kplayer/detail/EditItemView.swift +++ b/kplayer/detail/EditItemView.swift @@ -6,52 +6,65 @@ import Foundation import SwiftUI +protocol EditItemDelegate { + func captureZoom() + func setStart() + func setEnd() + func seek(_ : Double) +} + struct EditItemView: View { @ObservedObject var item: MediaItem var len: Double - var seek: (Double) -> Void - var capture: (MediaItem) -> Void + var delegate: EditItemDelegate var body: some View { Form { Section(header: Text("K Settings")) { - VStack { - Slider(value: Binding( - get: { item.time }, - set: { - item.time = $0 - seek(item.time) - } - ), in: 0...len) + VStack() { + HStack() { + Slider(value: Binding( + get: { item.time }, + set: { + item.time = $0 + delegate.seek(item.time) + } + ), in: 0...len) + Button(action: delegate.setStart, label: { + Text("Start") + }).buttonStyle(BorderlessButtonStyle()); + } Text("Start \(item.time, specifier: "%.1f") Length \(item.length, specifier: "%.1f")") - Slider(value: Binding( - get: { item.length }, - set: { - item.length = $0 - seek(item.time + item.length) - } - ), in: 1...500) + HStack { + Slider(value: Binding( + get: { item.length }, + set: { + item.length = $0 + delegate.seek(item.time + item.length) + } + ), in: 1...500) + Button(action: delegate.setEnd, label: { + Text("End") + }).buttonStyle(BorderlessButtonStyle()); + } Toggle(isOn: $item.loop, label: { Text("Loop") }) Text("Zoom \(item.scale, specifier: "%.1f") X \(item.offset.x, specifier: "%.1f") Y \(item.offset.y, specifier: "%.1f") ") HStack { + Button(action: delegate.captureZoom, label: { + Text("Zoom") + }).buttonStyle(BorderlessButtonStyle()); Button(action: { - capture(item) + item.scale = 1.0 + item.offset = CGPoint(x: 0,y: 0) item.objectWillChange.send() }, label: { - Text("Zoom") - }); -// Button(action: { -// item.scale = 1.0 -// item.offset = CGPoint(x: 0,y: 0) -// item.objectWillChange.send() -// }, label: { -// Text("Reset") -// }); + Text("Reset") + }).buttonStyle(BorderlessButtonStyle()); } }.background(Color.clear) }.background(Color.clear) @@ -69,7 +82,7 @@ struct EditItemView: View { struct EditItemView_Previews: PreviewProvider { static var previews: some View { - EditItemView(item: MediaItem(name: "extern", path: "", root: "", type: ItemType.FAVROOT), len: 1000, seek: { v in }, capture: { v in }) + EditItemView(item: MediaItem(name: "extern", path: "", root: "", type: ItemType.FAVROOT), len: 1000, delegate: VideoController()) } } diff --git a/kplayer/detail/VideoController.swift b/kplayer/detail/VideoController.swift index eb0f740..0cfc039 100644 --- a/kplayer/detail/VideoController.swift +++ b/kplayer/detail/VideoController.swift @@ -27,7 +27,7 @@ protocol ItemController { // Trimmer: https://github.com/Tomohiro-Yamashita/VideoTimelineView -class VideoController: UIViewController, ItemController, BMPlayerDelegate { +class VideoController: UIViewController, ItemController, BMPlayerDelegate, EditItemDelegate { var player = BMPlayer() var currentItem: MediaItem? var currentSnapshot: MediaItem? @@ -120,14 +120,11 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { totalTime = 1000 } - let kv = EditItemView(item: currentSnapshot!, len: totalTime, seek: - { value in - print(value) - self.player.seekSmoothlyToTime(newChaseTime: value) - }, capture: { item in - item.scale = Double(self.player.zoom) - item.offset = CGPoint(x: self.player.xpos, y: self.player.ypos) - }) + if (currentSnapshot!.length < 0.001) { + setEnd() + } + + let kv = EditItemView(item: currentSnapshot!, len: totalTime, delegate: self) let pc = UIHostingController(rootView: kv) pc.view.backgroundColor = .clear @@ -138,6 +135,41 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { } + func captureZoom() { + if let item = currentSnapshot { + item.scale = Double(self.player.zoom) + item.offset = CGPoint(x: self.player.xpos, y: self.player.ypos) + } + } + + func setStart() { + if let item = currentSnapshot { + let ctime = currentTime() + + item.time = ctime + + item.objectWillChange.send() + } + } + + private func currentTime() -> Double { + CMTimeGetSeconds(player.playerLayer!.playerItem!.currentTime()) + } + + func setEnd() { + if let item = currentSnapshot { + let ctime = currentTime() + + if (ctime > item.time) { + item.length = ctime - item.time + item.objectWillChange.send() + } + } + } + + func seek(_ value: Double) { + self.player.seekSmoothlyToTime(newChaseTime: value) + } override var prefersStatusBarHidden: Bool { return true @@ -407,11 +439,6 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { } - func playerItemDidReachEnd(_ note: Notification) { - print("finish") - // Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(update), userInfo: nil, repeats: false) - } - func addItemButton(_ newItem: MediaItem) { let frame = CGRect(x: 0, y: 0, width: 66.0, height: 44.0); @@ -448,19 +475,18 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { @objc func thumbnailClicked(_ source: UIButton) { if let currentSnapshot = buttons[source] { - gotoSnapshot(currentSnapshot: currentSnapshot) - if (edit) { + self.currentSnapshot = currentSnapshot editItem() } + else { + gotoSnapshot(currentSnapshot: currentSnapshot) + } } - // moviePlayer!.currentPlaybackRate = Float(speedOptions[speedOption]) - - // print("goto \(buttons[source]!.time!) is \(moviePlayer!.currentPlaybackTime)") } private func gotoSnapshot(currentSnapshot: MediaItem) { - player.seekSmoothlyToTime(newChaseTime: currentSnapshot.time) + player.forceSeekSmoothlyToTime(newChaseTime: currentSnapshot.time) loopStart = currentSnapshot.time player.loopEnd = loopStart + currentSnapshot.length @@ -475,7 +501,6 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { } @objc func update() { - reviewButton!.title = currentItem!.name if currentItem!.type == ItemType.SNAPSHOT { @@ -503,24 +528,6 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { } player.play() - - } - - func enteredFullscreen() { -// let mp = UIApplication.shared.keyWindow; -// if let moviePlayerContainer = mp!.recursiveSearchForViewWithName("MPVideoContainerView") { -// if (moviePlayerContainer.gestureRecognizers != nil) { -// return; -// } -// installGestures(moviePlayerContainer) -// } - } - - func exitedFullscreen() { -// moviePlayer!.view.removeFromSuperview(); -// moviePlayer = nil; -// NotificationCenter.default.removeObserver(self); - } func installGestures(_ moviePlayer: UIView) { @@ -759,8 +766,7 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate { func bmPlayer(player: BMPlayer, playTimeDidChange currentTime: TimeInterval, totalTime: TimeInterval) { if loopMode { if currentTime > player.loopEnd && loopStart < player.loopEnd { - player.chaseTime = CMTime.zero - player.seekSmoothlyToTime(newChaseTime: loopStart) + player.forceSeekSmoothlyToTime(newChaseTime: loopStart) } } diff --git a/kplayer/video/BMPlayer.swift b/kplayer/video/BMPlayer.swift index b3c72a2..e89e1b0 100644 --- a/kplayer/video/BMPlayer.swift +++ b/kplayer/video/BMPlayer.swift @@ -316,6 +316,10 @@ open class BMPlayer: UIView { } // https://gist.github.com/shaps80/ac16b906938ad256e1f47b52b4809512 + public func forceSeekSmoothlyToTime(newChaseTime: Double) { + chaseTime = CMTime.zero + seekSmoothlyToTime(newChaseTime: CMTime(value: Int64(newChaseTime * 10000), timescale: CMTimeScale(10000))) + } public func seekSmoothlyToTime(newChaseTime: Double) { seekSmoothlyToTime(newChaseTime: CMTime(value: Int64(newChaseTime * 10000), timescale: CMTimeScale(10000))) }