Browse Source

loop

master
marcoschmickler 4 years ago
parent
commit
88dff5596c
  1. 4
      kplayer.xcodeproj/project.pbxproj
  2. 38
      kplayer/core/NetworkManager.swift
  3. 54
      kplayer/video/SVideoLoopPlayer.swift
  4. 6
      kplayer/video/SVideoPlayer.swift

4
kplayer.xcodeproj/project.pbxproj

@ -27,6 +27,7 @@
1C73666A07CF2416B1B8D3F0 /* KSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C94157754DE1C808173 /* KSettingsModel.swift */; }; 1C73666A07CF2416B1B8D3F0 /* KSettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C94157754DE1C808173 /* KSettingsModel.swift */; };
1C736690D123BD4B24874394 /* pathfinder.scpt in Sources */ = {isa = PBXBuildFile; fileRef = 1C7369BED02028D8564E82D5 /* pathfinder.scpt */; }; 1C736690D123BD4B24874394 /* pathfinder.scpt in Sources */ = {isa = PBXBuildFile; fileRef = 1C7369BED02028D8564E82D5 /* pathfinder.scpt */; };
1C7366A0CFD2B55BF8C3BAF0 /* NetworkDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */; }; 1C7366A0CFD2B55BF8C3BAF0 /* NetworkDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364F10BED5DA0F1C0423C /* NetworkDelegate.swift */; };
1C7366FE5C760C8D5117207F /* SVideoLoopPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360F9835128FC0A198ED0 /* SVideoLoopPlayer.swift */; };
1C7367084839D2E8B180DB74 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360295486647982CFEACF /* UIViewController+Alert.swift */; }; 1C7367084839D2E8B180DB74 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7360295486647982CFEACF /* UIViewController+Alert.swift */; };
1C73671FC2CCCACAA2FFC153 /* ThumbnailCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736EA15A11AF7D57F85824 /* ThumbnailCache.swift */; }; 1C73671FC2CCCACAA2FFC153 /* ThumbnailCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736EA15A11AF7D57F85824 /* ThumbnailCache.swift */; };
1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736253AB7A95EA41B605B7 /* ItemModel.swift */; }; 1C73675C34BE0990D44570BE /* ItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736253AB7A95EA41B605B7 /* ItemModel.swift */; };
@ -95,6 +96,7 @@
1C7360A94DBECA685ED8602F /* ImageLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoadOperation.swift; sourceTree = "<group>"; }; 1C7360A94DBECA685ED8602F /* ImageLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoadOperation.swift; sourceTree = "<group>"; };
1C7360B6D0757D4FB6433E7B /* AsyncImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncImage.swift; sourceTree = "<group>"; }; 1C7360B6D0757D4FB6433E7B /* AsyncImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncImage.swift; sourceTree = "<group>"; };
1C7360F9649E40B7C2EAB581 /* kplayer.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = kplayer.txt; sourceTree = "<group>"; }; 1C7360F9649E40B7C2EAB581 /* kplayer.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = kplayer.txt; sourceTree = "<group>"; };
1C7360F9835128FC0A198ED0 /* SVideoLoopPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVideoLoopPlayer.swift; sourceTree = "<group>"; };
1C73611D226B48C24DB37535 /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.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>"; }; 1C73615FFA2AA98BD1C56CD4 /* links.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = links.html; sourceTree = "<group>"; };
1C7361F01841F546FA7AFD58 /* nspersistentcontainer-defaults-swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "nspersistentcontainer-defaults-swift.swift"; sourceTree = "<group>"; }; 1C7361F01841F546FA7AFD58 /* nspersistentcontainer-defaults-swift.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "nspersistentcontainer-defaults-swift.swift"; sourceTree = "<group>"; };
@ -282,6 +284,7 @@
1C73621E431C9BEC1440B936 /* SVideoPlayer.swift */, 1C73621E431C9BEC1440B936 /* SVideoPlayer.swift */,
1C73675F8DDFA82DEADB542E /* VideoPlayerView.swift */, 1C73675F8DDFA82DEADB542E /* VideoPlayerView.swift */,
1C73661C3F9F4E53645551AD /* KToggleButton.swift */, 1C73661C3F9F4E53645551AD /* KToggleButton.swift */,
1C7360F9835128FC0A198ED0 /* SVideoLoopPlayer.swift */,
); );
path = video; path = video;
sourceTree = "<group>"; sourceTree = "<group>";
@ -594,6 +597,7 @@
1C736C8DAD6C2FBB9A2EA625 /* SearchItemView.swift in Sources */, 1C736C8DAD6C2FBB9A2EA625 /* SearchItemView.swift in Sources */,
1C736690D123BD4B24874394 /* pathfinder.scpt in Sources */, 1C736690D123BD4B24874394 /* pathfinder.scpt in Sources */,
1C736559059B6FBA1C661191 /* KToggleButton.swift in Sources */, 1C736559059B6FBA1C661191 /* KToggleButton.swift in Sources */,
1C7366FE5C760C8D5117207F /* SVideoLoopPlayer.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

38
kplayer/core/NetworkManager.swift

@ -262,11 +262,24 @@ class NetworkManager {
if let json = response.value { if let json = response.value {
var hashes = Dictionary<String, String>() var hashes = Dictionary<String, String>()
var items : MediaModel?
for b in json as! [String] { for b in json as! [String] {
let p = NSURL(fileURLWithPath: b).lastPathComponent! let p = NSURL(fileURLWithPath: b).lastPathComponent!
if p.contains("_thumb.jpg") {
if p.contains(".json") {
do {
let enc = b.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
let jurl = NetworkManager.sharedInstance.vidurl + enc.substringStartingFrom(10)
let jsonData = try Data(contentsOf: URL(string: jurl)!)
items = try JSONDecoder().decode(MediaModel.self, from: jsonData)
}
catch {
}
}
else if p.contains("_thumb.jpg") {
let ts = p.substringWithoutLast(10) let ts = p.substringWithoutLast(10)
hashes[ts] = b hashes[ts] = b
@ -292,6 +305,18 @@ class NetworkManager {
snap.parent = item snap.parent = item
snap.loaded = true snap.loaded = true
if let ci = items {
for mic in ci.children {
if snap.indexId == mic.indexId {
if mic.length > 0 {
snap.length = mic.length
snap.scale = mic.scale
snap.offset = mic.offset
}
}
}
}
item.children.append(snap) item.children.append(snap)
} }
@ -394,6 +419,17 @@ class NetworkManager {
} }
} }
} }
do {
let j = item.snapshotDirPathForVideo + "items.json"
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(item.toMediaModel())
let op = UploadOperation(baseUrl: self.nodeurl + "upload", data: jsonData, path: j)
self.operationQueue.addOperation(op)
}
catch {
}
} }
} }

54
kplayer/video/SVideoLoopPlayer.swift

@ -0,0 +1,54 @@
//
// Created by Marco Schmickler on 03.04.22.
// Copyright (c) 2022 Marco Schmickler. All rights reserved.
//
import Foundation
import SwiftUI
import AVKit
struct SVideoLoopPlayer : View {
var completionHandler: () -> Void
var model : SVideoModel
var player = AVQueuePlayer(items: [AVPlayerItem]())
var playerLooper: AVPlayerLooper
init(completionHandler: @escaping () -> Void, baseModel: SVideoModel) {
self.completionHandler = completionHandler
self.model = SVideoModel(allItems: [], currentSnapshot: baseModel.currentSnapshot, baseItem: baseModel.baseItem)
var c = AVMutableComposition()
let tr = c.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
var currentTime = CMTime.zero
do {
var urlAsset = AVURLAsset(url: baseModel.currentSnapshot.playerURL!)
let range = CMTimeRangeMake(start: CMTime(seconds: baseModel.currentSnapshot.time, preferredTimescale: CMTimeScale(10000)), duration: CMTime(seconds: baseModel.currentSnapshot.length, preferredTimescale: CMTimeScale(10000)))
try tr!.insertTimeRange(range, of: urlAsset.tracks(withMediaType: AVMediaType.video)[0], at: CMTime.zero)
} catch {
print(error)
}
let item = AVPlayerItem(asset: c)
player.insert(item, after: nil)
self.playerLooper = AVPlayerLooper(player: player, templateItem: item)
}
var body: some View {
VideoPlayerView(model: model,
player: player)
.scaleEffect(model.scale)
.offset(model.dragOffset)
.onTapGesture(count: 2) {
completionHandler()
}.onAppear() {
player.play()
}
.onDisappear() {
player.pause()
}
}
}

6
kplayer/video/SVideoPlayer.swift

@ -207,6 +207,12 @@ struct SVideoPlayer: View, EditItemDelegate {
KToggleButton(text: "zoom", binding: $model.zoomed).frame(height: 30) KToggleButton(text: "zoom", binding: $model.zoomed).frame(height: 30)
KToggleButton(text: "loop", binding: $model.loop).frame(height: 30) KToggleButton(text: "loop", binding: $model.loop).frame(height: 30)
// .fullScreenCover(isPresented: $model.loop) {
// SVideoLoopPlayer(completionHandler: {
// model.loop = false
// }, baseModel: model)
// }
KToggleButton(text: "flip", binding: $upsidedown).frame(height: 30) KToggleButton(text: "flip", binding: $upsidedown).frame(height: 30)
Button(action: { Button(action: {

Loading…
Cancel
Save