diff --git a/kplayer.xcodeproj/project.pbxproj b/kplayer.xcodeproj/project.pbxproj index f6f6b53..2db8be6 100644 --- a/kplayer.xcodeproj/project.pbxproj +++ b/kplayer.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 1C7361D3BA77C40275F89D4A /* TimelineMeasure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7368C7B946BC9E067D37E7 /* TimelineMeasure.swift */; }; 1C7361F376DA11F17CD3250B /* TrimView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736ABA0E14A51ACAC84AB5 /* TrimView.swift */; }; 1C73631EACF56BABD3B2BCFB /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */; }; + 1C73633AAF0D77F8AC3557B9 /* SVideoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7362603E8588B4D1A8C617 /* SVideoModel.swift */; }; 1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C736777456388CA571DA17B /* MediaPlayer.framework */; }; 1C7363D4C34EBBD5C7AAD0A8 /* scratch.txt in Resources */ = {isa = PBXBuildFile; fileRef = 1C7363E0DDA5854D55F8836E /* scratch.txt */; }; 1C73640D928DE56D35175D39 /* UploadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736260E748CF136FF37EA7 /* UploadOperation.swift */; }; @@ -101,6 +102,7 @@ 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 = ""; }; + 1C7362603E8588B4D1A8C617 /* SVideoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SVideoModel.swift; path = svideo/SVideoModel.swift; sourceTree = ""; }; 1C736260E748CF136FF37EA7 /* UploadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadOperation.swift; sourceTree = ""; }; 1C73631C96E6C860833052CA /* ItemType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemType.swift; sourceTree = ""; }; 1C736362946D7A8585B0D875 /* TimelineScroller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimelineScroller.swift; path = timeline/TimelineScroller.swift; sourceTree = ""; }; @@ -341,6 +343,7 @@ 1C73661561AD069C92FE3B15 /* TimelineView.swift */, 1C736ABA0E14A51ACAC84AB5 /* TrimView.swift */, 1C73624617102E0DEB001C25 /* SVideoPlayer.swift */, + 1C7362603E8588B4D1A8C617 /* SVideoModel.swift */, ); path = kplayer; sourceTree = ""; @@ -592,6 +595,7 @@ 1C736EC45EE7DA5F7FCE63DA /* LocalManager.swift in Sources */, 1C736A78C1F8F41E2AEEF278 /* KVideoPlayer.swift in Sources */, 1C736FF8FF423F01F880F94D /* SVideoPlayer.swift in Sources */, + 1C73633AAF0D77F8AC3557B9 /* SVideoModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/kplayer/core/MediaItem.swift b/kplayer/core/MediaItem.swift index f124756..b9fc6cd 100644 --- a/kplayer/core/MediaItem.swift +++ b/kplayer/core/MediaItem.swift @@ -10,7 +10,7 @@ import Combine /** Repräsentiert ein Item eines der festgelegten Typen. */ -class MediaItem: CustomDebugStringConvertible, ObservableObject { +class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { /** Wird durch name, path und root identifiziert. diff --git a/kplayer/detail/DetailViewController.swift b/kplayer/detail/DetailViewController.swift index 625fad4..9b0408d 100644 --- a/kplayer/detail/DetailViewController.swift +++ b/kplayer/detail/DetailViewController.swift @@ -31,7 +31,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout var showFavoritesOnly = false var collectionView: UICollectionView! - var videoplayer = false + var videoplayer = true var currentItem: MediaItem? @@ -471,20 +471,22 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout var se = selectedItem var children = detailItem!.children if videoplayer { - if selectedItem.local { - let jfile = selectedItem.playerURL!.appendingPathExtension("json") - do { - let jsonData = try Data(contentsOf: jfile) - - let items = try JSONDecoder().decode(MediaModel.self, from: jsonData) - se = MediaItem(model: items) - children = se.children - - print (String(data: jsonData, encoding: .utf8)) - } catch { - print(error) - } - } + let model = SVideoModel(allItems: children, currentSnapshot: se) + + let player = SVideoPlayer(completionHandler: { + self.dismiss(animated: true, completion: nil); + }, model: model) + player + + let pc = UIHostingController(rootView: player) + pc.view.backgroundColor = .black + let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. + navController.modalPresentationStyle = .fullScreen + navController.setNavigationBarHidden(true, animated: false) + + present(navController, animated: false, completion: nil) + + return } var pc: VideoController diff --git a/kplayer/detail/VideoController.swift b/kplayer/detail/VideoController.swift index bb5e512..9405eb0 100644 --- a/kplayer/detail/VideoController.swift +++ b/kplayer/detail/VideoController.swift @@ -29,7 +29,10 @@ protocol ItemController { class VideoController: UIViewController, ItemController, BMPlayerDelegate, EditItemDelegate { var player = BMPlayer() + + // played on startup var currentItem: MediaItem? + var currentSnapshot: MediaItem? var allItems = [MediaItem]() var detailDelegate: DetailDelegate? @@ -148,16 +151,6 @@ class VideoController: UIViewController, ItemController, BMPlayerDelegate, EditI make.right.equalToSuperview() make.top.equalToSuperview() } - // player.controlView.topWrapperView.addSubview(hc!.view) - - // player.controlView.setNeedsLayout() - // player.controlView.layoutIfNeeded() - - // let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack. -// navController.modalPresentationStyle = .popover - - // present(navController, animated: false, completion: nil) - } func captureZoom() { diff --git a/kplayer/svideo/SVideoModel.swift b/kplayer/svideo/SVideoModel.swift new file mode 100644 index 0000000..a7c9a2c --- /dev/null +++ b/kplayer/svideo/SVideoModel.swift @@ -0,0 +1,23 @@ +// +// Created by Marco Schmickler on 28.11.21. +// Copyright (c) 2021 Marco Schmickler. All rights reserved. +// + +import Foundation +import AVKit + +class SVideoModel : ObservableObject { + var allItems : [MediaItem] + var currentSnapshot: MediaItem + + init(allItems: [MediaItem], currentSnapshot: MediaItem) { + self.allItems = allItems + self.currentSnapshot = currentSnapshot + } + + func currentPlayerItem() -> AVPlayerItem { + AVPlayerItem(asset: AVAsset(url: currentSnapshot.playerURL!)) + } + + +} diff --git a/kplayer/svideo/SVideoPlayer.swift b/kplayer/svideo/SVideoPlayer.swift new file mode 100644 index 0000000..0f3a500 --- /dev/null +++ b/kplayer/svideo/SVideoPlayer.swift @@ -0,0 +1,62 @@ +// +// Created by Marco Schmickler on 15.11.21. +// Copyright (c) 2021 Marco Schmickler. All rights reserved. +// + +import Foundation +import SwiftUI +import AVKit + +struct SVideoPlayer : View { + // url: URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")! + var player = AVQueuePlayer(items: [AVPlayerItem]()) + var completionHandler: (() -> Void)? + + var model: SVideoModel + + var body: some View { + HStack { + Button(action: { + completionHandler!() + }, label: { + Text("cancel") + }).buttonStyle(BorderlessButtonStyle()); + + ScrollView (.horizontal, showsIndicators: false) { + HStack { + ForEach(model.allItems) { item in + Button(action: { + + }) { + if item.image != nil { + Image(uiImage: item.image!) + } + else { + Image("Kirschkeks-256x256.png") + } + } + } + } + }.frame(height: 100) + + Spacer() + } + VideoPlayer(player: player) + .onAppear() { + player.removeAllItems() + player.insert(model.currentPlayerItem(), after: nil) + // Start the player going, otherwise controls don't appear + player.play() + } + .onDisappear() { + // Stop the player when the view disappears + player.pause() + } + } +} + +struct SVideoPlayer_Previews: PreviewProvider { + static var previews: some View { + SVideoPlayer(model: SVideoModel(allItems: [MediaItem](), currentSnapshot: MediaItem(name: "extern", path: "", root: "", type: ItemType.FAVROOT))) + } +}