Playing Video into Uitableview

Play Videos in TableViewCell

If you create a custom UITableViewCell, you can add a AVPlayer object to that cell and load it up with a video (some code you can use to start with can be found in this related question).

To be honest though, do not expect responsive or fast UI in your table view if you have 7 videos playing at the same time. This is going to be very taxing on the device (in terms of CPU and battery). And each time the "more" button is touched (to add more videos), you might get even slower performance (mitigated only by if you code things in a friendly way -- e.g. where the player stops when the cell is scrolled offscreen).

playing video in UItableView cell swift

As per my previous comment Please enable App transport security in info.plist .

Here are the settings visually:

Sample Image

Play the video on Table Cell

Make sure to import import AVKit and import AVFoundation.

And you can try like this inside cellForRowAtIndexPath:

let cell: FeedCell = tableView.dequeueReusableCellWithIdentifier("VedioCell", forIndexPath: indexPath) as! FeedCell

let videoURL = NSURL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(URL: videoURL!)

let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = cell.bounds

cell.layer.addSublayer(playerLayer)
cell?.playerView?.layer.addSublayer(playerLayer)
player.play()

return cell

If you are using swift3 then the syntax is like this:

let videoURL = NSURL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL! as URL)

let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = (cell?.bounds)!

cell?.layer.addSublayer(playerLayer)
cell?.playerView?.layer.addSublayer(playerLayer)
player.play()

And you also got to make sure you deal with cellForRowAtIndexPath if you are showing many of those.

Autoplay Video in UITableViewCell hiccupps

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.



Related Topics



Leave a reply



Submit