之前看過很多app的登錄頁面,會有背景在循環(huán)播放一段視頻枪汪,覺得非秤磕拢酷炫怔昨。
然后自己研究了許久,終于弄出點樣子宿稀,跟大家分享一下趁舀。
(gif圖做的很爛)
beijingVideo.2018-09-26 15_52_32.gif
1.創(chuàng)建父類視圖控制器
這是.h文件
#import <UIKit/UIKit.h>
//視頻播放時的窗口屬性enum
enum ScalingMode {
resize,
resizeAspect,
resizeAspectFill //默認(rèn)推薦這個屬性
};
@interface FKCVideoViewController : UIViewController
@property (nonatomic,strong) NSURL * contentURL ; //視頻文件地址
@property (nonatomic,assign) CGRect videoFrame ; //播放器的frame
@property (nonatomic,assign) CGFloat startTime ; //視頻開始時間
@property (nonatomic,assign) CGFloat duration ; //循環(huán)時間 不寫的話就默認(rèn)是視頻總長度
@property (nonatomic,strong) UIColor * backgroundColor ; //播放器背景顏色
@property (nonatomic,assign) BOOL sound ; //是否開啟聲音
@property (nonatomic,assign) CGFloat alpha ; //透明度
@property (nonatomic,assign) BOOL alwaysRepeat ; //是否一致循環(huán)
@property (nonatomic,assign) enum ScalingMode fillMode ; //視頻播放時的窗口屬性
@end
然后再到.m文件里來
頭文件一定要導(dǎo)入哦~
#import <AVKit/AVKit.h>
#import <MediaPlayer/MediaPlayer.h>
@interface FKCVideoViewController ()
@property (nonatomic,strong) AVPlayerViewController * moviePlayer ; //播放控制器本體啦
@property (nonatomic,assign) CGFloat moviePlayerSoundLevel ; //控制音量的(有點冗余)
@end
實現(xiàn)一些剛才定義的屬性的set方法
-(void)setBackgroundColor:(UIColor *)backgroundColor
{
self.view.backgroundColor = backgroundColor ;
}
-(void)setSound:(BOOL)sound
{
if (sound) {
self.moviePlayerSoundLevel = 1.0 ;
}
else
{
self.moviePlayerSoundLevel = 0.0 ;
}
}
-(void)setAlpha:(CGFloat)alpha
{
self.moviePlayer.view.alpha = alpha ;
}
-(void)setAlwaysRepeat:(BOOL)alwaysRepeat
{
if (alwaysRepeat) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:self.moviePlayer.player.currentItem] ;
}
}
-(void)setFillMode:(enum ScalingMode)fillMode
{
switch (fillMode) {
case resize:
self.moviePlayer.videoGravity = AVLayerVideoGravityResize ;
break;
case resizeAspect:
self.moviePlayer.videoGravity = AVLayerVideoGravityResizeAspect ;
break;
case resizeAspectFill:
self.moviePlayer.videoGravity = AVLayerVideoGravityResizeAspectFill ;
break;
default:
self.moviePlayer.videoGravity = AVLayerVideoGravityResizeAspectFill ;
break;
}
}
//對應(yīng) setAlwaysRepeat 的監(jiān)聽
-(void)playerItemDidReachEnd
{
[self.moviePlayer.player seekToTime:kCMTimeZero] ;
[self.moviePlayer.player play] ;
}
然后最重要的一步來了
-(void)setContentURL:(NSURL *)contentURL
{
self.moviePlayer = [[AVPlayerViewController alloc]init] ; //這個剛開始沒寫 一直沒有視圖,但是不一定放在這里是最好的祝沸。
[self setFKCMoviePlayer:contentURL] ; //在填寫視頻地址時矮烹,完成播放器的設(shè)置。
}
為了不堵塞主線程罩锐,這里用到了GCD多線程
-(void)setFKCMoviePlayer:(NSURL *)url
{
VideoCutter * videoCutter = [VideoCutter new] ; //這是一個對視頻進(jìn)行一次處理的類奉狈,等下上代碼
[videoCutter cropVideoWithUrl:url andStartTime:self.startTime andDuration:self.duration andCompletion:^(NSURL *videoPath, NSError *error) {
if ([videoPath isKindOfClass: [NSURL class]]) {
dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalDispatchQueueDefault, ^{
dispatch_async(dispatch_get_main_queue(), ^{
self.moviePlayer.player = [[AVPlayer alloc] initWithURL:videoPath] ;
[self.moviePlayer.player play] ;
self.moviePlayer.player.volume = self.moviePlayerSoundLevel ;
});
}) ;
}
}] ;
}
然后是兩個生命周期的方法
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated] ;
self.moviePlayer.view.frame = self.videoFrame ;
self.moviePlayer.showsPlaybackControls = false ;
[self.view addSubview:self.moviePlayer.view] ;
[self.view sendSubviewToBack:self.moviePlayer.view] ;
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated] ;
[[NSNotificationCenter defaultCenter] removeObserver:self] ;
}
viewDidLoad里面啥都沒寫哦
然后再回到剛才說的那個類VideoCutter
2.視頻處理類VideoCutter
這里是.h文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface VideoCutter : NSObject
-(void)cropVideoWithUrl:(NSURL *)url andStartTime:(CGFloat)startTime andDuration:(CGFloat)duration andCompletion:(void(^)(NSURL * videoPath,NSError * error))task ;
@end
再來到.m文件里
好像總共也就這一個方法。涩惑。嘹吨。
-(void)cropVideoWithUrl:(NSURL *)url andStartTime:(CGFloat)startTime andDuration:(CGFloat)duration andCompletion:(void(^)(NSURL * videoPath,NSError * error))task{
dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//由于本人也是參考其他大神的作品發(fā)揮的,所以可能理解的不是很準(zhǔn)確境氢。
dispatch_async(globalDispatchQueueDefault, ^{
AVURLAsset * asset = [[AVURLAsset alloc] initWithURL:url options:nil] ;
AVAssetExportSession * exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:@"AVAssetExportPresetHighestQuality"] ;
//這里是得到一個視頻轉(zhuǎn)碼類AVAssetExportSession 然后質(zhì)量是最高
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) ;
NSString * outputURL = paths.firstObject ;
NSFileManager * manager = [NSFileManager defaultManager] ;
[manager createDirectoryAtPath:outputURL withIntermediateDirectories:true attributes:nil error:nil] ;
outputURL = [outputURL stringByAppendingPathComponent:@"output.mp4"] ;
//拿到轉(zhuǎn)碼后的視頻地址
[manager removeItemAtPath:outputURL error:nil] ;
if ([exportSession isKindOfClass:[AVAssetExportSession class]]) {
exportSession.outputURL = [[NSURL alloc] initFileURLWithPath:outputURL] ;
exportSession.shouldOptimizeForNetworkUse = true ;
exportSession.outputFileType = AVFileTypeMPEG4 ;
Float64 duration64 = duration ;
Float64 startTime64 = startTime ;
CMTime start = CMTimeMakeWithSeconds(startTime64, 600) ;
CMTime duration = CMTimeMakeWithSeconds(duration64, 600) ;
CMTimeRange range = CMTimeRangeMake(start, duration) ;
exportSession.timeRange = range ;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
task(exportSession.outputURL,nil) ;
//轉(zhuǎn)換ok后把視頻地址block回去
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"%@",exportSession.error) ;
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"%@",exportSession.error) ;
break;
default:
NSLog(@"default case") ;
break;
}
}] ;
}
dispatch_async(dispatch_get_main_queue(), ^{
//回到主線程
});
}) ;
}
現(xiàn)在整個視頻播放器已經(jīng)寫好了蟀拷,調(diào)用!
在viewController.h里面
一定要繼承剛才寫的播放器
#import <UIKit/UIKit.h>
#import "FKCVideoViewController.h"
@interface ViewController:FKCVideoViewController
@end
然后回到.m文件里
NSString * videoPath = [[NSBundle mainBundle] pathForResource:@"spotify" ofType:@"mp4"] ;
//視頻地址
NSURL * videoUrl = [[NSURL alloc] initFileURLWithPath:videoPath] ;
self.videoFrame = self.view.frame ; //設(shè)置播放器的frame
self.fillMode = resizeAspectFill ; //設(shè)置播放器填充屬性
self.alwaysRepeat = true ; //是否一致循環(huán)
self.sound = false ; //是否有音效
self.startTime = 2.0 ; //開始時間
self.alpha = 0.8 ; //透明度
self.contentURL = videoUrl ; //把地址給到播放器萍聊,順帶也設(shè)置了
self.view.userInteractionEnabled = NO ; //關(guān)閉用戶交互
OK大功告成问芬!
小白不會寫文章,有遺漏的地方歡迎指出寿桨。