iOS 教你利用MP澳门美高梅手机网站、AVPlayer、AVPlayerVC构建一个全部的视频播放器

大型高性能ASP.NET系统架构设计

  大型动态应用系统平台首假诺对准于大流量、高并发网站建立的最底层系统架构。大型网站的运作须求一个保证、安全、可增添、易维护的施用系统平台做为支撑,以担保网站拔取的雅安久安运作。  

  大型动态应用连串又可分为多少个子系统:

> style=”color: red; font-family: simsun; font-size: 12pt;”>Web > style=”color: red; font-family: simsun; font-size: 12pt;”>前端系统

style=”color: red; font-family: simsun; font-size: 12pt;”>负载均衡系统

style=”color: red; font-family: simsun; font-size: 12pt;”>数据库集群系统

style=”color: red; font-family: simsun; font-size: 12pt;”>缓存系统

style=”color: red; font-family: simsun; font-size: 12pt;”>分布式存储系统

style=”color: red; font-family: simsun; font-size: 12pt;”>分布式服务器管理种类

style=”color: red; font-family: simsun; font-size: 12pt;”>代码分发系统

  

  Web前端系统

  为了完毕分化拔取的服务器共享、防止单点故障、集中管理、统一计划等目标,不以应用细分服
务器,而是将享有服务器做联合行使,每台服务器都足以对七个使用提供劳动,当某些应用访问量提高时,通过增加服务器节点达到任何服务器集群的性质升高,同时使他使用也会收益。

  该Web前端系统基于IIS/ASP.NET等的虚拟主机平台,提供PHP程序运行环境。服务器对开发人士是晶莹剔透的,不须求开发人士到场服务器管理。

 

  负载均衡系统

  负载均衡系统分为硬件和软件三种。硬件负载均衡功效高,但是价格贵,比如F5等。软件负载均衡系统价格较低仍旧免费,效用较硬件负载均衡系统低,但是对此流量一般或稍大些网站来讲也充裕使用,比如lvs,nginx。一大半网站都是硬件、软件负载均衡系统并用。

 

  数据库集群系统 

  由于Web前端采取了负荷均衡集群结构增强了劳务的实惠和伸张性,由此数据库必须也是高可信的才能保险全体服务连串的高可相信性,如何构建一个高可信的、可以提供广阔现身处理的数据库连串?

  大家得以选拔如上图所示的方案:

  1)使用SQL数据库,考虑到Web应用的数据库读多写少的特征,大家紧要对读数据库做了优化,提供专用的读数据库和写数据库,在应用程序中贯彻读操作和写操作分别走访分化的数据库。

  2)使用同步机制达成火速将主库(写库)的数据库复制到从库(读库)。一个主库对应四个从库,主库数据实时同步到从库。

  3)写数据库有多台,每台都得以提供几个应用共同利用,那样可以缓解写库的特性瓶颈难点和单点故障难题。

  4)读数据库有多台,通过负载均衡设备落实负载均衡,从而达到读数据库的高性能、高可信和高可扩张性。

  5)数据库服务器和应用服务器分离。

  6)从数据库使用BigIP做负载均衡。

 

  缓存系统 

  缓存分为文件缓存、内存缓存、数据库缓存。在巨型Web应用中行使最多且功效最高的是内存缓存。最常用的内存缓存工具是Memcachd。使用科学的缓存系统可以达标完结以下目标:

  1、使用缓存系统可以加强访问功效,升高服务器吞吐能力,改革用户体验。

  2、减轻对数据库及储存集服务器的访问压力。

  3、Memcached服务器有多台,防止单点故障,提供高可倚重性和可扩充性,进步性能。

  分布式存储系统

  Web系统平奥兰多的存储须要有上面多少个性状:

  1)
存储量很大,平常会落成单台服务器无法提供的范畴,比如相册、视频等接纳。由此必要专业的科普存储系统。

  2)
