You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
12 KiB
336 lines
12 KiB
//
|
|
// Created by Marco Schmickler on 2018-11-01.
|
|
// Copyright (c) 2018 Marco Schmickler. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import WebBrowser
|
|
import WebKit
|
|
import Alamofire
|
|
import SwiftUI
|
|
|
|
protocol DownloadDelegate {
|
|
func killFFMPEG()
|
|
|
|
func dlserverlen(result: @escaping (String) -> ())
|
|
func download(url: URL, path: String, result: @escaping (URL) -> () )
|
|
func downloadToServer(path: String, url: URL, result: @escaping (String) -> ())
|
|
|
|
func inProgress() -> Int
|
|
}
|
|
|
|
protocol ItemController {
|
|
func setCurrentItem(item: MediaItem)
|
|
func setItems(items: [MediaItem])
|
|
func setCompletionHandler(handler: @escaping (() -> Void))
|
|
}
|
|
|
|
class BrowserController : UIViewController, ItemController, WebBrowserDelegate, UINavigationControllerDelegate, WKScriptMessageHandler, WKHTTPCookieStoreObserver {
|
|
var completionHandler: (() -> Void)?
|
|
|
|
var currentItem : MediaItem?
|
|
|
|
var web : WebBrowserViewController?
|
|
|
|
var dl = false
|
|
|
|
func setItems(items: [MediaItem]) {
|
|
|
|
}
|
|
|
|
func setCurrentItem(item: MediaItem) {
|
|
currentItem = item
|
|
}
|
|
|
|
func setCompletionHandler(handler: @escaping (() -> Void)) {
|
|
completionHandler = handler
|
|
}
|
|
|
|
func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
|
|
cookieStore.getAllCookies { cookies in
|
|
print(cookies)
|
|
}
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
|
|
let preferences = WKPreferences()
|
|
preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
|
|
|
|
let config = WKWebViewConfiguration()
|
|
config.preferences = preferences
|
|
config.allowsInlineMediaPlayback = true
|
|
config.allowsAirPlayForMediaPlayback = false
|
|
config.userContentController.add(self, name: "openDocument")
|
|
config.userContentController.add(self, name: "jsError")
|
|
config.setValue(true, forKey: "_allowUniversalAccessFromFileURLs")
|
|
|
|
if (currentItem!.name.contains(".x")) {
|
|
config.websiteDataStore = WKWebsiteDataStore.nonPersistent()
|
|
}
|
|
config.websiteDataStore.httpCookieStore.add(self)
|
|
|
|
let cookiesStore = config.websiteDataStore.httpCookieStore
|
|
let cookieProps: [HTTPCookiePropertyKey : Any] = [
|
|
HTTPCookiePropertyKey.domain: "URL",
|
|
HTTPCookiePropertyKey.path: "/",
|
|
HTTPCookiePropertyKey.name: "key",
|
|
HTTPCookiePropertyKey.value: "value",
|
|
HTTPCookiePropertyKey.secure: "TRUE",
|
|
HTTPCookiePropertyKey.expires: NSDate(timeIntervalSinceNow: 209000)
|
|
]
|
|
cookiesStore.setCookie(HTTPCookie(properties: cookieProps)!)
|
|
|
|
let webBrowserViewController = WebBrowserViewController(configuration: config)
|
|
web = webBrowserViewController
|
|
web?.getWKWebView().customUserAgent = "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5";
|
|
|
|
webBrowserViewController.delegate = self
|
|
|
|
webBrowserViewController.language = .english
|
|
// webBrowserViewController.tintColor = ...
|
|
// webBrowserViewController.barTintColor = ...
|
|
webBrowserViewController.isToolbarHidden = false
|
|
webBrowserViewController.isShowActionBarButton = false
|
|
webBrowserViewController.toolbarItemSpace = 50
|
|
webBrowserViewController.isShowURLInNavigationBarWhenLoading = true
|
|
webBrowserViewController.isShowPageTitleInNavigationBar = true
|
|
|
|
// webBrowserViewController.customApplicationActivities = ...
|
|
webBrowserViewController.loadURLString(currentItem!.name)
|
|
webBrowserViewController.onOpenExternalAppHandler = { [weak self] _ in
|
|
guard let `self` = self else { return }
|
|
self.completionHandler!()
|
|
//self.navigationController?.popViewController(animated: true)
|
|
}
|
|
let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(BrowserController.back(_:)))
|
|
let closeButton = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(BrowserController.close(_:)))
|
|
webBrowserViewController.navigationItem.leftBarButtonItems = [backButton, closeButton]
|
|
|
|
let reviewButton = UIBarButtonItem(title:"download", style:UIBarButtonItem.Style.plain, target: self, action: #selector(BrowserController.doDownload(_:)))
|
|
let dlButton = UIBarButtonItem(title:"server", style:UIBarButtonItem.Style.plain, target: self, action: #selector(BrowserController.doServerDownload(_:)))
|
|
|
|
webBrowserViewController.navigationItem.rightBarButtonItems = [dlButton, reviewButton]
|
|
|
|
navigationController?.delegate = self
|
|
navigationController?.pushViewController(webBrowserViewController, animated: true)
|
|
// present(webBrowserViewController, animated: false)
|
|
}
|
|
|
|
@objc public func doDownload(_ sender: AnyObject) {
|
|
dl=false
|
|
executeDocumentDownloadScript(webView: web!.getWKWebView(), forAbsoluteUrl: "hello")
|
|
}
|
|
|
|
@objc public func doServerDownload(_ sender: AnyObject) {
|
|
dl=true
|
|
executeDocumentDownloadScript(webView: web!.getWKWebView(), forAbsoluteUrl: "hello")
|
|
}
|
|
|
|
@IBAction func close(_ sender: AnyObject) {
|
|
completionHandler!()
|
|
}
|
|
|
|
@IBAction func back(_ sender: AnyObject) {
|
|
if (web!.getWKWebView().canGoBack) {
|
|
web!.getWKWebView().goBack()
|
|
web!.updateToolBarState()
|
|
}
|
|
else {
|
|
completionHandler!()
|
|
}
|
|
}
|
|
|
|
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
debugPrint("did receive message \(message.name)")
|
|
|
|
|
|
if (message.name == "openDocument") {
|
|
do {
|
|
let data = (message.body as! String).data(using: .utf8)
|
|
let jsonObject = try JSONSerialization.jsonObject(with: data!, options: [])
|
|
handleDocument(jsonObject as! [String])
|
|
} catch {
|
|
}
|
|
|
|
|
|
|
|
} else if (message.name == "jsError") {
|
|
debugPrint(message.body as! String)
|
|
}
|
|
}
|
|
|
|
private func handleDocument(_ strings: [String]) {
|
|
print(strings)
|
|
|
|
let alertController = UIAlertController(title: "Download", message: "Videos found", preferredStyle: .alert)
|
|
|
|
NetworkManager.sharedInstance.dlserverlen { c in
|
|
alertController.title = "On Server: \(c)";
|
|
}
|
|
|
|
for s in strings {
|
|
var name = s
|
|
if let u = URL(string: s) {
|
|
name = u.lastPathComponent
|
|
if s.contains("720") {
|
|
name = name + "720 "
|
|
}
|
|
if s.contains("1080") {
|
|
name = name + "1080 "
|
|
}
|
|
if s.contains("480") {
|
|
name = name + "480 "
|
|
}
|
|
}
|
|
|
|
let oneAction = UIAlertAction(title: name, style: .default) { (action) in
|
|
self.preview(url: s)
|
|
}
|
|
alertController.addAction(oneAction)
|
|
}
|
|
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
|
|
}
|
|
|
|
alertController.addAction(cancelAction)
|
|
|
|
web!.present(alertController, animated: true) {
|
|
|
|
}
|
|
}
|
|
|
|
func preview(url: String) {
|
|
let url2 = URL(string: url)!
|
|
|
|
if (url2.pathExtension == "zip") {
|
|
downloadZip(url2, path: "download")
|
|
return
|
|
}
|
|
|
|
if (url2.pathExtension == "jpg") {
|
|
downloadZip(url2, path: "images/new")
|
|
return
|
|
}
|
|
|
|
let name = url2.lastPathComponent
|
|
let hostcomp = currentItem!.name.split(separator: ".")
|
|
let site = String(hostcomp[hostcomp.count-2])
|
|
|
|
if ((url2.pathExtension == "mp4" || url2.pathExtension == "m3u8") && dl) {
|
|
NetworkManager.sharedInstance.downloadToServer(path: site, url: url2, result: {
|
|
(r) in
|
|
print(r)
|
|
self.showAlert(title: "download ready", message: r)
|
|
if (r == "exists") {
|
|
|
|
}
|
|
})
|
|
return
|
|
}
|
|
|
|
let item = MediaItem(name: name, path: name, root: site, type: ItemType.VIDEO)
|
|
item.externalURL = url
|
|
showVideo(selectedItem: item)
|
|
}
|
|
|
|
|
|
func showVideo(selectedItem: MediaItem) {
|
|
var se = selectedItem
|
|
var children = [MediaItem]()
|
|
var clonedChildren = [MediaItem]()
|
|
var baseItem = selectedItem
|
|
|
|
if baseItem.type == ItemType.SNAPSHOT {
|
|
baseItem = selectedItem.parent!
|
|
}
|
|
|
|
children = baseItem.children
|
|
clonedChildren = baseItem.clone().children
|
|
|
|
let model = SVideoModel(allItems: children, currentSnapshot: se, baseItem: baseItem)
|
|
|
|
model.edit = LocalManager.sharedInstance.settings.edit
|
|
model.loop = LocalManager.sharedInstance.settings.autoloop
|
|
model.zoomed = LocalManager.sharedInstance.settings.zoomed
|
|
|
|
let player = SVideoPlayer(completionHandler: { saved in
|
|
baseItem.children = clonedChildren
|
|
|
|
self.dismiss(animated: true, completion: nil);
|
|
}, model: model)
|
|
player
|
|
|
|
let pc = UIHostingController(rootView: player)
|
|
pc.view.backgroundColor = .black
|
|
|
|
getWindow().rootViewController!.definesPresentationContext = true
|
|
pc.modalPresentationStyle = .overCurrentContext
|
|
getWindow().rootViewController!.present(pc, animated: true)
|
|
}
|
|
|
|
func getWindow() -> UIWindow {
|
|
let delegate2 = UIApplication.shared.delegate!
|
|
return delegate2.window as! UIWindow
|
|
}
|
|
|
|
private func downloadZip(_ url: URL, path: String) {
|
|
NetworkManager.sharedInstance.download(url: url, path: path) { url in
|
|
self.showAlert(title: url.lastPathComponent, message: "ready")
|
|
}
|
|
}
|
|
|
|
func webBrowser(_ webBrowser: WebBrowserViewController, didStartLoad url: URL?) {
|
|
print(url?.absoluteString)
|
|
}
|
|
|
|
func webBrowser(_ webBrowser: WebBrowserViewController, didFinishLoad url: URL?) {
|
|
}
|
|
|
|
func webBrowser(_ webBrowser: WebBrowserViewController, didFailLoad url: URL?, withError error: Error) {
|
|
}
|
|
|
|
func webBrowserWillDismiss(_ webBrowser: WebBrowserViewController) {
|
|
completionHandler!()
|
|
}
|
|
|
|
func webBrowserDidDismiss(_ webBrowser: WebBrowserViewController) {
|
|
completionHandler!()
|
|
}
|
|
|
|
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
|
|
|
|
if (animated && viewController == self) {
|
|
completionHandler!()
|
|
}
|
|
}
|
|
|
|
// func webBrowser(_ webBrowser: WebBrowserViewController, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) -> Bool {
|
|
// let url = navigationAction.request.url
|
|
// decisionHandler(.cancel)
|
|
// let closure = webBrowser.getWKWebView()
|
|
// executeDocumentDownloadScript(webView: closure, forAbsoluteUrl: url!.absoluteString)
|
|
//
|
|
// return true
|
|
// }
|
|
|
|
/*
|
|
Intercept the download of documents in webView, trigger the download in JavaScript and pass the binary file to JavaScript handler in Swift code
|
|
*/
|
|
private func executeDocumentDownloadScript(webView: WKWebView, forAbsoluteUrl absoluteUrl : String) {
|
|
// TODO: Add more supported mime-types for missing content-disposition headers
|
|
do {
|
|
let url = NetworkManager.sharedInstance.getDownloadJs()
|
|
let js = try String(contentsOf: url, encoding: .utf8)
|
|
let j = js.replacingOccurrences(of: "(absoluteUrl)", with: absoluteUrl)
|
|
webView.evaluateJavaScript(j) { (result, err) in
|
|
if (err != nil) {
|
|
debugPrint("JS ERR: \(String(describing: err))")
|
|
}
|
|
}
|
|
} catch {
|
|
print(error)
|
|
}
|
|
|
|
}
|
|
}
|