orj*_*orj 139 objective-c avfoundation ios avplayer swift
在AVFoundation中有一种相对简单的循环视频方式吗?
我已经创建了我的AVPlayer和AVPlayerLayer:
avPlayer = [[AVPlayer playerWithURL:videoUrl] retain];
avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];
avPlayerLayer.frame = contentView.layer.bounds;
[contentView.layer addSublayer: avPlayerLayer];
Run Code Online (Sandbox Code Playgroud)
然后我播放我的视频:
[avPlayer play];
Run Code Online (Sandbox Code Playgroud)
视频播放正常但最后停止播放.使用MPMoviePlayerController,您只需将其repeatMode属性设置为正确的值即可.AVPlayer似乎没有类似的属性.似乎没有一个回调可以告诉我什么时候电影结束所以我可以寻找开头并再次播放它.
我没有使用MPMoviePlayerController,因为它有一些严重的限制.我希望能够一次播放多个视频流.
Bas*_*ian 271
玩家结束时可以获得通知.校验AVPlayerItemDidPlayToEndTimeNotification
设置播放器时:
ObjC
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[avPlayer currentItem]];
Run Code Online (Sandbox Code Playgroud)
这样可以防止玩家在结束时暂停.
在通知中:
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[p seekToTime:kCMTimeZero];
}
Run Code Online (Sandbox Code Playgroud)
这将回放电影.
不要忘记在释放播放器时取消注册通知.
迅速
avPlayer?.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: .AVPlayerItemDidPlayToEndTime,
object: avPlayer?.currentItem)
@objc func playerItemDidReachEnd(notification: Notification) {
if let playerItem = notification.object as? AVPlayerItem {
playerItem.seek(to: kCMTimeZero)
}
}
Run Code Online (Sandbox Code Playgroud)
Nab*_*bha 52
如果它有帮助,在iOS/tvOS 10中,有一个新的AVPlayerLooper()可用于创建无缝的视频循环(Swift):
player = AVQueuePlayer()
playerLayer = AVPlayerLayer(player: player)
playerItem = AVPlayerItem(url: videoURL)
playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)
player.play()
Run Code Online (Sandbox Code Playgroud)
这是在WWDC 2016的"AVFoundation Playback的进展"中提出的:https: //developer.apple.com/videos/play/wwdc2016/503/
即使使用这段代码,在我向Apple提交错误报告并获得此回复之前,我还是有一个打嗝:
电影持续时间长于音频/视频轨道的电影文件是问题.FigPlayer_File正在禁用无间隙转换,因为音轨编辑比电影持续时间短(15.682 vs 15.787).
您需要修复影片文件以使影片持续时间和轨道持续时间长度相同,或者您可以使用AVPlayerLooper的时间范围参数(设置时间范围从0到音轨的持续时间)
事实证明,Premiere一直在导出文件的音轨长度与视频略有不同.在我的情况下,完全删除音频是很好的,这解决了问题.
Kin*_*ard 26
在Swift中:
当玩家结束时你可以获得通知...检查AVPlayerItemDidPlayToEndTimeNotification
设置播放器时:
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEnd.None
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: avPlayer.currentItem)
Run Code Online (Sandbox Code Playgroud)
这样可以防止玩家在结束时暂停.
在通知中:
func playerItemDidReachEnd(notification: NSNotification) {
if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem {
playerItem.seekToTime(kCMTimeZero)
}
}
Run Code Online (Sandbox Code Playgroud)
Swift3
NotificationCenter.default.addObserver(self,
selector: #selector(PlaylistViewController.playerItemDidReachEnd),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer?.currentItem)
Run Code Online (Sandbox Code Playgroud)
这将回放电影.
不要忘记在释放播放器时取消注册通知.
Isl*_* Q. 17
以下是我为防止暂停打嗝问题而采取的措施:
迅速:
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime,
object: nil,
queue: nil) { [weak self] note in
self?.avPlayer.seek(to: kCMTimeZero)
self?.avPlayer.play()
}
Run Code Online (Sandbox Code Playgroud)
目标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];
}];
Run Code Online (Sandbox Code Playgroud)
注意:我没有使用,avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone因为它不需要.
斯威夫特 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()
Run Code Online (Sandbox Code Playgroud)
并让 playerLooper 成为你的 UIViewController 的一个属性,否则视频只能播放一次。