AVPlayer的基本使用

來源:互聯網
上載者:User

標籤:

在iOS開發中,播放視頻通常有兩種方式,一種是使用MPMoviePlayerController(需要匯入MediaPlayer.Framework),還有一種是使用AVPlayer。關於這兩個類的區別可以參考http://stackoverflow.com/questions/8146942/avplayer-and-mpmovieplayercontroller-differences,簡而言之就是MPMoviePlayerController使用更簡單,功能不如AVPlayer強大,而AVPlayer使用稍微麻煩點,不過功能更加強大。這篇部落客要介紹下AVPlayer的基本使用,由於博主也是剛剛接觸,所以有問題大家直接指出~

  在開發中,單純使用AVPlayer類是無法顯示視頻的,要將視頻層添加至AVPlayerLayer中,這樣才能將視頻顯示出來,所以先在ViewController的@interface中添加以下屬性

@property (nonatomic ,strong) AVPlayer *player;@property (nonatomic ,strong) AVPlayerItem *playerItem;@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

+ (Class)layerClass { return [AVPlayerLayer class];} - (AVPlayer *)player { return [(AVPlayerLayer *)[self layer] player];} - (void)setPlayer:(AVPlayer *)player {    [(AVPlayerLayer *)[self layer] setPlayer:player];}

然後在viewDidLoad中執行初始化:

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]; [[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 of AVPlayerItemTrack—that correspond to the tracks in the asset.)

然後監聽playerItem的status和loadedTimeRange屬性,status有三種狀態:

AVPlayerStatusUnknown,

AVPlayerStatusReadyToPlay,

AVPlayerStatusFailed

當status等於AVPlayerStatusReadyToPlay時代表視頻已經可以播放了,我們就可以調用play方法播放了。

loadedTimeRange屬性代表已經緩衝的進度,監聽此屬性可以在UI中更新緩衝進度,也是很有用的一個屬性。

最後添加一個通知,用於監聽視頻是否已經播放完畢,然後實現KVO的方法:

- (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;// 擷取視頻總長度 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方法:

- (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做一些自訂,代碼如下:

- (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


AVPlayer的基本使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.