负载均衡cluster中的每个节点都有可能访问任何一个数额对象,每个节点对数据的拍卖也能被其余节点共享,因而那几个节点要操作的数额从逻辑上看只能够是一个完好无缺,不是分别独立的多寡资源。

  因而高性能的分布式存储系统对此大型网站使用来说是卓殊重大的一环。(那些地点需求投入对某个分布式存储系统的简短介绍。)

 

  分布式服务器管理连串

  随着网站访问流量的不断增多,大多的网络服务都是以载重均衡集群的法子对外提供劳务,随之集群规模的壮大,原来基于单机的服务器管理格局已经不可见满意我们的须求,新的须要必须可以集中式的、分组的、批量的、自动化的对服务器进行管理,可以批量化的实施陈设义务。

 

  在分布式服务器管理连串软件中有部分相比杰出的软件,其中相比较卓绝的一个是Cfengine(http://yahoon.bog.51cto.com/13184/52409)。它可以对服务器进行分组,不同的分组可以分别定制系统配置文件、计划任务等配置。

  它是按照C/S
结构的,所有的服务器配置和治本脚本程序都保留在Cfengine Server上,而被管理的服务器运行着 Cfengine Client程序,Cfengine
Client通过SSL加密的总是定期的向服务器端发送请求以取得最新的部署文件和管制命令、脚本程序、补丁安装等职务。

  有了Cfengine
那种集中式的服务器管理工具,大家就足以连忙的兑现广大的服务器集群管理,被管理服务器和 Cfengine
Server可以分布在别的职分,只要网络可以连接就能完结长足自动化的田间管理。

 

  代码分发系统 

  随着网站访问流量的四处追加,大多的网络服务都是以载重均衡集群的措施对外提供劳动,随之集群规模的恢弘,为了满意集群环境下程序代码的批量散发和换代,大家还亟需一个程序代码公布连串。

  那个布告连串可以帮大家落实上面的对象:

  1)
生产条件的服务器以虚拟主机格局提供劳务,不需求开发人士到场保证和一贯操作,提供公布种类可以完结不要求登陆服务器就能把程序分发到目标服务器。

  2)
大家要促成内部支出、内部测试、生产环境测试、生产环境揭橥的4个开发阶段的田间管理,公布种类可以出席各样阶段的代码发表。

  3)
我们须要完成源代码管理和版本控制,SVN可以已毕该须求。

  那中间可以动用常用的工具Rsync,通过支付相应的剧本工具已毕服务器集群间代码同步分发。

正文出自 “燕洋天
博客,请务必保留此出处http://yanyangtian.blog.51cto.com/2310974/489915

前言

标题必需求浮夸!要觉得像是一个大信息。长者如是说。
实质上是前天去面试的时候,被必要说必须做过视频播放相关品种。有点烦躁之余,就花了点时间在家写了一个简单易行播放器,基本落到实处了主流播放器的大约功用。以前项目尚未须求用到过视频播放,所以写的时候难免会碰到有些坑,花了有的时间解决。

苹果在视频播放方面提供了四个框架供我们接纳接纳。分别为:

  • 根据mediaPlayer类库的MPMediaPlayerController(iOS9后遇到抛弃,被AVPlayerViewController所替代)
  • 基于AVFounditon类库的AVPlayer
  • 据悉AVKit类库的AVPlayerViewController(iOS8后才可采纳)

正文

AVPlayer与MPMediaPlayerController比较:

  • AVplayer有更加多的灵活性,当然,也急需您去自定义构建UI。还有一大优势,例如其增添的AVQueuePlayer,能够兑现视频无缝队列播放、多录像同时播放、录像转换、编解码等功能。
  • MPMediaPlayerController实际上是依照AVPlayer的简单UI封装,对于一般的播放要求,几行代码就可已毕,省心省事。
    因为MPMediaPlayerController是对AVPlayer进行的单例封装,所以不可以举办多视频播放
播放器Demo(全屏)已落到实处效益点:
  • push到播放器页面,横屏呈现。
  • 单机隐藏or突显上边标题栏与江湖操作栏。
  • 呼出右边设置栏。
  • 视频播放操作与进程条设置。
  • 在显示器上左右拖动,举行视频快进与快退。
  • 在显示屏左边上下拖动,举行亮度调整。
  • 在显示屏右边上下拖动,举行高低调整。
