在iOS中平滑video循环
任何人都可以建议一种方法,通过它您可以在iOS中实现video剪辑的完全平滑和无缝循环? 我尝试了两种方法,这两种方法都会在video循环时产生一个小暂停
1)AVPlayerLayer与playerItemDidReachEnd通知设置关闭seekToTime:kCMTimeZero
我更喜欢使用AVPlayerLayer(出于其他原因),但是这种方法在循环之间产生大约一秒钟的显着暂停。
2)带有setRepeatMode的MPMoviePlayerController:MPMovieRepeatModeOne
这导致较小的暂停,但仍然不完美。
我不知道从哪里开始。 任何人都可以建议一个灵魂?
我可以同意@ SamBrodkin的发现。
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(myMovieFinishedCallback:) name: MPMoviePlayerPlaybackStateDidChangeNotification object: m_player];
和
-(void) myMovieFinishedCallback: (NSNotification*) aNotification { NSLog( @"myMovieFinishedCallback: %@", aNotification ); MPMoviePlayerController *movieController = aNotification.object; NSLog( @"player.playbackState = %d", movieController.playbackState ); }
我也修复了iOS 5上的非循环问题。
我刚刚在我的iPad 3上运行iOS 5.1.1,基础SDK iOS 5.1
设置电影播放器时,将重复模式设置为MPMovieRepeatModeNone,然后添加通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];
然后设置选择器以在电影结束播放时进行过滤
- (void)moviePlayerDidFinish:(NSNotification *)note { if (note.object == self.moviePlayer) { NSInteger reason = [[note.userInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue]; if (reason == MPMovieFinishReasonPlaybackEnded) { [self.moviePlayer play]; } } }
Apple对MPMoviePlayerController在从iOS 4更改为iOS 5时如何处理加载电影文件方面做了一些大的改动,所以我不知道这个方法在发布iOS 6时是否会起作用
要查看显示背景video(来自动画GIF)的无缝循环以及在一对前景角色动画(使用Alpha通道)之间切换的示例,请查看ios上的无缝video循环 。 我过去曾尝试过使用AVPlayer而不得不放弃与AVPlayer相关的解决方案,因为它们运行得不够好。 看到这个问题也是iphone-smooth-transition-from-one-video-to-another 。
我研究了原始海报所报告的相同问题(循环中的小停顿打破了无缝性)。 幸运的是,我有另一个没有这种行为的video样本,并且稍后才发现解释/不同:
音轨。
我怀疑声音初始化很慢(路由?)。
删除音轨对我来说是最简单的解决方案(不需要声音),但我将不得不进一步挖掘(音频混合选项并测试已在此线程中发布的解决方案)。
埃里克
为了避免video倒带时的差距,在合成中使用同一资产的多个副本对我来说效果很好。
AVURLAsset *tAsset = [AVURLAsset assetWithURL:tURL]; CMTimeRange tEditRange = CMTimeRangeMake(CMTimeMake(0, 1), CMTimeMake(tAsset.duration.value, tAsset.duration.timescale)); AVMutableComposition *tComposition = [[[AVMutableComposition alloc] init] autorelease]; for (int i = 0; i < 100; i++) { // Insert some copies. [tComposition insertTimeRange:tEditRange ofAsset:tAsset atTime:tComposition.duration error:nil]; } AVPlayerItem *tAVPlayerItem = [[AVPlayerItem alloc] initWithAsset:tComposition]; AVPlayer *tAVPlayer = [[AVPlayer alloc] initWithPlayerItem:tAVPlayerItem];