Autoplay Video in UITableViewCell hiccupps

后端 未结 2 469
粉色の甜心
粉色の甜心 2021-01-03 11:56

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

相关标签:
2条回答
  • 2021-01-03 12:26

    I have a few tips for you:

    1. Do not try to call play/pause during scrolling. Just perform this actions right after scrolling stops: https://gist.github.com/k06a/731654e3168277fb1fd0e64abc7d899e

    2. 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.

    3. I heard smooth payback can be achieved without dirty hacks. I'll ask a friend of mine to answer your question.

    0 讨论(0)
  • 2021-01-03 12:31

    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.

    0 讨论(0)
提交回复
热议问题