{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/1671","repository_url":"https://api.github.com/repos/facebook/AsyncDisplayKit","labels_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/1671/labels{/name}","comments_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/1671/comments","events_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/1671/events","html_url":"https://github.com/facebook/AsyncDisplayKit/pull/1671","id":155133251,"number":1671,"title":"ASVideoPlayerNode Beta","user":{"login":"Eke","id":817489,"avatar_url":"https://avatars.githubusercontent.com/u/817489?v=3","gravatar_id":"","url":"https://api.github.com/users/Eke","html_url":"https://github.com/Eke","followers_url":"https://api.github.com/users/Eke/followers","following_url":"https://api.github.com/users/Eke/following{/other_user}","gists_url":"https://api.github.com/users/Eke/gists{/gist_id}","starred_url":"https://api.github.com/users/Eke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Eke/subscriptions","organizations_url":"https://api.github.com/users/Eke/orgs","repos_url":"https://api.github.com/users/Eke/repos","events_url":"https://api.github.com/users/Eke/events{/privacy}","received_events_url":"https://api.github.com/users/Eke/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/labels/CLA%20Signed","name":"CLA Signed","color":"bfe5bf"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2016-05-16T22:05:56Z","updated_at":"2016-05-22T06:34:49Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/pulls/1671","html_url":"https://github.com/facebook/AsyncDisplayKit/pull/1671","diff_url":"https://github.com/facebook/AsyncDisplayKit/pull/1671.diff","patch_url":"https://github.com/facebook/AsyncDisplayKit/pull/1671.patch"},"body":"## ASVideoPlayerNode\r\n\r\n##### What is this?!\r\n`ASVideoPlayerNode` is `ASVideoNode` UI wrapper. It is highly customisable and gives developer ability to build UI above `ASVideoNode`. It has default template but gives developer ability to build fully custom UI with delegate methods\r\n\r\n#### So what about `ASVideoNode`?\r\n`ASVideoNode` will remain as video playback core. So `ASVideoPlayerNode` will be responsible for UI, `ASVideoNode` for playback\r\n\r\n## Delegate Methods\r\n##### videoPlayerNodeNeededControls:\r\nAsks delegate which controls does it need in certain `ASVideoPlayerNode`.  By default all controls are enabled but delegate can override this and use only `ASVideoPlayerNodeControlTypePlaybackButton`.\r\n```\r\n- (NSArray *)videoPlayerNodeNeededControls:(ASVideoPlayerNode *)videoPlayer\r\n{\r\n  return @[ @(ASVideoPlayerNodeControlTypePlaybackButton) ];\r\n}\r\n```\r\n##### videoPlayerNodeLayoutSpec:forControls:forMaximumSize:\r\nAsks delegate for `ASLayoutSpec` which will be used to layout  certain `ASVideoPlayerNode`. With this method developer can  whole layout for `ASVideoPlayerNode` except `ASVideoNode`, it's locked.\r\n\r\n```\r\n- (ASLayoutSpec *)videoPlayerNodeLayoutSpec:(ASVideoPlayerNode *)videoPlayer forControls:(NSDictionary *)controls forMaximumSize:(CGSize)maxSize\r\n{\r\n  NSMutableArray *bottomControls = [[NSMutableArray alloc] init];\r\n\r\n  ASDisplayNode *playbackButtonNode = controls[@(ASVideoPlayerNodeControlTypePlaybackButton)];\r\n\r\n  if (playbackButtonNode) {\r\n    [bottomControls addObject:playbackButtonNode];\r\n  }\r\n\r\n  ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];\r\n  spacer.flexGrow = YES;\r\n\r\n  ASStackLayoutSpec *controlbarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal\r\n  spacing:10.0\r\n  justifyContent:ASStackLayoutJustifyContentStart\r\n  alignItems:ASStackLayoutAlignItemsCenter\r\n  children:bottomControls];\r\n  controlbarSpec.alignSelf = ASStackLayoutAlignSelfStretch;\r\n\r\n  UIEdgeInsets insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);\r\n\r\n  ASInsetLayoutSpec *controlbarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:controlbarSpec];\r\n\r\n  controlbarInsetSpec.alignSelf = ASStackLayoutAlignSelfStretch;\r\n\r\n  ASStackLayoutSpec *mainVerticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical\r\n  spacing:0.0\r\n  justifyContent:ASStackLayoutJustifyContentStart\r\n  alignItems:ASStackLayoutAlignItemsStart\r\n  children:@[ spacer, controlbarInsetSpec ]];\r\n\r\n\r\n  return mainVerticalStack;\r\n}\r\n```\r\n\r\nIn this example we position play button at the bottom-left corner of `ASVideoPlayerNode`. `controls` dictionary contains only same elements which were returned by `videoPlayerNodeNeededControls:`\r\n\r\n##### videoPlayerNodeTimeLabelAttributes:timeLabelType\r\nAsks delegate for `NSAttributedString` options for duration and elapsed time labels. Developer can control everything, starting from color ending with `UIFont`\r\n\r\n##### videoPlayerNode:timeStringForTimeLabelType:forTime:\r\nGives delegate duration or current playback `CMTime` and asks to format it in desired way.\r\n\r\n##### Controlling tint colors\r\n###### videoPlayerNodeScrubberMaximumTrackTint:\r\n###### videoPlayerNodeScrubberMinimumTrackTint:\r\n###### videoPlayerNodeScrubberThumbTint:\r\n###### videoPlayerNodeScrubberThumbImage:\r\n###### videoPlayerNodePlaybackButtonTint:\r\n\r\nAlso there are all `ASVideoNode` delegate methods available :\r\n###### videoPlayerNodeWasTapped:\r\n###### videoPlayerNode:didPlayToTime:\r\n###### videoPlayerNode:willChangeVideoNodeState:toVideoNodeState:\r\n###### videoPlayerNode:shouldChangeVideoNodeStateTo:\r\n###### videoPlayerNodeDidPlayToEnd:\r\n\r\nExample project is not finished yet, will try to finish it asap"},"comment":{"url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/comments/220816979","html_url":"https://github.com/facebook/AsyncDisplayKit/pull/1671#issuecomment-220816979","issue_url":"https://api.github.com/repos/facebook/AsyncDisplayKit/issues/1671","id":220816979,"user":{"login":"Xinchi","id":1481896,"avatar_url":"https://avatars.githubusercontent.com/u/1481896?v=3","gravatar_id":"","url":"https://api.github.com/users/Xinchi","html_url":"https://github.com/Xinchi","followers_url":"https://api.github.com/users/Xinchi/followers","following_url":"https://api.github.com/users/Xinchi/following{/other_user}","gists_url":"https://api.github.com/users/Xinchi/gists{/gist_id}","starred_url":"https://api.github.com/users/Xinchi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Xinchi/subscriptions","organizations_url":"https://api.github.com/users/Xinchi/orgs","repos_url":"https://api.github.com/users/Xinchi/repos","events_url":"https://api.github.com/users/Xinchi/events{/privacy}","received_events_url":"https://api.github.com/users/Xinchi/received_events","type":"User","site_admin":false},"created_at":"2016-05-22T06:34:49Z","updated_at":"2016-05-22T06:34:49Z","body":"@Eke Great change! The PR looks good to me if you could address the PR comments.  One concern I have about this design is the flexibility in adding custom control elements such as the sound button and etc.  Do you have a plan for that? "}}
{"actor":{"display_login":"Xinchi"}}