我正在使用AVPlayer& amp;在全屏幕上显示“n”个视频和照片的应用程序。 AVPlayerLayer&具有水平滚动的UICollectionViewCell上的SDwebimage类。我在UIScrollView上启用了set paging。因为我需要播放/仅显示当前位置播放器/图像,否则如果是视频,则“上一个和下一个”小区播放器应处于“暂停”状态。
我正在拍摄视频&网址格式的图片。所以最初我需要下载,之后它将开始播放。因此,每个人都不需要从URL下载视频。所以我决定将下载的视频缓存在本地。所以我下载并将其存储在本地文件中。然后我从本地加载视频如果它存在于本地文件中。
问题:
(a)中。 “播放和暂停”在相关索引上无法正常工作。最初“0”指数被播放。当我滚动到下一个索引此时当前索引播放器应该正在播放时,下一个索引播放器应该处于“暂停”状态。它没有正确同步。
(b)中。当我滚动到索引1时,视频首先闪烁但音频将播放,并在几秒钟内开始播放视频
(c)中。所有观看的音频同时在后台播放以及释放播放器时也是如此。 (我的意思是,我可以在驳回一些观点或查看控制器之后听到)
(d)需要保持内存泄漏问题。
(e)scrollview会滞后一段时间
下面我尝试了一下源代码,
if ([[NSString stringWithFormat:@"%@",_streamArray[indexPath.row][@"media_type"]] isEqualToString:@"6"])
{
profileTableViewCell.videoView.hidden=NO;
NSString *urlStr=[NSString stringWithFormat:@"%@.mp4",[[_streamArray[indexPath.row][@"media"][@"url"] lastPathComponent]stringByDeletingPathExtension]];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:urlStr];
AVAsset *asset = [AVURLAsset URLAssetWithURL:documentURL options:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:[documentURL path]])
{
anItem = [[AVPlayerItem alloc] initWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:anItem];
profileTableViewCell.editBtn.enabled = YES;
}
else
{
profileTableViewCell.editBtn.enabled = NO;
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicator.hidesWhenStopped = YES;
activityIndicator.hidden = NO;
[activityIndicator startAnimating];
[profileTableViewCell.videoView addSubview:activityIndicator];
[[Utilities sharedManager] convertVideoUrltoPathWithURLString:[NSString stringWithFormat:@"%@",_streamArray[indexPath.row][@"media"][@"url"]]];
player = [AVPlayer playerWithURL:[NSURL URLWithString:_streamArray[indexPath.row][@"media"][@"url"]]];
}
layer = [AVPlayerLayer layer];
// isAudio=NO;
[layer setPlayer:player];
[player setMuted:NO];
[layer setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
profileTableViewCell.videoView.layer.sublayers = nil;
[profileTableViewCell.videoView.layer addSublayer:layer];
// player.loopEnabled = YES;
[player play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[player currentItem]];
}
else{
profileTableViewCell.videoView.hidden = YES;
[profileTableViewCell.postImageView sd_setImageWithURL:[NSURL URLWithString:_streamArray[indexPath.row][@"media"][@"url"]] placeholderImage:nil options:SDWebImageRefreshCached completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
}];
}
我将在scrollview中暂停视频
[player pause];
NSString*videoURL=tempCell.videoURLString;
NSString *urlStr=[NSString stringWithFormat:@"%@.mp4",[[videoURL lastPathComponent]stringByDeletingPathExtension]];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
NSURL *documentURL = [documentsDirectoryURL URLByAppendingPathComponent:urlStr];
AVAsset *asset = [AVURLAsset URLAssetWithURL:documentURL options:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:[documentURL path]])
{
anItem = [[AVPlayerItem alloc] initWithAsset:asset];
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
NSMutableArray *allAudioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks) {
AVMutableAudioMixInputParameters *audioInputParams =
[AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:1.0 atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]];
[allAudioParams addObject:audioInputParams];
}
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:allAudioParams];
[anItem setAudioMix:audioMix];
player = [AVPlayer playerWithPlayerItem:anItem];
videoPlayer = [SCPlayer player];
videoPlayer.delegate = self;
videoPlayer.autoRotate = NO;
// [videoPlayer setItemByUrl:_videoUrl];
[videoPlayer setItemByAsset:asset];
videoPlayer.loopEnabled = YES;
}
else
{
for (UIView *subView in tempCell.imageScrollView.subviews)
{
if ([subView isKindOfClass:[LOTAnimationView class]])
{
[subView removeFromSuperview];
}
}
self.lottieLogo = [LOTAnimationView animationNamed:@"loading_rain"];
self.lottieLogo.frame =CGRectMake((tempCell.imageScrollView.frame.size.width/2)-15, (tempCell.imageScrollView.frame.size.height/2)-15, 30, 30);
self.lottieLogo.loopAnimation=YES;
self.lottieLogo.contentMode = UIViewContentModeScaleAspectFill;
[tempCell.imageScrollView addSubview:self.lottieLogo];
[self.lottieLogo play];
[tempCell bringSubviewToFront:self.lottieLogo];
[[Utilities sharedManager] convertVideoUrltoPathWithURLString:[NSString stringWithFormat:@"%@",post.media_details.url]];
player = [AVPlayer playerWithURL:[NSURL URLWithString:post.media_details.url]];
}
layer = [AVPlayerLayer layer];
[layer setPlayer:player];
[player setMuted:NO];
[layer setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[layer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
tempCell.videoView.layer.sublayers = nil;
[tempCell.videoView.layer addSublayer:layer];
[player play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[player currentItem]];
这里我通过使用通知检查玩家是否达到了结束
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}