I have read most of the questions on StackOverflow
for autoplaying videos and I\'m able to autoplay them in UITableView
, but I\'m having few issues
I have a few tips for you:
Do not try to call play/pause during scrolling. Just perform this actions right after scrolling stops: https://gist.github.com/k06a/731654e3168277fb1fd0e64abc7d899e
You can try to use this dirty hacks: https://gist.github.com/k06a/66f7815b0325f239411e26f498c75755 To hide it from Apple Review Team just obfustace keypath @"_player.stateDispatchQueue"
with UAObfuscateString
library.
I heard smooth payback can be achieved without dirty hacks. I'll ask a friend of mine to answer your question.
So I achieved this smooth scrolling with Texturekit. In case anyone wants to achieve the smooth scrolling here is what I did.
I have created a new UItableViewCell -
#import <UIKit/UIKit.h>
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface AutoplayVideoTableViewCell : UITableViewCell {
ASVideoPlayerNode *_videoPlayerNode;
ASControlNode *_likeButtonNode;
ASButtonNode *_muteButtonNode;
UIImage* _fsIcon;
}
- (void)setVideoURL:(NSString*)aVideoURL;
@end
#import "AutoplayVideoTableViewCell.h"
#import "UIImage+Tint.h"
#define AVATAR_IMAGE_HEIGHT 30
#define HORIZONTAL_BUFFER 10
#define VERTICAL_BUFFER 5
@interface AutoplayVideoTableViewCell () <ASVideoPlayerNodeDelegate>
@end
@implementation AutoplayVideoTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
_muteButtonNode = [[ASButtonNode alloc] init];
_muteButtonNode.style.width = ASDimensionMakeWithPoints(16.0);
_muteButtonNode.style.height = ASDimensionMakeWithPoints(22.0);
[_muteButtonNode addTarget:self action:@selector(didTapMuteButton) forControlEvents:ASControlNodeEventTouchUpInside];
_videoPlayerNode = [[ASVideoPlayerNode alloc] init];
_videoPlayerNode.delegate = self;
_videoPlayerNode.backgroundColor = [UIColor blackColor];
[self.contentView addSubnode:_videoPlayerNode];
[self setMuteButtonIcon];
_fsIcon = [[UIImage imageNamed:@"fullScreenIcon"] imageTintedWithColor:[UIColor whiteColor]];
}
- (void)setVideoURL:(NSString*)aVideoURL {
//ASVideoNode *videoNode = [[ASVideoNode alloc] init];
CGFloat fullWidth = [UIScreen mainScreen].bounds.size.width;
_videoPlayerNode.view.frame = CGRectMake(0, 0, fullWidth, 200);
[_videoPlayerNode setAssetURL:[NSURL URLWithString:aVideoURL]];
[_videoPlayerNode setGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPlayerNode setShouldAutoPlay:YES];
[_videoPlayerNode setShouldAutoRepeat:NO];
[_videoPlayerNode play];
}
- (void)videoPlayerNodeDidPlayToEnd:(ASVideoPlayerNode *)videoPlayer {
[videoPlayer seekToTime:0];
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
CGFloat fullWidth = [UIScreen mainScreen].bounds.size.width;
_videoPlayerNode.style.width = ASDimensionMakeWithPoints(fullWidth);
// _videoPlayerNode.style.height = ASDimensionMakeWithPoints(200);
ASStackLayoutSpec *bottomControlsStack = [ASStackLayoutSpec horizontalStackLayoutSpec];
bottomControlsStack.spacing = HORIZONTAL_BUFFER;
bottomControlsStack.alignItems = ASStackLayoutAlignItemsCenter;
bottomControlsStack.children = @[_likeButtonNode];
UIEdgeInsets bottomControlsInsets = UIEdgeInsetsMake(HORIZONTAL_BUFFER, HORIZONTAL_BUFFER, HORIZONTAL_BUFFER, HORIZONTAL_BUFFER);
ASInsetLayoutSpec *bottomControlsInset = [ASInsetLayoutSpec insetLayoutSpecWithInsets:bottomControlsInsets child:bottomControlsStack];
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStack.alignItems = ASStackLayoutAlignItemsStretch;
verticalStack.children = @[_videoPlayerNode, bottomControlsInset];
return verticalStack;
}
- (void)setMuteButtonIcon
{
if (_videoPlayerNode.muted) {
[_muteButtonNode setImage:[UIImage imageNamed:@"ico-mute1"] forState:UIControlStateNormal];
} else {
[_muteButtonNode setImage:[UIImage imageNamed:@"ico-unmute1"] forState:UIControlStateNormal];
}
}
- (void)didTapMuteButton
{
_videoPlayerNode.muted = !_videoPlayerNode.muted;
[self setMuteButtonIcon];
}
#pragma mark - ASVideoPlayerNodeDelegate
- (void)didTapVideoPlayerNode:(ASVideoPlayerNode *)videoPlayer
{
if (_videoPlayerNode.playerState == ASVideoNodePlayerStatePlaying) {
_videoPlayerNode.controlsDisabled = !_videoPlayerNode.controlsDisabled;
[_videoPlayerNode pause];
} else {
[_videoPlayerNode play];
}
}
- (NSDictionary *)videoPlayerNodeCustomControls:(ASVideoPlayerNode *)videoPlayer
{
return @{
@"muteControl" : _muteButtonNode
};
}
- (UIImage *)videoPlayerNodeFullScreenButtonImage:(ASVideoPlayerNode *)videoPlayer {
return _fsIcon;
}
- (NSArray *)controlsForControlBar:(NSDictionary *)availableControls
{
NSMutableArray *controls = [[NSMutableArray alloc] init];
if (availableControls[ @(ASVideoPlayerNodeControlTypePlaybackButton) ]) {
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypePlaybackButton) ]];
}
if (availableControls[ @(ASVideoPlayerNodeControlTypeElapsedText) ]) {
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeElapsedText) ]];
}
if (availableControls[ @(ASVideoPlayerNodeControlTypeScrubber) ]) {
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeScrubber) ]];
}
if (availableControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]) {
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]];
}
if (availableControls[ @(ASVideoPlayerNodeControlTypeFullScreenButton) ]) {
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeFullScreenButton) ]];
}
return controls;
}
#pragma mark - Layout
- (ASLayoutSpec*)videoPlayerNodeLayoutSpec:(ASVideoPlayerNode *)videoPlayer forControls:(NSDictionary *)controls forMaximumSize:(CGSize)maxSize
{
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
spacer.style.flexGrow = 1.0;
UIEdgeInsets insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
if (controls[ @(ASVideoPlayerNodeControlTypeScrubber) ]) {
ASDisplayNode *scrubber = controls[ @(ASVideoPlayerNodeControlTypeScrubber) ];
scrubber.style.height = ASDimensionMakeWithPoints(44.0);
scrubber.style.minWidth = ASDimensionMakeWithPoints(0.0);
scrubber.style.maxWidth = ASDimensionMakeWithPoints(maxSize.width);
scrubber.style.flexGrow = 1.0;
}
NSArray *controlBarControls = [self controlsForControlBar:controls];
NSMutableArray *topBarControls = [[NSMutableArray alloc] init];
//Our custom control
if (controls[@"muteControl"]) {
[topBarControls addObject:controls[@"muteControl"]];
}
ASStackLayoutSpec *topBarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
spacing:10.0
justifyContent:ASStackLayoutJustifyContentStart
alignItems:ASStackLayoutAlignItemsCenter
children:topBarControls];
ASInsetLayoutSpec *topBarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:topBarSpec];
ASStackLayoutSpec *controlbarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
spacing:10.0
justifyContent:ASStackLayoutJustifyContentStart
alignItems:ASStackLayoutAlignItemsCenter
children: controlBarControls ];
controlbarSpec.style.alignSelf = ASStackLayoutAlignSelfStretch;
ASInsetLayoutSpec *controlbarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:controlbarSpec];
controlbarInsetSpec.style.alignSelf = ASStackLayoutAlignSelfStretch;
ASStackLayoutSpec *mainVerticalStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionVertical
spacing:0.0
justifyContent:ASStackLayoutJustifyContentStart
alignItems:ASStackLayoutAlignItemsStart
children:@[topBarInsetSpec, spacer, controlbarInsetSpec]];
return mainVerticalStack;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
@end
And in the cellforRow method I changed the code
if (post.medias.count > 0) {
MediaItem* item = post.medias[0];
if ([item getMediaType] == VIDEO) {
[cell setVideoURL:item.mediaUrl];
// dispatch_async(dispatch_get_main_queue(), ^{
//cell.videoThumbnail.image = nil;
//});
}
}
And it worked like a charm. I'm still trying to figure other things but it will be a enough to start for anyone else. The Code I picked up is from the sample app named ASDKTube [ObjC] from the Texture samples.