想开可是暂未落成的效应点:(大多为优化或与事务有关)
  • 屏幕或进程条拖动快进操作时,添加提示框举办快进时间的实时提醒。
  • 用户无操作两三秒之后自动隐藏上下View。
  • 视频清晰度调整按钮。(更换视频源)
  • 操作加锁按钮。(加锁后未举行解锁操作此前不得进行操作)
  • 弹幕相关。
  • 用户同意横屏状态下,横屏竖屏自动举办页面切换与动画片效果等。
  • 网络录像的缓存、下载等。
  • 软硬解码方式切换等。

小编Demo接纳选用了AVPlayer进行录像播放器的构建。由于UI的代码完成,加上略蛋疼的逻辑代码,播放器页面的代码量达到400多行,之后有时间的话会再拓展优化。那里只贴出部分代码,想要查看或借鉴完整Demo,能够到我github去下载。

接纳AVPlayer构建播放器

1.导入头文件

#import <AVFoundation/AVFoundation.h>

2.其实没什么可说的,很粗略,先开端化AVPlayer,然后添加到AVPlayerLayer,最终将其添加到视图的layer层。

#pragma mark - Demo中此视图的属性

#define TopViewHeight 55
#define BottomViewHeight 72
#define mainWidth [UIScreen mainScreen].bounds.size.width
#define mainHeight [UIScreen mainScreen].bounds.size.height

//上层建筑
@property (nonatomic,strong)UIView *topView;
@property (nonatomic,strong)UIButton *backBtn;
@property (nonatomic,strong)UILabel *titleLabel;
@property (nonatomic,strong)UIButton *settingsBtn;

//经济基础
@property (nonatomic,strong)UIView *bottomView;
@property (nonatomic,strong)UIButton *playBtn;
@property (nonatomic,strong)UILabel *textLabel;
@property (nonatomic,assign)BOOL isPlay;
@property (nonatomic,strong)UISlider *movieProgressSlider;//进度条
@property (nonatomic,assign)CGFloat ProgressBeginToMove;
@property (nonatomic,assign)CGFloat totalMovieDuration;//视频总时间

//核心躯干
@property (nonatomic,strong)AVPlayer *player;

//神之右手
@property (nonatomic,strong)UIView *settingsView;
@property (nonatomic,strong)UIView *rightView;
@property (nonatomic,strong)UIButton *setTestBtn;

//touch evens
@property (nonatomic,assign)BOOL isShowView;
@property (nonatomic,assign)BOOL isSettingsViewShow;
@property (nonatomic,assign)BOOL isSlideOrClick;

@property (nonatomic,strong)UISlider *volumeViewSlider;
@property (nonatomic,assign)float systemVolume;//系统音量值
@property (nonatomic,assign)float systemBrightness;//系统亮度
@property (nonatomic,assign)CGPoint startPoint;//起始位置坐标

@property (nonatomic,assign)BOOL isTouchBeganLeft;//起始位置方向
@property (nonatomic,copy)NSString *isSlideDirection;//滑动方向
@property (nonatomic,assign)float startProgress;//起始进度条

#pragma mark - 播放器躯干
- (void)createAvPlayer{
    //设置静音状态也可播放声音
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

    CGRect playerFrame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width);

    AVURLAsset *asset = [AVURLAsset assetWithURL: _url];
    Float64 duration = CMTimeGetSeconds(asset.duration);
    //获取视频总时长
    _totalMovieDuration = duration;

    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset: asset];

    _player = [[AVPlayer alloc]initWithPlayerItem:playerItem];

    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
    playerLayer.frame = playerFrame;
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    [self.view.layer addSublayer:playerLayer];
    //需要设置自动播放的直接play即可
    //[_player play];
}
屏幕单击手势与视频快进

