在我的应用程序中,ai已将所有视频网址加载到AVPlayer,它有前一个和下一个按钮,我有设置播放器
-(void)setUpMyNewPlayer
{
[self addTimer];
NSURL *url=[NSURL URLWithString:_videosArray[0]];
_currentIndex =0;
videoPlayer = [[AVPlayer alloc]init]; //WithPlayerItem:_avPlayerItem];
videoPlayer.automaticallyWaitsToMinimizeStalling = NO;
AVAsset *asset = [AVAsset assetWithURL:url];
[asset loadValuesAsynchronouslyForKeys:@[@"playable"] completionHandler:^{
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
videoPlayer = [AVPlayer playerWithPlayerItem:item];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:videoPlayer];
playerLayer.videoGravity = AVLayerVideoGravityResize;
playerLayer.frame = CGRectMake(0, 0, self.playView.frame.size.width, self.playView.frame.size.height);
[self.playView.layer addSublayer:playerLayer];
[videoPlayer play];
CMTime interval = CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
__weak typeof(self) weakSelf = self;
[videoPlayer addPeriodicTimeObserverForInterval:interval
queue:mainQueue
usingBlock:^(CMTime time) {
// Use weak reference to self
if (_currentIndex==_contentImages.count-1) {
weakSelf.nextButton.hidden=YES;
weakSelf.previousButton.hidden=NO;
}
else if (_currentIndex==0)
{
weakSelf.previousButton.hidden=YES;
if (_contentImages.count>1) {
weakSelf.nextButton.hidden=NO;
}
else
{
weakSelf.nextButton.hidden=YES;
}
}
else if (_currentIndex>0 && _currentIndex!=_contentImages.count-1)
{
// NSLog(@"Showing Both");
weakSelf.nextButton.hidden=NO;
weakSelf.previousButton.hidden=NO;
}
}];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying1:) name:AVPlayerItemDidPlayToEndTimeNotification object:item];
}];
}
-(void)itemDidFinishPlaying1:(NSNotification *) notification {
//
// Will be called when AVPlayer finishes playing playerItem
if (_currentIndex == _videosArray.count-1) {
}
else{
_currentIndex = _currentIndex+1;
NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]];
AVAsset *asset = [AVAsset assetWithURL:url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
[videoPlayer replaceCurrentItemWithPlayerItem:item];
[self changePage:UIPageViewControllerNavigationDirectionForward];
[self addTimer];
}
}
-(void)addTimer
{
myTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self
selector: @selector(callAfterOneSecond1:) userInfo: nil repeats: YES];
}
-(void) callAfterOneSecond1:(NSTimer*)t
{
[[AppDelegate shared] showLoading];
if (videoPlayer.rate !=0 && videoPlayer.error == nil && videoPlayer.status == AVPlayerStatusReadyToPlay) {
[[AppDelegate shared]removeLoading];
[myTimer invalidate];
myTimer=nil;
}
}
- (IBAction)previousButtonAction:(id)sender {
if (_currentIndex == 0) {
}
else{
_currentIndex = _currentIndex-1;
NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]];
AVAsset *asset = [AVAsset assetWithURL:url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
[videoPlayer replaceCurrentItemWithPlayerItem:item];
[videoPlayer play];
[self changePage:UIPageViewControllerNavigationDirectionReverse];
[self addTimer];
}
}
- (IBAction)nextButtonAction:(id)sender {
if (_currentIndex == _videosArray.count-1) {
}
else{
_currentIndex = _currentIndex+1;
NSURL *url=[NSURL URLWithString:_videosArray[_currentIndex]];
AVAsset *asset = [AVAsset assetWithURL:url];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
[videoPlayer replaceCurrentItemWithPlayerItem:item];
[videoPlayer play];
[self changePage:UIPageViewControllerNavigationDirectionForward];
[self addTimer];
}
}
这里的球员打得很好,但延迟很小。 。如何在播放当前视频的同时加载下一个即将播放的视频。
答案 0 :(得分:1)
我有点生疏,如果你想做任何稍微复杂的事情,整个AVFoundation的iOS文档都是不合适的。我这样做已经有一段时间了,但这样的事情应该有效(我假设你有一个NSArray*
,pAssets
包含你所有的视频AVAsset*
)
// Define the composition.
AVMutableComposition* pComposition = [AVMutableComposition composition];
// Define the tracks in the composition.
AVMutableCompositionTrack* pCompositionVideoTrack = [pComposition addMutableTrackWithMediaType: AVMediaTypeVideo preferredTrackID: 1];
AVMutableCompositionTrack* pCompositionAudioTrack = [pComposition addMutableTrackWithMediaType: AVMediaTypeAudio preferredTrackID: 2];
CMTime time = kCMTimeZero;
for ( AVAsset* pAssetsAsset in pAssets )
{
// Grab first video and audio tracks
AVAssetTrack* pAssetsAssetVideoTrack = [pAssetsAsset tracksWithMediaType: AVMediaTypeVideo].firstObject;
AVAssetTrack* pAssetsAssetAudioTrack = [pAssetsAsset tracksWithMediaType: AVMediaTypeAudio].firstObject;
// Get time range of entire video.
CMTimeRange timeRange = CMTimeRangeMake( kCMTimeZero, timepAssetsAsset.duration );
// Insert the entire video and audio into their respective tracks at "time".
NSError* pVideoError = nil;
NSError* pAudioError = nil;
[pCompositionVideoTrack insertTimeRange: timeRange ofTrack: pAssetsAssetVideoTrack atTime: time error: &pVideoError];
[pCompositionAudioTrack insertTimeRange: timeRange ofTrack: pAssetsAssetAudioTrack atTime: time error: &pAudioError];
// Move time along appropriately.
time = CMTimeAdd( time, pAssetsAsset.duration );
}
如果您然后传递AVMutableComposition
来自AVAsset
,那么您可以正常使用它并将其放入AVPlayer
(通过AVPlayerItem
)。
现在,您可以搜索视频中的任何一点。存储每个视频的开始/结束点,您可以轻松找到它。
编辑:它使用AVPlayer非常简单。首先,你需要创建一个AVPlayerItem ..然后你需要播放它。
AVPlayerItem* pPlayerItem = [AVPlayerItem playerItemWithAsset: pComposition];
AVPlayer* pPlayer = [AVPlayer playerWithPlayerItem: pPlayerItem];
现在您需要将其附加到视图层。所以从你的ViewController里面做这样的事情:
AVPlayerLayer* pLayer = [AVPlayerLayer playerLayerWithPlayer: pPlayer];
[self.view.layer addSublayer: pLayer];
答案 1 :(得分:0)
使用AVQueuePlayer
代替简单AVPlayer
。在当前视频结束时,它将预加载下一个视频。
在此处查看如何使用AVQueuePlayer
:https://stackoverflow.com/a/22785665/1271424