[转]AVPlayer的基本使用

在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要导入MediaPlayer.Framework),还有一种是使用AVPlayer。关于这两个类的区别可以参考http://stackoverflow.com/questions/8146942/avplayer-and-mpmovieplayercontroller-differences,简而言之就是MPMoviePlayerController使用更简单,功能不如AVPlayer强大,而AVPlayer使用稍微麻烦点,不过功能更加强大。这篇博客主要介绍下AVPlayer的基本使用,由于博主也是刚刚接触,所以有问题大家直接指出~

  在开发中,单纯使用AVPlayer类是无法显示视频的,要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来,所以先在ViewController的@interface中添加以下属性


1

2

@property (nonatomic ,strong) AVPlayer *player;

@property (nonatomic ,strong) AVPlayerItem *playerItem;<br>@property (nonatomic ,weak) IBOutletPlayerView *playerView;

其中playerView继承自UIView,不过重写了set和get方法,用于将player添加至playerView的AVPlayerLayer中,这样才能顺利将视频显示出来

在PlayerView.h中声明一个AVPlayer对象,由于默认的layer是CALayer,而AVPlayer只能添加至AVPlayerLayer中,所以我们改变一下layerClass,这样PlayerView的默认layer就变了,之后我们可以把在viewController中初始化的AVPlayer对象赋给AVPlayerLayer的player属性。

 PlayerView.h 

 @property (nonatomic ,strong) AVPlayer *player;

 PlayerView.m


1

2

3

4

5

6

7

8

9

10

11

+ (Class)layerClass {

    return [AVPlayerLayer class];

}

- (AVPlayer *)player {

    return [(AVPlayerLayer *)[self layer] player];

}

- (void)setPlayer:(AVPlayer *)player {

    [(AVPlayerLayer *)[self layer] setPlayer:player];

}

然后在viewDidLoad中执行初始化:


1

2

3

4

5

NSURL *videoUrl = [NSURL URLWithString:@"http://www.jxvdy.com/file/upload/201405/05/18-24-58-42-627.mp4"];

self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];

