用AVFoundation AVPlayer循环播放视频?

yqkkidmi  于 2022-09-19  发布在  Swift
关注(0)|答案(20)|浏览(263)

在AVFoundation中有没有相对简单的循环播放视频的方法?

我已经创建了AVPlayer和AVPlayerLayer,如下所示:

avPlayer = [[AVPlayer playerWithURL:videoUrl] retain];
avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];

avPlayerLayer.frame = contentView.layer.bounds;
[contentView.layer addSublayer: avPlayerLayer];

然后我用以下方式播放我的视频:

[avPlayer play];

视频播放正常,但在结尾停止。对于MPMoviePlayerController,您所要做的就是将其repeatMode属性设置为正确的值。AVPlayer上似乎没有类似的特性。似乎也没有回调来告诉我电影什么时候结束,这样我就可以从头开始再放一遍。

我没有使用MPMoviePlayerController,因为它有一些严重的限制。我希望能够一次回放多个视频流。

mwecs4sa

mwecs4sa16#

我建议使用AVQueuePlayer来无缝循环您的视频。添加通知观察者

AVPlayerItemDidPlayToEndTimeNotification

在其选择器中,循环播放您的视频

AVPlayerItem *video = [[AVPlayerItem alloc] initWithURL:videoURL];
[self.player insertItem:video afterItem:nil];
[self.player play];
jecbmhm3

jecbmhm317#

斯威夫特5:

我对前面的回答做了一些细微的调整,比如在将playerItem添加到playerLayer之前将其添加到队列中。

let playerItem = AVPlayerItem(url: url)
let player = AVQueuePlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)

playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)

playerLayer.frame = cell.eventImage.bounds
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

// Add the playerLayer to a UIView.layer

player.play()

并将playerLooper设置为您的UIView控制器的属性,否则视频可能只播放一次。

irtuqstp

irtuqstp18#

以下是我最终为防止停顿-打嗝问题所做的事情:

SWIFT:

NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime,
                                       object: nil,
                                       queue: nil) { [weak self] note in
                                        self?.avPlayer.seek(to: kCMTimeZero)
                                        self?.avPlayer.play()
}

目标C:

__weak typeof(self) weakSelf = self; // prevent memory cycle
NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
[noteCenter addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
                        object:nil
                         queue:nil
                    usingBlock:^(NSNotification *note) {
                        [weakSelf.avPlayer seekToTime:kCMTimeZero];
                        [weakSelf.avPlayer play];
                    }];

**注意:**我没有使用avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone,因为它不需要。

wpx232ag

wpx232ag19#

SWIFT中:

当玩家结束时,您可以收到通知...检查AVPlayerItemDidPlayToEndTimeNotify

设置播放器时:

avPlayer.actionAtItemEnd = AVPlayerActionAtItemEnd.None

NSNotificationCenter.defaultCenter().addObserver(self, 
                                                 selector: "playerItemDidReachEnd:", 
                                                 name: AVPlayerItemDidPlayToEndTimeNotification, 
                                                 object: avPlayer.currentItem)

这将防止玩家在结束时停顿。

在通知中:

func playerItemDidReachEnd(notification: NSNotification) {
    if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
        playerItem.seekToTime(kCMTimeZero)
    }
}

Swift3

NotificationCenter.default.addObserver(self,
    selector: #selector(PlaylistViewController.playerItemDidReachEnd),
     name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
     object: avPlayer?.currentItem)

这将使电影倒带。

在释放播放器时,不要忘记注销通知。

rwqw0loc

rwqw0loc20#

在iOS/TVOS 10中,有一个新的AVPlayerLooper(),可以用来创建视频的无缝循环(Swift):

player = AVQueuePlayer()
playerLayer = AVPlayerLayer(player: player)
playerItem = AVPlayerItem(url: videoURL)
playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)
player.play()

这是在2016年WWDC上发表的《AVFoundation回放的进展》:https://developer.apple.com/videos/play/wwdc2016/503/

即使使用这段代码,我也遇到了一个问题,直到我向苹果提交了一份错误报告,并得到了以下回复:
电影持续时间长于音频/视频轨道的电影文件是问题所在。图播放器_文件正在禁用无缝过渡,因为音频曲目编辑比电影持续时间短(15.682比15.787)。

你需要修复电影文件,使电影时长和音轨时长相同,或者你可以使用AVPlayerLooper的时间范围参数(设置时间范围从0到音轨的时长)

事实证明,Premiere一直在导出音轨长度与视频略有不同的文件。在我的例子中,完全删除音频是可以的,这解决了问题。

相关问题