Browse Source

Prefetch Bulk

master
Marco Schmickler 10 years ago
parent
commit
a2c3cca94b
  1. 178
      kplayer/photo/MediaPhotoController.swift
  2. 19
      kplayer/util/DataLoadOperation.swift
  3. 9
      kplayer/util/ImageLoadOperation.swift

178
kplayer/photo/MediaPhotoController.swift

@ -7,7 +7,7 @@ import Foundation
import Nimbus
import Alamofire
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource {
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource, NSURLSessionDelegate {
var items = [MediaItem]()
var completionHandler: ((Void) -> Void)?
@ -21,29 +21,41 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
var timer: NSTimer?
var currentIndex = 80
var currentIndex = 100
lazy var backgroundOperationQueue: NSOperationQueue = {
var queue = NSOperationQueue()
queue.name = "Thumb queue"
queue.maxConcurrentOperationCount = 10
return queue
}()
var urlSession: NSURLSession?
var sessionOwner = false
let dateFormatter = NSDateFormatter()
lazy var operationQueue: NSOperationQueue = {
var queue = NSOperationQueue()
queue.name = "Photo queue"
queue.maxConcurrentOperationCount = 6
queue.maxConcurrentOperationCount = 3
return queue
}()
override func viewDidDisappear(animated: Bool) {
backgroundOperationQueue.cancelAllOperations()
operationQueue.cancelAllOperations()
}
public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
print(error)
}
override func viewDidLoad() {
super.viewDidLoad()
if urlSession == nil {
sessionOwner = true
let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration(); // backgroundSessionConfigurationWithIdentifier("imageLoad");
configuration.HTTPMaximumConnectionsPerHost = 10;
configuration.timeoutIntervalForRequest = 100;
configuration.timeoutIntervalForResource = 200;
urlSession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil);
}
imageCache.totalCostLimit = 1024 * 1024 * 1024
let backButton = UIBarButtonItem(barButtonSystemItem: .Cancel, target: self, action: Selector("back"))
@ -57,59 +69,40 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
setChromeVisibility(true, animated: true)
self.photoAlbumView.reloadData();
self.photoScrubberView.reloadData();
preload(0, count: 40)
preload(40, count: 40)
preload(0, count: 50)
preload(50, count: 50)
}
func preload(start: Int, count: Int) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm:ss.SSSZ"
var preview = ""
let end = start + count
for var k = start; k < end; k++ {
let tu = items[k].thumbUrl!.stringByReplacingOccurrencesOfString("?preview=true", withString: "")
preview += "\(tu);"
}
preview = preview.stringByAddingPercentEscapesUsingEncoding(NSISOLatin1StringEncoding)!
let u2 = "\(NetworkManager.sharedInstance.baseurl)/service/preload?preview=\(preview)"
let u3 = NSURL(string: u2)
if let URL = u3 {
let time = dateFormatter.stringFromDate(NSDate())
print("\(time) preload image \(u2)")
let op1 = DataLoadOperation(imageURL: URL, succeeder: {
da in
if da.length > 0 {
let d = da as! NSData
func loadData(d: NSData, start: Int, end: Int) {
let bytes = Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(d.bytes), count: d.length))
let string1 = NSString(data: d, encoding: NSUTF8StringEncoding)
print(string1)
var index = 0
let fHi = (Int(bytes[index++]) << 24)+(Int(bytes[index++]) << 16)
let fHi = (Int(bytes[index++]) << 24) + (Int(bytes[index++]) << 16)
let f = fHi + (Int(bytes[index++]) << 8) + Int(bytes[index++])
// let f = (bytes[index++] << 24)+(bytes[index++] << 16)+(bytes[index++] << 8) + bytes[index++]
let time = dateFormatter.stringFromDate(NSDate())
print("\(time) start \(start) count \(f) size \(d.length)")
var rest = self.items.count - self.currentIndex
if rest > 40 {
rest = 40
if rest > 50 {
rest = 50
}
if rest > 0 {
self.preload(self.currentIndex, count: rest)
self.currentIndex += rest
} else {
dispatch_async(dispatch_get_main_queue(), {
() -> Void in
self.photoScrubberView.reloadData();
})
}
for var bild = start; bild < end; bild++ {
let sizeHi = (Int(bytes[index++]) << 24)+(Int(bytes[index++]) << 16)
let sizeHi = (Int(bytes[index++]) << 24) + (Int(bytes[index++]) << 16)
let size = (Int(bytes[index++]) << 8) + Int(bytes[index++]) + sizeHi
if size > 0 {
@ -128,49 +121,45 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
}
index += size
}
}
func preload(start: Int, count: Int) {
dateFormatter.dateFormat = "HH:mm:ss.SSSZ"
var preview = ""
var end = start + count
if end > items.count {
end = items.count
}
}, index: start)
op1.qualityOfService = NSQualityOfService.Background
backgroundOperationQueue.addOperation(op1)
} else {
print("## Invalid URL: \(u2)")
for var k = start; k < end; k++ {
let tu = items[k].thumbUrl!.stringByReplacingOccurrencesOfString("?preview=true", withString: "")
preview += "\(tu);"
}
preview = preview.stringByAddingPercentEscapesUsingEncoding(NSISOLatin1StringEncoding)!
let u2 = "\(NetworkManager.sharedInstance.baseurl)/service/preload?preview=\(preview)"
let u3 = NSURL(string: u2)
// for i in items {
// if j++ > 1000 {
// break
// }
//
// let u1 = NSURL(string: i.thumbUrlAbsolute)
//
// if let URL = u1 {
// let time = dateFormatter.stringFromDate(NSDate())
// print("\(time) preload image \(i.name)")
//
// let op1 = DataLoadOperation(imageURL: URL, succeeder: {
// d in
// if d.length > 0 {
// if let img = UIImage(data: d) {
// let imageRef = img.CGImage;
// let bytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8;
// let cost = CGImageGetWidth(imageRef) * CGImageGetHeight(imageRef) * bytesPerPixel;
// self.total += d.length
//
// let time = dateFormatter.stringFromDate(NSDate())
// print("\(time) preload image loaded \(i.name) cost \(cost) total\(self.total)")
// self.imageCache.setObject(img, forKey: i.thumbUrlAbsolute, cost: d.length)
// }
// }
// }, index: j)
if let URL = u3 {
let time = dateFormatter.stringFromDate(NSDate())
print("\(time) preload image \(u2)")
urlSession!.dataTaskWithURL(URL) {
(da, response, error) in
if let d = da {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
() -> Void in
self.loadData(d, start: start, end: end)
}
}
}.resume()
// op1.qualityOfService = NSQualityOfService.Background
// backgroundOperationQueue.addOperation(op1)
// } else {
// print("## Invalid URL: \(i.thumbUrlAbsolute)")
// }
// }
} else {
print("## Invalid URL: \(u2)")
}
}
override func didReceiveMemoryWarning() {
@ -194,6 +183,13 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
}
func back() {
imageCache.removeAllObjects()
operationQueue.cancelAllOperations()
if sessionOwner {
urlSession!.invalidateAndCancel()
}
completionHandler!()
}
@ -246,7 +242,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
for s in json as! [String] {
if s.hasSuffix(".jpg") {
let l = s.length
let name = NSURL(fileURLWithPath: s ).lastPathComponent!
let name = NSURL(fileURLWithPath: s).lastPathComponent!
var pathlen = l - len - name.length
// if (pathlen > 1000) {
@ -276,6 +272,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
}
let pc = MediaPhotoController()
pc.urlSession = self.urlSession!
pc.items = im
pc.completionHandler = {
@ -379,7 +376,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
self.photoScrubberView.didLoadThumbnail(i, atIndex: photoAtIndex);
}
}
}, index: photoAtIndex)
}, index: photoAtIndex, session: urlSession!)
op3.qualityOfService = NSQualityOfService.UserInteractive
operationQueue.addOperation(op3)
}
@ -445,19 +442,19 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
return nil
}
var image: UIImage?
let newItem = items[thumbnailIndex]
let u1 = NSURL(string: newItem.thumbUrlAbsolute)
var image: UIImage?
if let URL = u1 {
image = imageCache.objectForKey(newItem.thumbUrlAbsolute) as? UIImage
image = imageCache.objectForKey(URL.absoluteString) as? UIImage
if (image == nil) {
let u1 = NSURL(string: newItem.thumbUrlAbsolute)
if let URL = u1 {
let op3 = DataLoadOperation(imageURL: URL, succeeder: {
d in
urlSession!.dataTaskWithURL(URL) {
(da, response, error) in
if d.length > 0 {
if let d = da {
if let i = UIImage(data: d) {
// println("thumb image loaded \(newItem.thumbUrlAbsolute)")
let imageRef = i.CGImage;
@ -469,13 +466,12 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView
self.photoScrubberView.didLoadThumbnail(i, atIndex: thumbnailIndex);
}
}
}, index: thumbnailIndex)
op3.qualityOfService = NSQualityOfService.UserInitiated
operationQueue.addOperation(op3)
} else {
print("## Invalid URL: \(newItem.thumbUrlAbsolute)")
}
}
}
else {
print("## Invalid URL: \(newItem.thumbUrlAbsolute)")
}
return image
}

19
kplayer/util/DataLoadOperation.swift

@ -17,11 +17,14 @@ class DataLoadOperation: NSOperation {
var ready1 = false
let backgroundSession: NSURLSession
var downloadTask: NSURLSessionDataTask?
init(imageURL: NSURL, succeeder: Succeeder, index: Int) {
init(imageURL: NSURL, succeeder: Succeeder, index: Int, session: NSURLSession) {
self.imageURL = imageURL
self.succeeder = succeeder
self.index = index
self.backgroundSession = session
}
override func main() {
@ -31,11 +34,11 @@ class DataLoadOperation: NSOperation {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm:ss.SSS"
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration(); // backgroundSessionConfigurationWithIdentifier("imageLoad");
configuration.HTTPMaximumConnectionsPerHost = 100;
var backgroundSession = NSURLSession(configuration: configuration, delegate: nil, delegateQueue: nil);
// var configuration = NSURLSessionConfiguration.defaultSessionConfiguration(); // backgroundSessionConfigurationWithIdentifier("imageLoad");
// configuration.HTTPMaximumConnectionsPerHost = 100;
// var backgroundSession = NSURLSession(configuration: configuration, delegate: nil, delegateQueue: nil);
var url = NSURLRequest(URL: imageURL);
var downloadTask = backgroundSession.dataTaskWithRequest(url, completionHandler: {
downloadTask = backgroundSession.dataTaskWithRequest(url, completionHandler: {
data,response,error in
if error == nil {
@ -58,7 +61,7 @@ class DataLoadOperation: NSOperation {
let time = dateFormatter.stringFromDate(NSDate())
// print("\(time) preload image \(imageURL)")
downloadTask.resume();
downloadTask!.resume();
// Alamofire.request(.GET, imageURL).response {
@ -72,6 +75,10 @@ class DataLoadOperation: NSOperation {
ready1 = true
if let t = downloadTask {
t.cancel()
}
super.cancel()
}

9
kplayer/util/ImageLoadOperation.swift

@ -31,12 +31,17 @@ class ImageLoadOperation: NSOperation {
return
}
let r = NSMutableURLRequest(URL: imageURL)
r.HTTPBody = nil
r.addValue("0", forHTTPHeaderField: "Content-Length")
if let m = manager {
request = m.request(.GET, imageURL)
request = m.request(.GET, r)
} else {
request = Alamofire.request(.GET, imageURL)
request = Alamofire.request(.GET, r)
}
request!.validate().response { (request, response, data, error) in
if let e = error as? NSError {
if (e.code != -999) {

Loading…
Cancel
Save