[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 监听status属性

[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听loadedTimeRanges属性

self.player = [AVPlayer playerWithPlayerItem:self.playerItem];<br>[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotificationobject:self.playerItem];

先将在线视频链接存放在videoUrl中,然后初始化playerItem,playerItem是管理资源的对象(A player item manages the presentation state of an asset with which it is associated. A player item contains player item tracks—instances ofAVPlayerItemTrack—that correspond to the tracks in the asset.)

然后监听playerItem的status和loadedTimeRange属性,status有三种状态:

AVPlayerStatusUnknown,

AVPlayerStatusReadyToPlay,

AVPlayerStatusFailed

当status等于AVPlayerStatusReadyToPlay时代表视频已经可以播放了,我们就可以调用play方法播放了。

loadedTimeRange属性代表已经缓冲的进度,监听此属性可以在UI中更新缓冲进度,也是很有用的一个属性。

最后添加一个通知,用于监听视频是否已经播放完毕,然后实现KVO的方法:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    AVPlayerItem *playerItem = (AVPlayerItem *)object;

    if ([keyPath isEqualToString:@"status"]) {

        if ([playerItem status] == AVPlayerStatusReadyToPlay) {

            NSLog(@"AVPlayerStatusReadyToPlay");

            self.stateButton.enabled = YES;

            CMTime duration = self.playerItem.duration;// 获取<span id="2_nwp" style="width: auto; height: auto; float: none;"><a id="2_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Edaxueit%2Ecom%2Farticle%2F3407%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=00007110_cpr&k=%CA%D3%C6%B5&k0=ios&kdi0=8&k1=%C8%ED%BC%FE&kdi1=8&k2=%C8%ED%BC%FE%BF%AA%B7%A2&kdi2=8&k3=%C6%BB%B9%FB&kdi3=8&k4=block&kdi4=8&k5=%CA%D3%C6%B5&kdi5=8&sid=2e3a805149a5f46f&ch=0&tu=u1704338&jk=6e6f3626bb79a9f4&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=6&seller_id=1&di=128" target="_blank" mpid="2" style="text-decoration: none;"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">视频</span></a></span>总长度

            CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;// 转换成秒

            _totalTime = [self convertTime:totalSecond];// 转换成播放时间

            [self customVideoSlider:duration];// 自定义UISlider外观

            NSLog(@"movie total duration:%f",CMTimeGetSeconds(duration));

            [self monitoringPlayback:self.playerItem];// 监听播放状态

        } else if ([playerItem status] == AVPlayerStatusFailed) {

            NSLog(@"AVPlayerStatusFailed");

        }

    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {

        NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度

        NSLog(@"Time Interval:%f",timeInterval);

        CMTime duration = self.playerItem.duration;

        CGFloat totalDuration = CMTimeGetSeconds(duration);

        [self.videoProgress setProgress:timeInterval / totalDuration animated:YES];

    }

}

- (NSTimeInterval)availableDuration {

    NSArray *loadedTimeRanges = [[self.playerView.player currentItem] loadedTimeRanges];

    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域

    float startSeconds = CMTimeGetSeconds(timeRange.start);

    float durationSeconds = CMTimeGetSeconds(timeRange.duration);

    NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度

    return result;

}

- (NSString *)convertTime:(CGFloat)second{

    NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

    if (second/3600 >= 1) {

        [formatter setDateFormat:@"HH:mm:ss"];

    } else {

        [formatter setDateFormat:@"mm:ss"];

    }

    NSString *showtimeNew = [formatter stringFromDate:d];

    return showtimeNew;

}

此方法主要对status和loadedTimeRanges属性做出响应,status状态变为AVPlayerStatusReadyToPlay时,说明视频已经可以播放了,这时我们可以获取一些视频的信息,包含视频长度等,把播放按钮设备enabled,点击就可以调用play方法播放视频了。在AVPlayerStatusReadyToPlay的底部还有个monitoringPlayback方法:


1

2

3

4

5

6

7

8

- (void)monitoringPlayback:(AVPlayerItem *)playerItem {

    self.playbackTimeObserver = [self.playerView.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {

        CGFloat currentSecond = playerItem.currentTime.value/playerItem.currentTime.timescale;// 计算当前在第几秒

        [self updateVideoSlider:currentSecond];

        NSString *timeString = [self convertTime:currentSecond];

        self.timeLabel.text = [NSString stringWithFormat:@"%@/%@",timeString,_totalTime];

    }];

}

monitoringPlayback用于监听每秒的状态,- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;此方法就是关键,interval参数为响应的间隔时间,这里设为每秒都响应,queue是队列,传NULL代表在主线程执行。可以更新一个UI,比如进度条的当前时间等。

  作为播放器,除了播放,暂停等功能外。还有一个必不可少的功能,那就是显示当前播放进度,还有缓冲的区域,我的思路是这样,用UIProgressView显示缓冲的可播放区域,用UISlider显示当前正在播放的进度,当然这里要对UISlider做一些自定义,代码如下:


1

2

3

4

5

6

7

8

9

- (void)customVideoSlider:(CMTime)duration {

    self.videoSlider.maximumValue = CMTimeGetSeconds(duration);

    UIGraphicsBeginImageContextWithOptions((CGSize){ 1, 1 }, NO, 0.0f);

    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    

    [self.videoSlider setMinimumTrackImage:transparentImage forState:UIControlStateNormal];

    [self.videoSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];

}

这样UISlider就只有中间的ThumbImage了,而ThumbImage左右的颜色都变成透明的了,仅仅是用于显示当前的播放时间。UIProgressView则用于显示当前缓冲的区域,不做任何自定义的修改,在StoryBoard看起来是这样的:

把UISlider添加至UIProgressView上面,运行起来的效果就变成了这样:

这样基本的缓冲功能就做好了,当然还有一些功能没做,比如音量大小,滑动屏幕快进快退等,大家有时间可以自己做着玩儿下~ 最后的效果如下:

最后附上demo链接:https://github.com/mzds/AVPlayerDemo

时间: 2024-10-28 21:21:51

[转]AVPlayer的基本使用的相关文章

iOS - AVPlayer 音视频播放

iOS - AVPlayer 音视频播放 本文目录 前言 1.本地/网络音视频播放 2.本地/网络音视频播放设置 3.AVPlayerViewControllerDelegate 画中画协议方法 回到顶部 前言 NS_CLASS_AVAILABLE(10_7, 4_0) @interface AVPlayer : NSObject @available(iOS 4.0, *) public class AVPlayer : NSObject NS_CLASS_AVAILABLE_IOS(8_0)

第六篇、AVplayer地址视频播放控件

1.引用头文件#import AVFoundation 2.自定义AVPlayer(播放的机器) 3.自定义AVPlayerItem(胶片) >> 视频的URL转成AVAsset 4.AVPlayerLayer(白板)

iOS AVPlayer 学习

1 .使用环境: 在实际开发过程中 有需要展示流媒体的模块 ,需求非常简单 :播放 和 暂停 ,其实这个时候有很多选择 ,可以选择 MPMoviePlayerController(MediaPlayer.framework), AVAudioPlayer(AVFunction.framework) 但是考虑到扩展性,高度自定义性  我选择使用 AVPlayer. 事实是对的  后来需求又增加了, 还需要展示播放进度,缓冲进度,变化时间,视频时长等,还有对UI有要求,甚至不为过的说 要苹果手机那个

AVPlayer

AVPlayer的功能很强大,既可以播放视频, 也可以播放音频, 既可以播放本地的, 也可以播放网络的; 下面是我封装的一个AVPlayer的Demo,在ViewController中实现 工程中的所有东西如下: 创建一个PlayView类,PlayView.h中的代码如下 #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @class PlayView; @protocol PlayViewDelegate

播放器: AVPlayer

AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:@"http://flv2.bn.netease.com/videolib3/1511/30/wvCOz5519/SD/wvCOz5519-mobile.mp4"]];    //视频展示涂层    AVPlayerLayer *playLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];   

