iOS 에서 영상 재생 의 기본 방법 요약
본 고 는 iOS 에서 가장 흔히 볼 수 있 는 영상 재생 방법 을 정리 하고 서로 다른 방법 이 모두 특징 을 가지 기 때문에 저 는 그들의 차이 점 을 정리 하고 개발 에서 적당 한 기술 방안 을 선택 하 는 데 편리 하 기 를 바 랍 니 다.
애플 은 MPMoviePlayer Controller,MPMoviePlayer View Controller,AVPlayer,AVPlayer View Controller 등 다양한 방법 을 제공 했다.주의해 야 할 것 은 상기 MPMoviePlayerController 와 MPMoviePlayerViewController 가 iOS 9.0 이후 버 려 졌 다 는 점 이다.그럼 에 도 불구 하고 이것 은 그들의 용법 을 정리 한 것 입 니 다.다음은 네 가지 재생 방식 의 차 이 를 간단하게 알 아 보 겠 습 니 다.
iOS 동 영상 재생.png
훈훈 한 알림:코드 가 더욱 직관 적 이 므 로 먼저 본문 Demo 를 첨부 합 니 다. ( 로 컬 다운로드 )
1.MPMoviePlayerController
1.동 영상 재생
MPMovie wPlayerController 는 NSObject 에 계승 되 어 동 영상 을 재생 하려 면 보기 컨트롤 러 의 View 에 비디오 View 를 추가 해 야 동 영상 을 표시 할 수 있 습 니 다.사용 절 차 는 다음 과 같 습 니 다.
: MediaPlayer , PlayerController
#import <mediaplayer mediaplayer.h>
@property(nonatomic,strong)MPMoviePlayerController *playerController;
// : ,
//
NSString* localFilePath=[[NSBundle mainBundle]pathForResource:@" " ofType:@"mp4"];
NSURL *localVideoUrl = [NSURL fileURLWithPath:localFilePath];
//
NSString *webVideoPath = @"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1115.mp4";
NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath];
self.playerController =[[MPMoviePlayerController alloc]initWithContentURL:webVideoUrl];
// : Frame View View
self.playerController.view.frame = CGRectMake(0, 10, kDeviceWidth, 300);
[self.view addSubview: self.playerController.view];
// :
// : , , ,
self.playerController.controlStyle = MPMovieControlStyleDefault;
// ( YES)
self.playerController.shouldAutoplay = NO;
// , , Fill
self.playerController.scalingMode = MPMovieScalingModeAspectFit;
//
self.playerController.repeatMode = MPMovieRepeatModeOne;
// :
// ,
[ self.playerController prepareToPlay];
// ,
//[ self.playerController play];
// : , ,
- (void)dealloc{
// pop ,
[self.playerController stop];
self.playerController = nil;
//
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
2.동 영상 재생 관련 알림MPMoviePlayer Controller 와 관련 된 영상 재생 의 많은 상태 통 제 는 알림 을 통 해 이 루어 집 니 다.특히 온라인 영상 을 재생 할 때 저 희 는 영상 로드 의 성공 여 부 를 감시 할 뿐만 아니 라 영상 캐 시 진도 등 도 모니터링 합 니 다.여기 서 자주 사용 하 는 알림 을 다음 과 같이 보 여 줍 니 다.
// ( , SDK)
NSNotificationCenter *notificaionCenter = [NSNotificationCenter defaultCenter];
//
[notificaionCenter addObserver:self
selector:@selector(playerStateChanged:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:nil];
//
[notificaionCenter addObserver:self
selector:@selector(playerFinished) name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
//
[notificaionCenter addObserver:self
selector:@selector(palyerChangeFullScreen) name:MPMoviePlayerDidEnterFullscreenNotification
object:nil];
//
[notificaionCenter addObserver:self
selector:@selector(playerCaptureFinished:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification
object:nil];
#pragma mark -
// ,
- (void)playerStateChanged:(NSNotification *)notificaion{
switch (self.playerController.playbackState) {
case MPMoviePlaybackStateStopped:{
NSLog(@" ");
break;
}
case MPMoviePlaybackStatePlaying:{
NSLog(@" ");
break;
}
case MPMoviePlaybackStatePaused:{
NSLog(@" ");
break;
}
case MPMoviePlaybackStateInterrupted:{
NSLog(@" ");
break;
}
case MPMoviePlaybackStateSeekingForward:{
NSLog(@" ");
break;
}
case MPMoviePlaybackStateSeekingBackward:{
NSLog(@" ");
break;
}
default:
break;
}
}
//
- (void)playerFinished{
NSLog(@"playerFinished: ");
}
//
- (void)palyerChangeFullScreen{
NSLog(@"palyerChangeFullScreen: ");
}
//
- (void)playerCaptureFinished:(NSNotification *)notification{
//
UIImage *image=notification.userInfo[MPMoviePlayerThumbnailImageKey];
self.captureImgView.image = image;
}
3.캡 처 실현
// ,
_captureBtn = [[UIButton alloc] initWithFrame:CGRectMake(30, CGRectGetMaxY(self.playerController.view.frame) + 30, kDeviceWidth - 30 * 2, 50)];
_captureBtn.backgroundColor = [UIColor purpleColor];
[_captureBtn setTitle:@" " forState: UIControlStateNormal];
[_captureBtn addTarget:self action:@selector(captureCurrentScreenImg) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_captureBtn];
// ImgView
_captureImgView = [[UIImageView alloc] initWithFrame:CGRectMake((kDeviceWidth - 150)/2, CGRectGetMaxY(_captureBtn.frame) + 20, 150, 150)];
_captureImgView.contentMode = UIViewContentModeScaleAspectFit;
_captureImgView.backgroundColor = [UIColor grayColor];
[self.view addSubview:_captureImgView];
//
- (void)captureCurrentScreenImg{
[self.playerController requestThumbnailImagesAtTimes:@[@(self.playerController.currentPlaybackTime)] timeOption:MPMovieTimeOptionNearestKeyFrame];
}
// : ,
- (void)playerCaptureFinished:(NSNotification *)notification{
UIImage *image=notification.userInfo[MPMoviePlayerThumbnailImageKey];
self.captureImgView.image = image;
}
2.MPMoviePlayerViewControllerMPMovicePlayerViewController 는 전체 화면 에서 만 영상 을 재생 할 수 있 습 니 다.MPMoviePlayerController 형식 속성 을 포함 하 는 특수 보기 컨트롤 러 이기 때문에 모드 보기 팝 업 방식 으로 영상 을 표시 합 니 다.이 를 이해 하면 우 리 는 MPMovicePlayerViewController 를 사용 할 때 우 리 는 그의 MPMoviePlayerController 속성 을 통 해 많은 플레이어 의 속성 을 설정 할 수 있다 는 것 을 알 수 있다.구체 적 인 용법 은 MPMoviePlayerController 와 같 지만 많은 설명 에 불과 하 다.동 영상 을 재생 하 는 코드 예 는 다음 과 같다.
// :
//
NSString* localFilePath=[[NSBundle mainBundle]pathForResource:@" " ofType:@"mp4"];
NSURL *localVideoUrl = [NSURL fileURLWithPath:localFilePath];
//
//NSString *webVideoPath = @"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1115.mp4";
//NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath];
// :
MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:localVideoUrl];
// :
// moviePlayer ( MPMoviePlayerController )
playerViewController.moviePlayer.scalingMode = MPMovieScalingModeFill;
// :
[self presentViewController:playerViewController animated:YES completion:nil];
3.AVPlayerAVPlayer 는 상기 두 가지 방식 에 비해 영상 재생 기능 이 더욱 강하 고 사용 도 유연 하 다.왜냐하면 이것 은 밑바닥 에 더욱 가 깝 기 때문이다.그러나 AVPlayer 자 체 는 동 영상 을 직접 표시 할 수 없습니다.재생 층 AVPlayer Layer 를 만 들 고 다른 보기 Layer 에 추가 해 야 표시 할 수 있 습 니 다.
1.AVPlayer 를 사용 할 때 알 아야 할 상용 클래스
// : AVFoundation ,
#import <AVFoundation/AVFoundation.h>
@property (nonatomic,strong)AVPlayer *player;//
@property (nonatomic,strong)AVPlayerItem *currentPlayerItem;
// : URL
//
NSString* localFilePath=[[NSBundle mainBundle]pathForResource:@" " ofType:@"mp4"];
NSURL *localVideoUrl = [NSURL fileURLWithPath:localFilePath];
//
NSString *webVideoPath = @"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1129.mp4";
NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath];
// : ( )
// URL AVPlayer AVPlayerItem
//self.player = [AVPlayer playerWithURL:localVideoUrl];
//self.player = [[AVPlayer alloc] initWithURL:localVideoUrl];
//self.player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:webVideoUrl];
self.currentPlayerItem = playerItem;
self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
// : AVPlayerLayer, ,
//contentView View,
/*
AVLayerVideoGravityResizeAspectFill ,
AVLayerVideoGravityResizeAspect
AVLayerVideoGravityResize
*/
AVPlayerLayer *avLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
avLayer.videoGravity = AVLayerVideoGravityResizeAspect;
avLayer.frame = _containerView.bounds;
[_containerView.layer addSublayer:avLayer];
// : play ,
//
// AVPlayerItem status AVPlayerStatusReadyToPlay
[self.player play];
3.속성 관찰 추가AVPlayer Item 대상 이 동 영상 에 대응 하고 있 습 니 다.저 희 는 AVPlayer Item 을 통 해 동 영상 속성 을 가 져 와 야 합 니 다.그러나 AVPlayer Item 은 재생 이 가능 할 때 까지 비디오 자원 을 불 러 와 야 사용 할 수 있 는데 이것 은 네트워크 에 제 한 된 이유 이다.이 문 제 를 해결 하려 면 AVPlayer Item 의 status 속성 을 KVO 로 모니터링 해 야 합 니 다.AVPlayer Item Status Ready ToPlay 일 때 영상 관련 속성 을 얻 을 수 있 습 니 다.관련 코드 예 시 는 다음 과 같다.
//1. ,
// Status ,
[self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
// loadedTimeRanges, ,
[self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
//2.
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
AVPlayerItem *playerItem = (AVPlayerItem *)object;
if ([keyPath isEqualToString:@"status"]) {
// playerItem status
AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
switch (status) {
case AVPlayerStatusReadyToPlay:{
//
CMTime duration = playerItem.duration;
// : ( )
self.totalNeedPlayTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(duration)];
//
self.sliderView.enabled = YES;
// Loading
[self showaAtivityInDicatorView:NO];
//
[self.player play];
break;
}
case AVPlayerStatusFailed:{// ,
[self showaAtivityInDicatorView:NO];// Loading
self.playerInfoButton.hidden = NO; // ,
[self.playerInfoButton setTitle:@" , " forState: UIControlStateNormal];
break;
}
case AVPlayerStatusUnknown:{
NSLog(@" :AVPlayerStatusUnknown");
break;
}
default:
break;
}
} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
// ,
NSArray *loadedTimeRanges = playerItem.loadedTimeRanges;
//
CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];
//
NSTimeInterval loadStartSeconds = CMTimeGetSeconds(timeRange.start);
//
NSTimeInterval loadDurationSeconds = CMTimeGetSeconds(timeRange.duration);
//
NSTimeInterval currentLoadTotalTime = loadStartSeconds + loadDurationSeconds;
//NSLog(@" :%f, :%f, :%f", loadStartSeconds, loadDurationSeconds, currentLoadTotalTime);
// :
_currentLoadTimeLabel.text = [self formatTimeWithTimeInterVal:currentLoadTotalTime];
// :
_totalNeedLoadTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(self.player.currentItem.duration)];
// :
_progressView.progress = currentLoadTotalTime/CMTimeGetSeconds(self.player.currentItem.duration);
}
}
//
- (NSString *)formatTimeWithTimeInterVal:(NSTimeInterval)timeInterVal{
int minute = 0, hour = 0, secend = timeInterVal;
minute = (secend % 3600)/60;
hour = secend / 3600;
secend = secend % 60;
return [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, secend];
}
4.현재 재생 시간 과 총 시간 가 져 오기그 전에 우 리 는 먼저 데이터 형식 을 알 아야 한다.즉,상기 작업 중의 CMTime 이다.AVPlayer 의 사용 에서 우 리 는 이 를 자주 사용 할 것 이다.사실은 CMTime 은 다음 과 같은 구조 체 이다.
typedef struct{
CMTimeValue value; //
CMTimeScale timescale; // ( )
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTi
위의 작업 에서 우 리 는 AVPlayer Item 의 Duration 속성 이 바로 CMTime 형식의 데이터 라 는 것 을 보 았 다.따라서 동 영상 을 가 져 오 는 총 시간(초)은 duration.value/duration.timescale 이 필요 합 니 다.물론 시스템 도 우리 에 게 CMTimeGetSeconds 함 수 를 제공 하여 계산 하기에 더욱 편리 하 다.총 시간:duration.value=CMTimeGetSeconds(duration).
동 영상 이 어느 위치 에 들 어 갈 때 도 CMTime 을 매개 변수 로 만들어 야 합 니 다.그러면 CMTime 의 생 성 방법 은 두 가지 가 있 습 니 다.
// 1:
CMTimeMakeWithSeconds(Flout64 seconds, int32_t scale)
// 2:
CMTimeMake(int64_t value, int32_t scale)
// : float
동 영상 을 가 져 오 는 총 시간 은 상기 코드 에 나타 나 는데 재생 상태 가 AVPlayer Status Ready ToPlay 로 바 뀌 었 을 때 가 져 온 것 입 니 다.
// , AVPlayerItem AVPlayerStatusReadyToPlay
CMTime duration = self.player.currentItem.duration;
CGFloat totalTime = CMTimeGetSeconds(duration);
// AVPlayer
CMTime cmTime = self.player.currentTime;
CGFloat currentTime = CMTimeGetSeconds(cmTime);
5.재생 진도 와 상태 리 셋현재 재생 시간 을 실시 간 으로 업데이트 합 니 다.이때 우 리 는 타 이 머 를 사용 할 필요 가 없습니다.왜냐하면 AVPlayer 가 이미 방법 을 제 공 했 기 때 문 입 니 다.
addPeriodicTimeObserverForInterval: queue: usingBlock。재생 진도 가 바 뀌 었 을 때 방법 중의 리 셋 이 실 행 됩 니 다.우 리 는 여기에서 새로 고침 시간 을 조작 할 수 있 습 니 다.코드 예 시 는 다음 과 같 습 니 다.
__weak __typeof(self) weakSelf = self;
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
//
NSTimeInterval currentTime = CMTimeGetSeconds(time);
//
NSTimeInterval totalTime = CMTimeGetSeconds(weakSelf.player.currentItem.duration);
//
weakSelf.sliderView.value = currentTime/totalTime;
// : 00:00:00
weakSelf.currentTimeLabel.text = [weakSelf formatTimeWithTimeInterVal:currentTime];
}];
6.슬라이더 드래그 로 비디오 재생 진행 수정
//UISlider : ,
- (IBAction)sliderViewChange:(id)sender {
if(self.player.status == AVPlayerStatusReadyToPlay){
NSTimeInterval playTime = self.sliderView.value * CMTimeGetSeconds(self.player.currentItem.duration);
CMTime seekTime = CMTimeMake(playTime, 1);
[self.player seekToTime:seekTime completionHandler:^(BOOL finished) {
}];
}
}
4.AVPlayerViewControllerAVPlayerViewController 는 iOS 8 에 추 가 된 비디오 프레임 워 크 AVKit 의 플레이어 클래스 입 니 다.iOS 9 가 앞의 두 가지 플레이어 류 를 버 리 는 이유 로 AVPlayerViewController 도 더욱 자주 사용 된다.AVPlayerViewController 는 재생 인터페이스 개발 에 적합 하 며 요구 가 높 지 않 은 응용 프로그램 입 니 다.AVPlayer 보다 사용 이 편리 하지만 원리 적 으로 는 AVPlayer ViewController 에 AVPlayer 대상 이 포함 되 어 있 습 니 다.
AVPlayerViewController 는 동 영상 을 재생 하 는 두 가지 방식 이 있 습 니 다.
첫 번 째:직접 팝 업 모드 보기 컨트롤 러 재생
// 1:
NSString *webVideoPath = @"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1213.mp4";
NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath];
// 2: AVPlayer
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:webVideoUrl];
// 3: AVPlayer AVPlayerViewController,
AVPlayerViewController *avPlayerVC =[[AVPlayerViewController alloc] init];
avPlayerVC.player = avPlayer;
[self presentViewController:avPlayerVC animated:YES completion:nil];
두 번 째:AVPlayerViewController 의 View 를 부모 보기에 추가 하여 재생 합 니 다.이러한 방식 으로 재생 하 는 장점 은 재생 인터페이스의 원본 크기 를 지정 할 수 있다 는 것 이다.그러나 주의해 야 할 것 은 AVPlayerViewController 가 현재 보기 컨트롤 러 에 의 해 가지 고 있어 야 국부 변수 로 방출 되 는 것 을 방지 해 야 한 다 는 것 이다.이 조건 을 만족 시 키 기 위해 저 희 는 AVPlayerViewController 를 속성 으로 할 수도 있 고 addChildViewController 방법 으로 현재 보기 컨트롤 러 의 하위 보기 컨트롤 러 로 할 수도 있 습 니 다.예제 코드 는 다음 과 같 습 니 다.
// 1:
NSString *webVideoPath = @"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1213.mp4";
NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath];
// 2: AVPlayer
AVPlayer *avPlayer = [[AVPlayer alloc] initWithURL:webVideoUrl];
// 3: AVPlayer AVPlayerViewController,
AVPlayerViewController *avPlayerVC =[[AVPlayerViewController alloc] init];
avPlayerVC.player = avPlayer;
// 4:
avPlayerVC.view.frame = CGRectMake(25, 0, 320, 300);
// :AVPlayerViewController ,
// 1.AVPlayerViewController
// 2: addChildViewController,AVPlayerViewController
[self addChildViewController:avPlayerVC];
[self.view addSubview:avPlayerVC.view];
마지막 요약:이상 은 iOS 영상 재생 의 기본 적 인 방법 이지 만 여기 서도 기본 적 인 재생 수요 만 제한 합 니 다.더 복잡 한 재생 기능 을 실현 하려 면 우리 가 계속 깊이 연구 해 야 할 것 이 많 습 니 다.화 이 팅!
자,이상 이 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.