@ -7,32 +7,164 @@
//
import UIKit
import MediaPlayer
class DetailViewController : UIViewController {
class DetailViewController : UIViewController , UICollectionViewDelegateFlowLayout , UICollectionViewDataSource {
@IBOutlet weak var detailDescriptionLabel : UILabel !
var moviePlayer : MPMoviePlayerController ?
var detailItem : AnyObject ? {
var collectionView : UICollectionView !
var detailItem : MediaItem ? {
didSet {
println ( detailItem ! . children )
if collectionView != nil {
collectionView . reloadData ( )
}
// U p d a t e t h e v i e w .
self . configureView ( )
// s e l f . c o n f i g u r e V i e w ( )
}
}
var currentItem : MediaItem ?
func configureView ( ) {
// U p d a t e t h e u s e r i n t e r f a c e f o r t h e d e t a i l i t e m .
if let detail : AnyObject = self . detailItem {
println ( detailItem )
if let detail : MediaItem = self . detailItem {
println ( detail )
println ( detail . children )
if let label = self . detailDescriptionLabel {
label . text = detail . valueForKey ( " timeStamp " ) ! . description
label . text = detail . na me
}
if count ( detail . children ) > 0 {
let i = detail . children [ 0 ]
var url = NetworkManager . sharedInstance . playerURL ( i )
println ( url )
// i f m o v i e P l a y e r = = n i l {
play ( url )
// }
}
}
}
func play ( url : String ) {
self . moviePlayer = MPMoviePlayerController ( )
if let player = self . moviePlayer {
NSNotificationCenter . defaultCenter ( ) . addObserver ( self , selector : Selector ( " exitedFullscreen " ) , name : MPMoviePlayerDidExitFullscreenNotification , object : nil ) ;
NSNotificationCenter . defaultCenter ( ) . addObserver ( self , selector : Selector ( " enteredFullscreen " ) , name : MPMoviePlayerDidEnterFullscreenNotification , object : nil ) ;
NSNotificationCenter . defaultCenter ( ) . addObserver ( self , selector : Selector ( " showThumbnail: " ) , name : MPMoviePlayerThumbnailImageRequestDidFinishNotification , object : nil ) ;
player . view . frame = CGRect ( x : 0 , y : 0 , width : self . view . frame . size . width , height : self . view . frame . size . height )
player . view . sizeToFit ( )
player . scalingMode = MPMovieScalingMode . AspectFit
player . controlStyle = MPMovieControlStyle . Embedded
player . movieSourceType = MPMovieSourceType . Streaming
player . repeatMode = MPMovieRepeatMode . One
player . contentURL = NSURL ( string : url )
player . play ( )
var timer = NSTimer . scheduledTimerWithTimeInterval ( 1.0 , target : self , selector : Selector ( " update " ) , userInfo : nil , repeats : false )
self . view . addSubview ( player . view )
}
}
func showThumbnail ( note : NSNotification ) {
let userInfo = note . userInfo ! as NSDictionary
let thumbnail = userInfo . objectForKey ( MPMoviePlayerThumbnailImageKey ) as ! UIImage
let time = userInfo . objectForKey ( MPMoviePlayerThumbnailTimeKey ) as ! NSTimeInterval
let newItem = MediaItem ( name : currentItem ! . name , path : currentItem ! . path , root : currentItem ! . root , type : ItemType . SNAPSHOT )
newItem . image = thumbnail
newItem . time = time
newItem . parent = currentItem !
currentItem ! . children . append ( newItem )
println ( newItem . time )
}
func update ( ) {
if let player = self . moviePlayer {
if let t = currentItem ! . time {
player . currentPlaybackTime = t
}
else {
println ( player . duration )
player . currentPlaybackTime = player . duration / 2
}
if currentItem ! . type = = ItemType . SNAPSHOT {
currentItem = currentItem ! . parent
}
player . fullscreen = true
}
}
func enteredFullscreen ( ) {
let mp = UIApplication . sharedApplication ( ) . keyWindow ;
if let moviePlayerContainer = recursiveSearchForViewWithName ( mp ! , classname : " MPVideoContainerView " ) {
if ( moviePlayerContainer . gestureRecognizers != nil ) {
return ;
}
installGestures ( moviePlayerContainer )
}
}
func exitedFullscreen ( ) {
moviePlayer ! . view . removeFromSuperview ( ) ;
moviePlayer = nil ;
NSNotificationCenter . defaultCenter ( ) . removeObserver ( self ) ;
collectionView . reloadData ( )
collectionView . collectionViewLayout . invalidateLayout ( )
}
override func loadView ( ) {
super . loadView ( )
}
override func viewDidLoad ( ) {
super . viewDidLoad ( )
let layout : UICollectionViewFlowLayout = UICollectionViewFlowLayout ( )
layout . sectionInset = UIEdgeInsets ( top : 2 , left : 2 , bottom : 2 , right : 2 )
layout . itemSize = CGSize ( width : 14 * 16 , height : 14 * 10 )
layout . headerReferenceSize = CGSize ( width : 50 , height : 50 )
collectionView = UICollectionView ( frame : view . frame , collectionViewLayout : layout )
collectionView . dataSource = self
collectionView . delegate = self
collectionView . registerClass ( ItemCell . self , forCellWithReuseIdentifier : " Cell " )
collectionView . backgroundColor = UIColor . greenColor ( )
collectionView . registerClass ( ItemCell . self , forSupplementaryViewOfKind : UICollectionElementKindSectionHeader , withReuseIdentifier : " HeaderView " ) ;
view . addSubview ( collectionView )
// v i e w . a u t o r e s i z e s S u b v i e w s = t r u e
// c o l l e c t i o n V i e w . a u t o r e s i z i n g M a s k = U I V i e w A u t o r e s i z i n g . F l e x i b l e W i d t h | U I V i e w A u t o r e s i z i n g . F l e x i b l e H e i g h t
// D o a n y a d d i t i o n a l s e t u p a f t e r l o a d i n g t h e v i e w , t y p i c a l l y f r o m a n i b .
self . configureView ( )
collectionView . reloadData ( )
}
override func viewDidAppear ( animated : Bool ) {
super . viewDidAppear ( animated )
// s e l f . c o n f i g u r e V i e w ( )
}
override func didReceiveMemoryWarning ( ) {
@ -40,6 +172,146 @@ class DetailViewController: UIViewController {
// D i s p o s e o f a n y r e s o u r c e s t h a t c a n b e r e c r e a t e d .
}
func numberOfSectionsInCollectionView ( collectionView : UICollectionView ) -> Int {
if let detail : MediaItem = self . detailItem {
let cnt = count ( detail . children )
println ( cnt )
return cnt
}
return 0
}
func collectionView ( collectionView : UICollectionView , numberOfItemsInSection section : Int ) -> Int {
if let detail : MediaItem = self . detailItem {
return count ( detail . children [ section ] . children ) + 1
}
return 0
}
func collectionView ( collectionView : UICollectionView , cellForItemAtIndexPath indexPath : NSIndexPath ) -> UICollectionViewCell {
let cell = collectionView . dequeueReusableCellWithReuseIdentifier ( " Cell " , forIndexPath : indexPath ) as ! ItemCell
if let detail : MediaItem = self . detailItem {
let items = detail . children [ indexPath . section ]
if indexPath . item >= count ( items . children ) {
cell . setItem ( items )
} else {
let item = items . children [ indexPath . item ]
cell . setItem ( item )
}
}
cell . backgroundColor = UIColor . blueColor ( )
return cell
}
func collectionView ( collectionView : UICollectionView ,
viewForSupplementaryElementOfKind kind : String ,
atIndexPath indexPath : NSIndexPath ) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader :
let headerView =
collectionView . dequeueReusableSupplementaryViewOfKind ( kind ,
withReuseIdentifier : " HeaderView " ,
forIndexPath : indexPath )
as ! ItemCell
let items = detailItem ! . children [ indexPath . section ]
println ( " sec \( indexPath . section ) " + items . name )
headerView . label . text = items . name
headerView . backgroundColor = UIColor . yellowColor ( )
return headerView
default :
assert ( false , " Unexpected element kind " )
}
}
func collectionView ( collectionView : UICollectionView , didSelectItemAtIndexPath indexPath : NSIndexPath ) {
if let detail : MediaItem = self . detailItem {
var items = detail . children [ indexPath . section ]
if indexPath . item >= count ( items . children ) {
println ( items . name )
} else {
items = items . children [ indexPath . item ]
println ( items . name )
}
currentItem = items
var url = NetworkManager . sharedInstance . playerURL ( items )
println ( url )
play ( url )
}
}
func installGestures ( moviePlayer : UIView ) {
let twoFingersTwoTaps = UITapGestureRecognizer ( target : self , action : " twoFingersTwoTaps " )
twoFingersTwoTaps . numberOfTapsRequired = 2
twoFingersTwoTaps . numberOfTouchesRequired = 2
moviePlayer . addGestureRecognizer ( twoFingersTwoTaps )
let sR = UISwipeGestureRecognizer ( target : self , action : " swipeRight " )
sR . direction = UISwipeGestureRecognizerDirection . Right
sR . numberOfTouchesRequired = 1
moviePlayer . addGestureRecognizer ( sR )
let sL = UISwipeGestureRecognizer ( target : self , action : " swipeLeft " )
sL . direction = UISwipeGestureRecognizerDirection . Left
sL . numberOfTouchesRequired = 1
moviePlayer . addGestureRecognizer ( sL )
let sR2 = UISwipeGestureRecognizer ( target : self , action : " swipeDown " )
sR2 . direction = UISwipeGestureRecognizerDirection . Down
sR2 . numberOfTouchesRequired = 1
moviePlayer . addGestureRecognizer ( sR2 )
}
func swipeRight ( ) {
println ( " r " )
if let player = self . moviePlayer {
player . currentPlaybackTime = player . currentPlaybackTime + 30.0
}
}
func swipeDown ( ) {
println ( " r " )
if let player = self . moviePlayer {
player . currentPlaybackTime = player . currentPlaybackTime + 10.0
}
}
func swipeLeft ( ) {
println ( " l " )
if let player = self . moviePlayer {
player . currentPlaybackTime = player . currentPlaybackTime - 30.0
}
}
func twoFingersTwoTaps ( ) {
println ( " tap " )
moviePlayer ! . requestThumbnailImagesAtTimes ( [ moviePlayer ! . currentPlaybackTime ] ,
timeOption : MPMovieTimeOption . NearestKeyFrame ) ;
}
func recursiveSearchForViewWithName ( view : UIView , classname : String ) -> UIView ? {
for v in view . subviews {
var result = recursiveSearchForViewWithName ( v as ! UIView , classname : classname )
let cn = toString ( v . dynamicType )
if cn = = classname {
return v as ! UIView
}
if result != nil {
return result
}
}
return nil
}
}