AVPlayer播放视频(本地视频,或网络视频)

本文介绍如何使用AVPlayer播放本地或网络视频,并通过添加AVFoundation框架实现自定义播放器界面。文中详细展示了如何利用通知模式、观察者模式及时间观察者模式来监控播放状态,包括播放结束、播放状态变更及进度更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://github.com/potato512/SYAVPlayer

使用AVPlayer播放本地视频,或网络视频,需要添加AVFoundation框架。

使用AVPlayer播放视频的优势在于,开发者可以自定义视频界面。同时可以通过通知模式、观察者模式、时间观察者模式监测播放时的各种状态。

效果图


关键源码

// 导入头文件
#import "AVMoviePlayer.h"
// 定义属性
@property (nonatomic, strong) AVPlayer *player;
// 实例化
- (void)playMovie
{
    // 播放本地视频
    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"movie02" ofType:@"mov"];
    NSURL *url = [NSURL fileURLWithPath:urlStr];
    
    // 播放网络视频
//    NSString *urlStr = @"http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8";
//    NSURL *url = [NSURL URLWithString:urlStr];
    
    if (self.player)
    {
        // 已经创建则不再创建
        return;
    }
    
    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:url];
    self.player = [AVPlayer playerWithPlayerItem:item];
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    layer.frame = CGRectMake(10.0, 10.0, (self.view.bounds.size.width - 10.0 * 2), 200.0);
    [self.view.layer addSublayer:layer];
    [self.player play];
    
    // 设置KVC 播放结束
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playEndNotification:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    // 设置KVO
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    // 设置每秒执行一次进度更新
    AVPlayerVC __weak *weakSelf = self;
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        NSLog(@"1 current time = %.2f", current);
        
        float total = CMTimeGetSeconds([weakSelf.player.currentItem duration]);
        NSLog(@"2 total time = %.2f", total);
        
        if (current)
        {
            CGFloat progress = current / total;
            NSLog(@"3 progress = %.2f", progress);
        }
    }];
}
// 通知模式
// 视频播放完成
- (void)playEndNotification:(NSNotification *)notification
{
    NSLog(@"视频播放完成");
    [self.player seekToTime:kCMTimeZero];
}
// 观察者模式
// 通过KVO监控播放器的状态
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    AVPlayerItem *playerItem = object;
    if ([keyPath isEqualToString:@"status"])
    {
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
        if (status == AVPlayerStatusReadyToPlay)
        {
            NSLog(@"正在播放:%.2f", CMTimeGetSeconds(playerItem.duration));
        }
    }
    else if([keyPath isEqualToString:@"loadedTimeRanges"])
    {
        NSArray *array = playerItem.loadedTimeRanges;
        // 本次缓冲时间范围
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        // 缓冲总长度
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;
        NSLog(@"共缓冲:%.2f", totalBuffer);
    }
}
// 调用
- (void)playPause:(id)sender
{
    [self playMovie];
    if (self.player.rate == 0)
    {
        // 暂停时,继续播放
        [self.player play];
    }
    else if (self.player.rate == 1)
    {
        // 正在播放时,暂停
        [self.player pause];
    }
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番薯大佬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值