ios 依次播放 3 个视频
ios playing 3 videos one after another
我正尝试在第一个视频结束后立即开始新视频。我尝试使用 AVQueuePlayer 但是当第一个视频结束和第二个视频开始时会有一些延迟。
我需要它是样本同步的。也就是说,如果视频 1 长 10.25 秒,那么当我播放 11.5 秒时,视频 2 应该是 1.25 秒。
我一直在尝试保留 3 个 AVPlayer 对象,我使用相同的主时钟预滚动每个播放器。然后我试图拦截 AVPlayerItemDidPlayToEndTimeNotification
然后调用 setRate:time:atHostTime:
开始下一个视频。但是我没有播放任何视频。
我使用以下代码预滚动我的视频:
- (void) preRollPlayer: (AVPlayer*) pPlayer withMasterClock: (CMClockRef) masterClock atTime: (NSTimeInterval) time
{
[pPlayer setRate: 0.0f];
[pPlayer play];
[pPlayer seekToTime: CMTimeMakeWithSeconds( time, 1000000 ) toleranceBefore: kCMTimeZero toleranceAfter: kCMTimeZero];
[pPlayer setMasterClock: masterClock];
__block volatile int32_t completed = 0;
[pPlayer prerollAtRate: 1.0f completionHandler: ^( BOOL finished )
{
OSAtomicIncrement32( &completed );
}];
while( completed == 0 )
{
[NSThread sleepForTimeInterval: 0.01];
}
}
然后我按如下方式调用 preRoll:
if ( pAudioVideoEntry.beforeVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.beforeVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
{
[self preRollPlayer: pAudioVideoEntry.videoReader.player withMasterClock: hostClock atTime: currentTime];
}
if ( pAudioVideoEntry.afterVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.afterVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
最后我开始视频如下:
[pAudioVideoEntry.beforeVideoReader.player setRate: 1.0f time: kCMTimeZero atHostTime: syncTime];
pAudioVideoEntry.playingPlayer = pAudioVideoEntry.beforeVideoReader.player;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector( beforeVideoEnded: )
name: AVPlayerItemDidPlayToEndTimeNotification
object: pAudioVideoEntry.beforeVideoReader.playerItem];
奇怪的是,我听不到音频,从未发送通知,每次调用我的 AVPlayerItem
的输出 AVPlayerItemVideoOutput
的 hasNewPixelBufferForItemTime
returns 错误。所以我猜视频还没有开始。有什么想法吗?
所以在我 post 之后大约一个小时的经典风格(我花了一天的大部分时间为此而奋斗)我在这里找到了一个简单的解决方案:
使用 AVMutableComposition
我可以将每个视频按顺序添加到合成中,并获得完美的播放效果:
// Fill in the assets that make up the composition
CMTime time = kCMTimeZero;
for( AVAsset* pThisAsset in pAssets )
{
CMTimeRange timeRange = CMTimeRangeMake( kCMTimeZero, pThisAsset.duration );
[pComposition insertTimeRange: timeRange ofAsset: pThisAsset atTime: time error: nil];
time = CMTimeAdd( time, pThisAsset.duration );
}
我在播放视频图像与音频不同步时遇到一个小错误,但音频表现完美。也大大简化了我的代码!
我正尝试在第一个视频结束后立即开始新视频。我尝试使用 AVQueuePlayer 但是当第一个视频结束和第二个视频开始时会有一些延迟。
我需要它是样本同步的。也就是说,如果视频 1 长 10.25 秒,那么当我播放 11.5 秒时,视频 2 应该是 1.25 秒。
我一直在尝试保留 3 个 AVPlayer 对象,我使用相同的主时钟预滚动每个播放器。然后我试图拦截 AVPlayerItemDidPlayToEndTimeNotification
然后调用 setRate:time:atHostTime:
开始下一个视频。但是我没有播放任何视频。
我使用以下代码预滚动我的视频:
- (void) preRollPlayer: (AVPlayer*) pPlayer withMasterClock: (CMClockRef) masterClock atTime: (NSTimeInterval) time
{
[pPlayer setRate: 0.0f];
[pPlayer play];
[pPlayer seekToTime: CMTimeMakeWithSeconds( time, 1000000 ) toleranceBefore: kCMTimeZero toleranceAfter: kCMTimeZero];
[pPlayer setMasterClock: masterClock];
__block volatile int32_t completed = 0;
[pPlayer prerollAtRate: 1.0f completionHandler: ^( BOOL finished )
{
OSAtomicIncrement32( &completed );
}];
while( completed == 0 )
{
[NSThread sleepForTimeInterval: 0.01];
}
}
然后我按如下方式调用 preRoll:
if ( pAudioVideoEntry.beforeVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.beforeVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
{
[self preRollPlayer: pAudioVideoEntry.videoReader.player withMasterClock: hostClock atTime: currentTime];
}
if ( pAudioVideoEntry.afterVideoReader )
{
[self preRollPlayer: pAudioVideoEntry.afterVideoReader.player withMasterClock: hostClock atTime: currentTime];
}
最后我开始视频如下:
[pAudioVideoEntry.beforeVideoReader.player setRate: 1.0f time: kCMTimeZero atHostTime: syncTime];
pAudioVideoEntry.playingPlayer = pAudioVideoEntry.beforeVideoReader.player;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector( beforeVideoEnded: )
name: AVPlayerItemDidPlayToEndTimeNotification
object: pAudioVideoEntry.beforeVideoReader.playerItem];
奇怪的是,我听不到音频,从未发送通知,每次调用我的 AVPlayerItem
的输出 AVPlayerItemVideoOutput
的 hasNewPixelBufferForItemTime
returns 错误。所以我猜视频还没有开始。有什么想法吗?
所以在我 post 之后大约一个小时的经典风格(我花了一天的大部分时间为此而奋斗)我在这里找到了一个简单的解决方案:
使用 AVMutableComposition
我可以将每个视频按顺序添加到合成中,并获得完美的播放效果:
// Fill in the assets that make up the composition
CMTime time = kCMTimeZero;
for( AVAsset* pThisAsset in pAssets )
{
CMTimeRange timeRange = CMTimeRangeMake( kCMTimeZero, pThisAsset.duration );
[pComposition insertTimeRange: timeRange ofAsset: pThisAsset atTime: time error: nil];
time = CMTimeAdd( time, pThisAsset.duration );
}
我在播放视频图像与音频不同步时遇到一个小错误,但音频表现完美。也大大简化了我的代码!