From 4138015d71549a25a8aaa890f91fb5f9c7e66083 Mon Sep 17 00:00:00 2001 From: Marco Schmickler Date: Fri, 29 May 2015 23:04:50 +0200 Subject: [PATCH] init --- kplayer.xcodeproj/project.pbxproj | 4 +++ kplayer/DetailViewController.swift | 41 +++++++++++---------- kplayer/HeaderCell.swift | 39 ++++++++++++++++++++ kplayer/ItemCell.swift | 24 +++---------- kplayer/MasterViewController.swift | 53 +++++++++++++++++++++++++-- kplayer/VideoPlayerController.swift | 41 +++++++++++++++------ kplayer/core/MediaItem.swift | 8 ++++- kplayer/core/NetworkManager.swift | 56 +++++++++++++++++++++++++---- kplayer/core/UploadOperation.swift | 3 ++ 9 files changed, 208 insertions(+), 61 deletions(-) create mode 100644 kplayer/HeaderCell.swift diff --git a/kplayer.xcodeproj/project.pbxproj b/kplayer.xcodeproj/project.pbxproj index dad3852..4bd1559 100644 --- a/kplayer.xcodeproj/project.pbxproj +++ b/kplayer.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 1C73670791CDD5C9BB6B1DDC /* NetData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7364950C3B8C5DFA243D62 /* NetData.swift */; }; 1C7367A160B25EEC5E99A517 /* ImageLoadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736E98DC8F46C7FF9CD540 /* ImageLoadOperation.swift */; }; 1C73688D13E5A804880C8768 /* UIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */; }; + 1C73691418724950CCD87C14 /* HeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736C189E5F32219F4B4B13 /* HeaderCell.swift */; }; 1C736AD52D967F2F4000F997 /* UploadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7362F9C26405D4F3FA15A1 /* UploadOperation.swift */; }; 1C736BF3C4F2D3BE570A89C7 /* NetworkHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7368F1190278747E95C12F /* NetworkHelper.swift */; }; 1C736C90DB50C4FDED266C3D /* ItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7362C647AEBF03F5FD9FEB /* ItemCell.swift */; }; @@ -54,6 +55,7 @@ 1C73688DAB88F9360FB62A49 /* MediaItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaItem.swift; sourceTree = ""; }; 1C7368DC7EF11A553145E169 /* Kirschkeks-256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Kirschkeks-256x256.png"; sourceTree = ""; }; 1C7368F1190278747E95C12F /* NetworkHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkHelper.swift; sourceTree = ""; }; + 1C736C189E5F32219F4B4B13 /* HeaderCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderCell.swift; sourceTree = ""; }; 1C736DCCE3AA9993E15F7652 /* UIImageExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageExtension.swift; sourceTree = ""; }; 1C736E98DC8F46C7FF9CD540 /* ImageLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoadOperation.swift; sourceTree = ""; }; 5C6CBA548F885BF342F594EA /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -169,6 +171,7 @@ 1C7368DC7EF11A553145E169 /* Kirschkeks-256x256.png */, 1C7366EF59D75216EBC0D3F0 /* VideoPlayerController.swift */, 1C7365603CAE04E39B73D843 /* util */, + 1C736C189E5F32219F4B4B13 /* HeaderCell.swift */, ); path = kplayer; sourceTree = ""; @@ -365,6 +368,7 @@ 1C73664F657BE51633B69851 /* alamojson.swift in Sources */, 1C7367A160B25EEC5E99A517 /* ImageLoadOperation.swift in Sources */, 1C73688D13E5A804880C8768 /* UIImageExtension.swift in Sources */, + 1C73691418724950CCD87C14 /* HeaderCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/kplayer/DetailViewController.swift b/kplayer/DetailViewController.swift index b0d2b13..69542bf 100644 --- a/kplayer/DetailViewController.swift +++ b/kplayer/DetailViewController.swift @@ -73,8 +73,8 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout collectionView.dataSource = self collectionView.delegate = self collectionView.registerClass(ItemCell.self, forCellWithReuseIdentifier: "Cell") - collectionView.backgroundColor = UIColor.greenColor() - collectionView.registerClass(ItemCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderView"); + collectionView.backgroundColor = UIColor.lightGrayColor() + collectionView.registerClass(HeaderCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderView"); view.addSubview(collectionView) view.autoresizesSubviews = true @@ -95,19 +95,22 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout let index = notification.object as! Int if let detail: MediaItem = self.detailItem { - collectionView.performBatchUpdates( { - let path = NSIndexPath(forItem: 0, inSection: index) - self.collectionView.reloadItemsAtIndexPaths([path]) - + collectionView.performBatchUpdates({ var newItems = [NSIndexPath]() var j = 0 - for i in detail.children[index].children { - if j >= 1 { - newItems.append(NSIndexPath(forItem: j, inSection: index)) + + if count(detail.children) > index { + let path = NSIndexPath(forItem: 0, inSection: index) + self.collectionView.reloadItemsAtIndexPaths([path]) + + for i in detail.children[index].children { + if j >= 1 { + newItems.append(NSIndexPath(forItem: j, inSection: index)) + } + j++ } - j++ + self.collectionView.insertItemsAtIndexPaths(newItems) } - self.collectionView.insertItemsAtIndexPaths(newItems) return }, completion: nil) } @@ -125,8 +128,8 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout println("couldn't find index path"); } else { if let detail: MediaItem = self.detailItem { - if (detail.loaded) { - let items = detail.children[indexPath!.section] + let items = detail.children[indexPath!.section] + if (items.loaded) { if count(items.children) == 0 { } else { if indexPath!.item >= count(items.children) { @@ -155,7 +158,6 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { if let detail: MediaItem = self.detailItem { let cnt = count(detail.children) - println(cnt) return cnt } return 0 @@ -168,7 +170,6 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout if n == 0 { return 1 } - println(n) return n } return 0 @@ -190,7 +191,6 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout } } } - cell.backgroundColor = UIColor.blueColor() return cell } @@ -203,11 +203,10 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "HeaderView", forIndexPath: indexPath) - as! ItemCell + as! HeaderCell let items = detailItem!.children[indexPath.section] - headerView.label.text = items.name - headerView.backgroundColor = UIColor.yellowColor() + headerView.setItem(items) return headerView default: assert(false, "Unexpected element kind") @@ -216,8 +215,8 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { if let detail: MediaItem = self.detailItem { - if (detail.loaded) { - var items = detail.children[indexPath.section] + var items = detail.children[indexPath.section] + if (items.loaded) { if indexPath.item >= count(items.children) { println(items.name) } else { diff --git a/kplayer/HeaderCell.swift b/kplayer/HeaderCell.swift new file mode 100644 index 0000000..58db079 --- /dev/null +++ b/kplayer/HeaderCell.swift @@ -0,0 +1,39 @@ +// +// Created by Marco Schmickler on 25.05.15. +// Copyright (c) 2015 Marco Schmickler. All rights reserved. +// + +import Foundation +import UIKit +import Haneke + +class HeaderCell: UICollectionViewCell { + var item: MediaItem? + + var label: UILabel! + + required init(coder aDecoder: NSCoder) + { + super.init(coder: aDecoder) + } + + + override init(frame: CGRect) { + + super.init(frame: frame) + + label = UILabel(frame: frame) + + autolayout(["label": label], + constraints: + "H:|-5-[label]-5-|", + "V:|-5-[label]-5-|" ) + } + + func setItem(item: MediaItem) { + self.item = item + + label.text = item.name + backgroundColor = UIColor.grayColor() + } +} diff --git a/kplayer/ItemCell.swift b/kplayer/ItemCell.swift index 0a1a6f4..582a246 100644 --- a/kplayer/ItemCell.swift +++ b/kplayer/ItemCell.swift @@ -10,7 +10,6 @@ import Haneke class ItemCell: UICollectionViewCell { var item: MediaItem? - var label: UILabel! var image: UIImageView! required init(coder aDecoder: NSCoder) @@ -24,36 +23,23 @@ class ItemCell: UICollectionViewCell { super.init(frame: frame) - label = UILabel(frame: frame) - image = UIImageView(frame: frame) - image.layer.borderWidth = 2.0; - autolayout(["label": label, "imag": image], + autolayout(["imag": image], constraints: - "H:|-5-[label]-5-|", - "H:|-5-[imag]-5-|", - "V:|-5-[label(<=50)]-5-[imag]-5-|" ) + "H:|-[imag]-|", + "V:|-[imag]-|" ) } func setItem(item: MediaItem) { self.item = item - if (item.type == ItemType.SNAPSHOT) { - label.hidden = true - } - else { - label.text = item.name - label.hidden = false - } - if let url = item.thumbUrl { - image.hnk_setImageFromURL(NSURL(string: NetworkManager.sharedInstance.baseurl + "/service/download" + url)!) + image.hnk_setImageFromURL(NSURL(string: item.thumbUrlAbsolute)!) } else { if let i = item.image { - println(i) - image.image = i + image.image = i.scaleToSize(14 * 16, height: 14 * 10) image.sizeToFit() } else { image.image = UIImage(named: "Kirschkeks-256x256.png") diff --git a/kplayer/MasterViewController.swift b/kplayer/MasterViewController.swift index 0ec49ab..0a6a327 100644 --- a/kplayer/MasterViewController.swift +++ b/kplayer/MasterViewController.swift @@ -35,16 +35,61 @@ class MasterViewController: UITableViewController { if p == nil { p = MediaItem(name: "", path: f.path, root: f.root, type: ItemType.FOLDER) d[f.path] = p! - println(p) } p!.children.append(f) f.parent = p! } - self.items = Array(d.values) + NetworkManager.sharedInstance.loadDirs("/srv/samba/ren/knk_archiv3") { + (g) in - self.tableView.reloadData() + for f in g { + var p = d[f.path] + + if p == nil { + p = MediaItem(name: "", path: f.path, root: f.root, type: ItemType.FOLDER) + d[f.path] = p! + } + + p!.children.append(f) + f.parent = p! + } + + NetworkManager.sharedInstance.loadDirs("/srv/samba/ren/knk_archiv2") { + (g) in + + for f in g { + var p = d[f.path] + + if p == nil { + p = MediaItem(name: "", path: f.path, root: f.root, type: ItemType.FOLDER) + d[f.path] = p! + } + + p!.children.append(f) + f.parent = p! + } + NetworkManager.sharedInstance.loadDirs("/srv/samba/ren/knk_archiv") { + (g) in + + for f in g { + var p = d[f.path] + + if p == nil { + p = MediaItem(name: "", path: f.path, root: f.root, type: ItemType.FOLDER) + d[f.path] = p! + } + + p!.children.append(f) + f.parent = p! + } + self.items = Array(d.values) + + self.tableView.reloadData() + } + } + } } // Do any additional setup after loading the view, typically from a nib. @@ -60,6 +105,8 @@ class MasterViewController: UITableViewController { override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() + + println("Memory Warning") // Dispose of any resources that can be recreated. } diff --git a/kplayer/VideoPlayerController.swift b/kplayer/VideoPlayerController.swift index 5838e1e..b082ade 100644 --- a/kplayer/VideoPlayerController.swift +++ b/kplayer/VideoPlayerController.swift @@ -7,6 +7,7 @@ import Foundation import UIKit import MediaPlayer import ALMoviePlayerController +import Haneke class VideoPlayerController: UIViewController { var moviePlayer: ALMoviePlayerController? @@ -25,6 +26,9 @@ class VideoPlayerController: UIViewController { println(url) + let barbutton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: Selector("twoFingersTwoTaps")); + navigationItem.rightBarButtonItems = [barbutton] + play(url) } @@ -86,14 +90,28 @@ class VideoPlayerController: UIViewController { } func addItemButton(newItem: MediaItem) { - let icon = newItem.image!.scaleToSize(66.0, height: 44.0) let frame = CGRectMake(0, 0, 66.0, 44.0); let button = UIButton(frame: frame) - button.setBackgroundImage(icon, forState: UIControlState.Normal); button.showsTouchWhenHighlighted = true button.addTarget(self, action: "thumbnailClicked:", forControlEvents: .TouchDown) + if newItem.image != nil { + let icon = newItem.image!.scaleToSize(66.0, height: 44.0) + + button.setBackgroundImage(icon, forState: UIControlState.Normal); + } else { + if newItem.thumbUrl != nil { + let URL = NSURL(string: newItem.thumbUrlAbsolute)! + + Shared.imageCache.fetch(URL: URL).onSuccess { + i in + let icon = i.scaleToSize(66.0, height: 44.0) + button.setBackgroundImage(icon, forState: UIControlState.Normal); + } + } + } + let barbutton = UIBarButtonItem(customView: button); if navigationItem.rightBarButtonItems == nil { @@ -181,21 +199,22 @@ class VideoPlayerController: UIViewController { func swipeUp() { println("u") if let player = self.moviePlayer { - if index < count(currentItem!.children) - 1 { - index++; + if !(currentItem!.children.isEmpty) { + if index < count(currentItem!.children) - 1 { + index++; + } else { + index = 0; + } + let child = currentItem!.children[index] + player.currentPlaybackTime = child.time! } - else { - index = 0; - } - let child = currentItem!.children[index] - player.currentPlaybackTime = child.time! } } func swipeRight() { println("r") if let player = self.moviePlayer { - player.currentPlaybackTime = player.currentPlaybackTime + 30.0 + player.currentPlaybackTime = player.currentPlaybackTime - 30.0 } } @@ -209,7 +228,7 @@ class VideoPlayerController: UIViewController { func swipeLeft() { println("l") if let player = self.moviePlayer { - player.currentPlaybackTime = player.currentPlaybackTime - 30.0 + player.currentPlaybackTime = player.currentPlaybackTime + 30.0 } } diff --git a/kplayer/core/MediaItem.swift b/kplayer/core/MediaItem.swift index 58960bc..00378a9 100644 --- a/kplayer/core/MediaItem.swift +++ b/kplayer/core/MediaItem.swift @@ -37,11 +37,17 @@ class MediaItem : DebugPrintable { var thumbPath: String { let len = count("/srv/samba/ren") - let tpath = "/srv/samba/ren/thumb" + (root as NSString).substringFromIndex(len) + "/" + path + "/" + name + let enc = name.stringByReplacingOccurrencesOfString(" ", withString: "+") + let tpath = "/srv/samba/ren/thumb" + (root as NSString).substringFromIndex(len) + "/" + path + "/" + enc + return tpath + "/" } + var thumbUrlAbsolute: String { + return NetworkManager.sharedInstance.baseurl + "/service/download" + thumbUrl! + } + var fullPath: String { let fpath = root + "/" + path + "/" + name diff --git a/kplayer/core/NetworkManager.swift b/kplayer/core/NetworkManager.swift index 2d260ce..0dafb73 100644 --- a/kplayer/core/NetworkManager.swift +++ b/kplayer/core/NetworkManager.swift @@ -45,6 +45,47 @@ class NetworkManager { } func loadDirs(root: String, completionHandler: ([MediaItem]) -> Void) -> Void { + let url = baseurl + "/service/listvideos" + root + let len = count(root) + var res = [MediaItem]() + + println(url) + + Alamofire.request(.GET, url).responseSwiftyJSON({ + (request, response, json, error) in + + var hashes = NSMutableSet() + + for (a, c) in json { + // let (a,b) = j # + let s = c.object as! String + + if s.hasSuffix(".mp4") || s.hasSuffix(".m4v") { + let l = count(s) + let name = (s as NSString).lastPathComponent + var pathlen = l - len - count(name) + +// if (pathlen > 1000) { + println (pathlen) + println (name) + println (s) +// } + if (pathlen < 2) { + pathlen = 2 + } + + let path = (s as NSString).substringWithRange(NSMakeRange(len + 1, pathlen - 2)) + let i = MediaItem(name: name, path: path, root: root, type: ItemType.VIDEO) + if !name.hasPrefix(".") { + res.append(i) + } + } + } + completionHandler(res) + }) + } + + func loadDir(root: String, completionHandler: ([MediaItem]) -> Void) -> Void { var itemsArray = []; Alamofire.request(.GET, baseurl + "/service/dirs" + root) @@ -59,7 +100,7 @@ class NetworkManager { var res = [MediaItem]() for s in f { - if (s.hasSuffix(".mp4")) { + if s.hasSuffix(".mp4") || s.hasSuffix(".m4v") { let l = count(s) let name = (s as NSString).lastPathComponent let pathlen = l - len - count(name) @@ -75,7 +116,8 @@ class NetworkManager { } func playerURL(item: MediaItem) -> String { - return baseurl + "/service/stream" + item.root + "/" + item.path + "/" + item.name + let enc = item.name // .stringByReplacingOccurrencesOfString(" ", withString: "+") + return baseurl + "/service/stream" + item.root + "/" + item.path + "/" + enc } func loadItems(item: MediaItem) { @@ -136,7 +178,6 @@ class NetworkManager { } for (ts, p) in hashes { - println ("\(ts) \(p)") let t = (ts as NSString).doubleValue / 1000 let snap = MediaItem(name: item.name, path: item.path, root: item.root, type:.SNAPSHOT) @@ -147,9 +188,8 @@ class NetworkManager { // self.operationQueue.addOperation(op) snap.parent = item + snap.loaded = true item.children.append(snap) - - println ("Time: \(t)") } item.loaded = true @@ -196,9 +236,13 @@ class NetworkManager { let op = UploadOperation(baseUrl: self.baseurl, data: imageData, path: p) self.operationQueue.addOperation(op) - let imageDataT = UIImageJPEGRepresentation(c.image!.scaleToSize(14 * 16, height: 14 * 10), 1.0); + let thumb = c.image!.scaleToSize(14 * 16, height: 14 * 10) + let imageDataT = UIImageJPEGRepresentation(thumb, 1.0); + c.image = thumb let opT = UploadOperation(baseUrl: self.baseurl, data: imageDataT, path: pt) self.operationQueue.addOperation(opT) + + c.loaded = true } hashes.removeObject(p) hashes.removeObject(pt) diff --git a/kplayer/core/UploadOperation.swift b/kplayer/core/UploadOperation.swift index 179f94b..bd9b2a1 100644 --- a/kplayer/core/UploadOperation.swift +++ b/kplayer/core/UploadOperation.swift @@ -30,6 +30,9 @@ class UploadOperation: NSOperation { let urlRequest = urlRequestWithComponents(baseUrl + "/service/upload", parameters) let request = Alamofire.upload(urlRequest) + + // success: todo set url to item + // .progress { // (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in // println("progress : \(totalBytesWritten) / \(totalBytesExpectedToWrite)")