Swift Media Player
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.
 
 
 

439 lines
15 KiB

//
// Created by Marco Schmickler on 04.06.15.
// Copyright (c) 2015 Marco Schmickler. All rights reserved.
//
import Foundation
import Nimbus
import Alamofire
/**
NIPhotoScrollView
if (NIPhotoScrollViewPhotoSizeThumbnail != photoSize) {
// Don't let minScale exceed maxScale. (If the image is smaller than the screen, we
// don't want to force it to be zoomed.)
// todo marco minScale = MIN(minScale, maxScale);
}
*/
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource {
var items = [MediaItem]()
var completionHandler: (() -> Void)?
var loadOriginal : ImageLoadOperation?
var loadNext : ImageLoadOperation?
var nextImage : UIImage?
var nextImageIndex = 0
var slide = 0
var timer: Timer?
var thumbnails: ThumbnailCache?
lazy var operationQueue: OperationQueue = {
var queue = OperationQueue()
queue.name = "Photo queue"
queue.maxConcurrentOperationCount = 1
return queue
}()
override func viewDidDisappear(_ animated: Bool) {
operationQueue.cancelAllOperations()
}
override func setChromeTitle() {
let idx = photoAlbumView.centerPageIndex
if (items.count > idx) {
let selected = items[idx]
title = "(\(idx + 1) / \(photoAlbumView.numberOfPages)) \(selected.path) \(selected.name)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(MediaPhotoController.back))
let slideButton = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(MediaPhotoController.slideShow))
navigationItem.leftBarButtonItems = [backButton, slideButton]
let playButton = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: #selector(MediaPhotoController.play))
let shotButton = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(MediaPhotoController.shot))
navigationItem.rightBarButtonItems = [playButton, shotButton]
setChromeVisibility(true, animated: true)
thumbnails = ThumbnailCache(items: items, refresh: {
() -> Void in
self.photoScrubberView.reloadData();
});
self.photoAlbumView.reloadData();
pagingScrollViewDidChangePages(photoAlbumView)
}
override func didReceiveMemoryWarning() {
print("warning")
thumbnails?.cancel()
super.didReceiveMemoryWarning()
}
@objc func shot() {
let currentItem = items[photoAlbumView.centerPageIndex]
var imageUrl = currentItem.thumbUrl!.replacingOccurrences(of: "_thumb.jpg", with: ".jpg")
imageUrl = imageUrl.replacingOccurrences(of: "?preview=true", with: "")
if imageUrl.starts(with: "file://") {
let pages = photoAlbumView.visiblePages()!
for case let page as NIPhotoScrollView in pages {
if (page.pageIndex == photoAlbumView.centerPageIndex) {
let scroll = page.value(forKey: "scrollView") as! UIScrollView
if scroll.isScrollEnabled {
currentItem.scale = Double(scroll.zoomScale)
currentItem.offset = scroll.contentOffset
currentItem.size = scroll.contentSize
let jsonFile = currentItem.path + "/" + currentItem.name.replacingOccurrences(of: ".jpg", with: ".json")
let url = FileHelper.getDocumentsDirectory().appendingPathComponent(jsonFile)
LocalManager.sharedInstance.saveFavDir(url: url, item: currentItem)
// print(currentItem.toJSON())
scroll.isScrollEnabled = false
}
else {
scroll.isScrollEnabled = true
}
}
}
}
else {
let url = NetworkManager.sharedInstance.baseurl + "/service/linkfavpic" + imageUrl
print(url)
AF.request(url).responseString {
(result) in
print("ok")
}
}
}
@objc func back() {
if let t = timer {
t.invalidate()
}
operationQueue.cancelAllOperations()
thumbnails?.cancel();
completionHandler!()
}
@objc func slideShow() {
slide += 1
if (slide > 2) {
slide = 0
}
if timer == nil {
showItem()
}
}
@objc func showItem() {
var nextItem = photoAlbumView.centerPageIndex + 1
if (nextItem >= (items).count) {
nextItem = 0
}
photoAlbumView.moveToPage(at: nextItem, animated: false);
photoScrubberView.setSelectedPhotoIndex(nextItem, animated: true)
pagingScrollViewDidChangePages(photoAlbumView)
}
@objc func play() {
let currentItem = items[photoAlbumView.centerPageIndex]
if (currentItem.type == ItemType.PICS) {
let items = currentItem
let len = items.root.count
let url = NetworkManager.sharedInstance.baseurl + "/service/listfiles" + items.root + "/" + items.path + "/" + items.name
print(items)
print(url)
AF.request(url).responseJSON {
(response) in
var im = [MediaItem]()
if let json = response.value {
for s in json as! [String] {
if s.hasSuffix(".jpg") {
let l = s.count
let name = NSURL(fileURLWithPath: s).lastPathComponent!
var pathlen = l - len - name.count
// if (pathlen > 1000) {
print(pathlen)
print(name)
print(s)
// }
if (pathlen < 2) {
pathlen = 2
}
let path = (s as NSString).substring(with: NSMakeRange(len + 1, pathlen - 2))
let folderName = NSURL(fileURLWithPath: path).lastPathComponent!
let fl = path.length()
let pfl = fl - folderName.length()
print("\(folderName) \(pfl)")
let fpath = s.substringLeft(pfl)
let i = MediaItem(name: folderName, path: fpath, root: items.root, type: ItemType.PICS)
i.thumbUrl = "\(s)?preview=true"
if !name.hasPrefix(".") {
im.append(i)
}
}
}
let pc = MediaPhotoController()
pc.items = im
pc.completionHandler = {
self.dismiss(animated: true, completion: nil);
}
let navController = UINavigationController(rootViewController: pc) // Creating a navigation controller with pc at the root of the navigation stack.
self.present(navController, animated: false, completion: nil)
}
}
return
}
let controller = VideoController()
controller.edit = false
controller.allowEdit = false
controller.currentItem = currentItem
controller.setItems(items: [currentItem])
controller.navigationItem.leftItemsSupplementBackButton = true
navigationController!.navigationBar.barTintColor = UIColor.black
navigationController!.pushViewController(controller, animated: true)
controller.completionHandler = {
() in
// NetworkManager.sharedInstance.saveItem(self.currentItem!)
self.dismiss(animated: true, completion: nil);
}
}
override func loadView() {
super.loadView()
photoAlbumView.dataSource = self
photoScrubberView.dataSource = self
isToolbarTranslucent = true
hidesChromeWhenScrolling = true
chromeCanBeHidden = true
isScrubberEnabled = true
// Toolbar Setup
let bounds = self.view.bounds;
let toolbarHeight = CGFloat(120.0)
toolbar.frame = CGRect(x: 0, y: bounds.size.height - toolbarHeight, width: bounds.size.width, height: toolbarHeight)
photoAlbumView.isZoomingAboveOriginalSizeEnabled = true;
// This title will be displayed until we get the results back for the album information.
self.title = "loading"
// self.photoAlbumView.loadingImage = UIImage(named: "Kirschkeks-256x256.png")
print("\(items.count)")
}
func photoAlbumScrollView(_ photoAlbumScrollView: NIPhotoAlbumScrollView!, photoAt photoAtIndex: Int, photoSize: UnsafeMutablePointer<NIPhotoScrollViewPhotoSize>,
isLoading: UnsafeMutablePointer<ObjCBool>, originalPhotoDimensions: UnsafeMutablePointer<CGSize>) -> UIImage! {
let newItem = items[photoAtIndex]
let u1 = URL(string: newItem.imageUrlAbsolute)
let u2 = URL(string: newItem.thumbUrlAbsolute)
if let hqURL = u1, let u5 = u2 {
var image: UIImage? = nil
var size = NIPhotoScrollViewPhotoSizeUnknown
image = thumbnails?.getThumbnail(newItem)
if image != nil {
size = NIPhotoScrollViewPhotoSizeThumbnail
isLoading[0] = false
} else {
let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in
self.photoAlbumView.didLoadPhoto(i, at: photoAtIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex)
}
let image = thumbnails?.loadThumbnail(thumbnailIndex: photoAtIndex, thumbnail: thumbnail)
}
if (image == nil) {
isLoading[0] = true
}
photoSize[0] = size
return image
} else {
print("## Invalid URL: \(newItem.imageUrlAbsolute)")
return nil
}
}
public override func pagingScrollViewDidChangePages(_ pagingScrollView: NIPagingScrollView!) {
setChromeTitle()
let currentIndex: Int = self.photoAlbumView.centerPageIndex
let hqURL = URL(string: items[currentIndex].imageUrlAbsolute)!
if let op = loadOriginal {
op.cancel()
loadOriginal = nil
}
let view2 = photoAlbumView.centerPageView() as! NIPhotoScrollView
restoreScrollState(currentIndex: currentIndex, view: view2)
if view2.photoSize() != NIPhotoScrollViewPhotoSizeOriginal {
if nextImage != nil && currentIndex == nextImageIndex {
self.photoAlbumView.didLoadPhoto(nextImage!, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal)
nextImage = nil
}
else {
let op2 = ImageLoadOperation(imageURL: hqURL, succeeder: {
i in
// self.photoAlbumView.isZoomingAboveOriginalSizeEnabled = max(i.size.height, i.size.width) <= 6000;
self.photoAlbumView.didLoadPhoto(i, at: currentIndex, photoSize: NIPhotoScrollViewPhotoSizeOriginal)
self.restoreScrollState(currentIndex: currentIndex, view: view2)
}, index: currentIndex)
loadOriginal = op2
op2.qualityOfService = QualityOfService.userInitiated
operationQueue.addOperation(op2)
}
}
if currentIndex + 1 < items.count {
if let op = loadNext {
op.cancel()
loadNext = nil
}
if let image = thumbnails?.getThumbnail(items[currentIndex+1]) {
self.photoAlbumView.didLoadPhoto(image, at: currentIndex+1, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
}
let hqURL2 = URL(string: items[currentIndex+1].imageUrlAbsolute)!
nextImage = nil
let op3 = ImageLoadOperation(imageURL: hqURL2, succeeder: {
i in
self.nextImage = i
self.nextImageIndex = currentIndex + 1
if (self.slide > 0) {
self.timer = Timer.scheduledTimer(timeInterval: Double(self.slide) / 2, target: self, selector: #selector(self.showItem), userInfo: nil, repeats: false)
} else {
self.timer = nil
}
}, index: currentIndex)
loadNext = op3
op3.qualityOfService = QualityOfService.userInitiated
operationQueue.addOperation(op3)
}
let oldIndex = currentIndex - 1;
if (oldIndex >= 0) {
let newItem = items[oldIndex]
if let image = thumbnails?.getThumbnail(newItem) {
self.photoAlbumView.didLoadPhoto(image, at: oldIndex, photoSize: NIPhotoScrollViewPhotoSizeThumbnail)
}
}
}
private func restoreScrollState(currentIndex: Int, view: NIPhotoScrollView) {
let item = items[currentIndex]
if item.scale > 0.0 {
// view.setValue(false, forKey: "zoomingIsEnabled")
let scroll = view.value(forKey: "scrollView") as! UIScrollView
scroll.zoomScale = CGFloat(item.scale)
scroll.contentSize = item.size
scroll.contentOffset = item.offset
scroll.isScrollEnabled = false
}
}
func numberOfPages(in pagingScrollView: NIPagingScrollView) -> Int {
let c = items.count
return c
}
/**
* Fetches a page that will be displayed at the given page index.
*
* You should always try to reuse pages by calling dequeueReusablePageWithIdentifier: on the
* paging scroll view before allocating a new page.
*/
func pagingScrollView(_ pagingScrollView: NIPagingScrollView, pageViewFor pageViewForIndex: Int) -> (UIView & NIPagingScrollViewPageProtocol)! {
let view = photoAlbumView.pagingScrollView(pagingScrollView, pageViewFor: pageViewForIndex) as! NIPhotoScrollView
// view.maximumScale = 2;
return view;
}
func numberOfPhotos(in photoScrubberView: NIPhotoScrubberView!) -> Int {
let c = items.count
return c
}
/**
* Fetch the thumbnail image for the given photo index.
*
* Please read and understand the performance considerations for this data source.
*/
func photoScrubberView(_ photoScrubberView: NIPhotoScrubberView!, thumbnailAt thumbnailIndex: Int) -> UIImage! {
if thumbnailIndex < 0 {
return nil
}
let thumbnail: (UIImage, Int) -> () = { (i: UIImage, thumbnailIndex: Int) in
self.photoScrubberView.didLoadThumbnail(i, at: thumbnailIndex)
}
let image = thumbnails?.loadThumbnail(thumbnailIndex: thumbnailIndex, thumbnail: thumbnail)
return image
}
}