显示器单击
1.符合条件的情况下(手指按下后离开显示器,并且没有拖动)通过BOOL值判断,隐藏或突显上下View

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint point = [[touches anyObject] locationInView:self.view];
     if (_isShowView) {
        //上下View为显示状态,此时点击上下View直接return
        if ((point.y>CGRectGetMinY(self.topView.frame)&&point.y< CGRectGetMaxY(self.topView.frame))||(point.y<CGRectGetMaxY(self.bottomView.frame)&&point.y>CGRectGetMinY(self.bottomView.frame))) {
            return
         }
        _isShowView = NO;
        [UIView animateWithDuration:0.5 animations:^{
            _topView.alpha = 0;
            _bottomView.alpha = 0;
        }];
    }else{
        _isShowView = YES;
        [UIView animateWithDuration:0.5 animations:^{
            _topView.alpha = 1;
            _bottomView.alpha = 1;
        }];
    }
}

2.右手View展现的动静下,点击显示器左半空荡荡区域,隐藏左边View

if (_isSettingsViewShow) {
    if (point.x>CGRectGetMinX(_rightView.frame)&&point.x< CGRectGetMaxX(_rightView.frame)) {
        return;
    }
    _settingsView.alpha = 0;
    _isSettingsViewShow = NO;
}

拖动快进
1.乘除后得出拖动方向为横向拖动。

CGPoint location = [[touches anyObject] locationInView:self.view];
CGFloat changeY = location.y - _startPoint.y;
CGFloat changeX = location.x - _startPoint.x;
if(fabs(changeX) > fabs(changeY)){
    _isSlideDirection = @"横向";//设置为横向
}else if(fabs(changeY)>fabs(changeX)){
    _isSlideDirection = @"纵向";//设置为纵向
}else{
    _isSlideOrClick = NO;
    NSLog(@"不在五行中。");
}

2.基于手指按下与离开屏幕后,横向位移的坐标值,对录像播放进度进行刷新。

    if (_isSlideOrClick) {
        _isSlideDirection = @"";
         _isSlideOrClick = NO;

        CGFloat changeY = point.y - _startPoint.y;
        CGFloat changeX = point.x - _startPoint.x;
        //如果位置改变 刷新进度条
        if(fabs(changeX) > fabs(changeY)){
            [self scrubberIsScrolling];
        }
        return;
    }
//拖动进度条
-(void)scrubberIsScrolling{
    //计算出拖动的当前秒数(总长*当前百分比)
    NSInteger dragedSeconds = floorf(_totalMovieDuration * _movieProgressSlider.value);
    CMTime newCMTime = CMTimeMake(dragedSeconds, 1);

    [_player seekToTime:newCMTime completionHandler:^(BOOL finished) {
        [_player play];
        [_playBtn setTitle:@"暂停" forState:UIControlStateNormal];
    }];
}
MPMediaPlayerController与AVPlayerViewController的施用介绍

MPMediaPlayerController与AVPlayerViewController,两者都是依照AVPlayer的简单UI封装,假如只是索要简单的视频播放效果,能够应用那四个类火速的构建视频播放器。

MPMediaPlayerController
1.导入头文件

#import <MediaPlayer/MediaPlayer.h>

2.先河化mp,几行代码既可以兑现。

@property (nonatomic,strong)MPMoviePlayerController *mp;

NSURL *url1 = [[NSBundle mainBundle]URLForResource:@"chenyifaer" withExtension:@"mp4"];

_mp = [[MPMoviePlayerController alloc] initWithContentURL:url1];
_mp.controlStyle = MPMovieControlStyleNone;
_mp.view.frame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width);
[self.view addSubview:_mp.view];
[_mp play];

controlStyle属性有多个值:

  • MPMovieControlStyleNone, //无控制
  • MPMovieControlStyleEmbedded, //有全屏按钮与控制
  • MPMovieControlStyleFullscreen, // 默许全屏,有退出和决定

当然还有一对其余性能,有亟待能够活动举办安装。

AVPlayerViewController
1.导入框架与头文件

#import <AVKit/AVKit.h>

2.初叶化AVPlayerViewController,成立一个AVPlayer添加上。然后将其添加到视图上,再将View添加到self.View上,然后play即可