avplayer 播放视频

最近在做一个小学生教育方面的项目,要在应用中看各种各样的小故事,所以要用到视频,刚把视频方面的东西搞好,在这里稍微的分享一下 首先介绍几个方法吧和属性吧. - (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block 这个方法可以用于跟新进度条. - (void)seekToTime:(CMTime)ti

AVPlayer的使用,带缓冲

#import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController () { AVPlayer *player; AVPlayerItem *playerItem; UIProgressView * progressView; UISlider *_slider; //推断slider是否按下, BOOL isOpen; } @end @implementati

iOS AVPlayer 后台播放问题自动停止问题 防止应用被后台挂起方法

iOS AVPlayer 后台播放问题自动停止问题 防止应用被后台挂起方法 2016-09-08 16:16 1597人阅读 评论(0) 收藏 举报  分类: iOS 开发笔记(37)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 1.创建播放器时创建AVAudioSession [objc] view plain copy AVAudioSession *session = [AVAudioSessionsharedInstance]; [session setCa

iOS AvPlayer AvAudioPlayer音频的后台播放问题

王桂敏 iOS AvPlayer AvAudioPlayer音频的后台播放问题 iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能. 首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionC

iOS开发 - AVPlayer实现流音频边播边存

边播边下有三套左右实现思路,本文使用AVPlayer + AVURLAsset实现. 概述 1. AVPlayer简介 AVPlayer存在于AVFoundation中,可以播放视频和音频,可以理解为一个随身听 AVPlayer的关联类: AVAsset:一个抽象类,不能直接使用,代表一个要播放的资源.可以理解为一个磁带子类AVURLAsset是根据URL生成的包含媒体信息的资源对象.我们就是要通过这个类的代理实现音频的边播边下的 AVPlayerItem:可以理解为一个装在磁带盒子里的磁带 2