I am trying to setup a UITableView that can play videos. Many of the previous SO questions on this used MPMoviePlayer(Playing Video into UITableView, Playing video in UItableView in SWIFT, Playing Video From UITableView), which is now deprecated in iOS 9. One of the few that used AVFoundation (what i'm using), is this one: Play video on UITableViewCell when it is completely visible and is where I'm getting most of my code from. Here is my code, inside cellForRowAtIndexPath:
VideoCell *videoCell = (VideoCell *)[self.tableView dequeueReusableCellWithIdentifier:@"VideoCell"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
NSURL *url = [[NSURL alloc] initWithString:urlString];
dispatch_async(queue, ^{
videoCell.item = [AVPlayerItem playerItemWithURL:url];
dispatch_sync(dispatch_get_main_queue(), ^{
videoCell.player = [[AVPlayer alloc] initWithPlayerItem:videoCell.item];
videoCell.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:videoCell.player];
playerLayer.frame = CGRectMake(0, 0, videoCell.contentView.frame.size.width, videoCell.contentView.frame.size.height);
[videoCell.contentView.layer addSublayer:playerLayer];
playerLayer.videoGravity = AVLayerVideoGravityResize;
[videoCell.player play];
});
});
return videoCell;
From what I understand, I need to asynchronously download the videos before I play them. I've asynchronously downloaded images before, and the "download" part of that always involves converting NSURL -> NSData -> UIImage. And then when you have the UIImage, you're ready to display it in the cell, so you bring the main queue up and dispatch_async and perform the cell.imageView.image = yourImage; on the main queue.
Here, I have an NSURL, but I don't quite get which steps here should be on the main queue and which should be off the main thread. I tried what was suggested in the aforementioned SO question, but so far it isn't working. The table cell just loads, and the video never plays. I just see the first frame. Sometimes the first 1 second of it will play, but then it buffers after that and won't. I'm working with a table view that has only 1 object right now, so there is just 1 video to play, and it still isn't playing.
What am I doing wrong, and could someone help me explain exactly which parts need to be on the main thread and which off? A responder in the thread I mentioned at the top said there were "lots of tutorials on this out there," but upon scanning google I didn't see any. the terms "asynchronous" and "iOS" together almost always get search results about image downloading, not video. But if any tutorials exist it would be nice to see one.
thanks