NSURL *url1 = [[NSBundle mainBundle]URLForResource:@"chenyifaer" withExtension:@"mp4"];

AVPlayer * player = [AVPlayer playerWithURL:url1];
AVPlayerViewController *playerController = [[AVPlayerViewController alloc]init];
playerController.player = player;

[self addChildViewController:playerController];
[self.view addSubview:playerController.view];
playerController.view.frame = CGRectMake(0, 0, self.view.layer.bounds.size.height, self.view.layer.bounds.size.width);
[player play];

同样几行代码,即可完结。

高低调整

1.导入头文件

#import <MediaPlayer/MediaPlayer.h>

2.依赖MPVolumeView类来赢获得其音量进程条,进而拓展高低获取与控制

@property (nonatomic,strong)UISlider *movieProgressSlider;//进度条

MPVolumeView *volumeView = [[MPVolumeView alloc] init];
_volumeViewSlider = nil;
for (UIView *view in [volumeView subviews]){
    if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
        _volumeViewSlider = (UISlider *)view;
        break;
}

3.LED显示屏时,记录手指按下的岗位、获取按下时系统的音量(达成touchesBegan方法)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        _startProgress = _movieProgressSlider.value;
}

4.手指在规定行为下(手指按下地方为视图右半区,且纵向滑动)持续滑动时,动态改变系统音量(完结touchesMoved方法)

//手指持续滑动,此方法会持续调用
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint location = [[touches anyObject] locationInView:self.view];
    int index = location.y - _startPoint.y;
    if(index>0){
        [_volumeViewSlider setValue:_systemVolume - (abs(index)/10 * 0.05) animated:YES];
        [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
    }else{
       [_volumeViewSlider setValue:_systemVolume + (abs(index)/10 * 0.05) animated:YES];
        [_volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
}
亮度调整

1.触摸屏幕时,记录手指按下的职责、按下时显示器的亮度(落成touchesBegan方法)
2.手指在规定行为下(手指按下地点为视图左半区,且纵向滑动)持续滑动时,不断动态处理(达成touchesMoved方法)
3.改动显示屏亮度:[UIScreen mainScreen].brightness = X (0~1);

//手指持续滑动,此方法会持续调用
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint location = [[touches anyObject] locationInView:self.view];
    int index = location.y - _startPoint.y;
    if(index>0){
        [UIScreen mainScreen].brightness = _systemBrightness - abs(index)/10 * 0.01;
    }else{
        _movieProgressSlider.value = _startProgress - abs(index)/10 * 0.008;
    }
}
屏幕旋转

1.设置使用支撑横屏(默许协理)。
2.在根视图中设置默认竖屏(Nav、TabBar、VC基类)

- (BOOL)shouldAutorotate{
    return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

3.在须要横屏的VC中重写下列情势即可

//允许横屏旋转
- (BOOL)shouldAutorotate{
    return YES;
}

//支持左右旋转
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft;
}

//默认为右旋转
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return UIInterfaceOrientationLandscapeRight;
}

源码

点此下载:github源码
小编其余作品推荐:iOS
使用CIDetector扫描相册二维码、原生扫描

结语

如何,完毕一个概括的视频播放器是或不是很简短。当然,要做一个好的视频播放器,要求越多的优化处理、UI处理、业务职能伸张、动画效果….
作者Demo中有关timer与进度条的相互之间不甚完善,还有些小难题。
一言以蔽之,初次尝试写,水平有限,如有错误,还望指正。

参考:
1.http://www.techotopia.com/index.php/iOS8AVPlayerAndPlayerViewController
2.http://stackoverflow.com/questions/8146942/avplayer-and-mpmovieplayercontroller-differences
3.http://www.jianshu.com/p/e64fe3c7f9ab
4.http://www.th7.cn/Program/IOS/201504/439086.shtml
其余不成难点多在stackoverflow查询解决。


PS:最后吐槽一下。因为写的有点有些多,想做个飞跃电梯树举行页内跳转,结果发现简书竟然不扶助<span
id=”jump”>正文</span>那样使用锚点进行页内跳转的语法。大致坑爹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注