iOS视频播放器之ZFPlayer剖析

作者: renzifeng | 来源:发表于2016-08-10 17:59 被阅读30604次

引言

本文主要针对ZFPlayer的功能实现来剖析,以及总结一下大家遇到的问题和解决方案
首先ZFPlayer现在拥有的功能:

  • 支持横、竖屏切换,在全屏播放模式下还可以锁定屏幕方向
  • 支持本地视频、网络视频播放
  • 支持在TableviewCell播放视频
  • 左侧1/2位置上下滑动调节屏幕亮度(模拟器调不了亮度,请在真机调试)
  • 右侧1/2位置上下滑动调节音量(模拟器调不了音量,请在真机调试)
  • 左右滑动调节播放进度
  • 全屏状态下拖动slider控制进度,显示视频的预览图
  • 断点下载功能
  • 切换视频分辨率

ZFPlayer是对AVPlayer的封装,有人会问它支持什么格式的视频播放,问这个问题的可以自行搜索AVPlayer支持的格式。

跟AVPlayer联系密切的名词:

  • Asset:AVAsset是抽象类,不能直接使用,其子类AVURLAsset可以根据URL生成包含媒体信息的Asset对象。
  • AVPlayerItem:和媒体资源存在对应关系,管理媒体资源的信息和状态。
  • AVPlayerLayer: CALayer的subclass,它主要用来在iOS中播放视频内容

具体功能实现

1、通过一个网络链接播放视频

AVURLAsset *urlAsset = [AVURLAsset assetWithURL:videoURL];
// 初始化playerItem
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:urlAsset];
// 也可以使用来初始化playerItem
// AVPlayerItem * playerItem = [AVPlayerItem playerItemWithURL:videoURL];

// 初始化Player
AVPlayer *player = [AVPlayer playerWithPlayerItem:self.playerItem];
// 初始化playerLayer
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
// 添加playerLayer到self.layer
[self.layer insertSublayer:self.playerLayer atIndex:0];

2、播放器的常用操作

  • 播放:
[player play];

需要注意的是初始化完player之后不一定会马上开始播放,需要等待player的状态变为ReadyToPlay才会进行播放。

  • 暂停:
[player pause];

3、播放多个items

这里我们有两种方式可以实现,一种是由你自行控制下一首歌曲的item,将其替换到当前播放的item

[player replaceCurrentItemWithPlayerItem:playerItem];

在iOS9后,AVPlayer的replaceCurrentItemWithPlayerItem方法在切换视频时底层会调用信号量等待然后导致当前线程卡顿,如果在UITableViewCell中切换视频播放使用这个方法,会导致当前线程冻结几秒钟。遇到这个坑还真不好在系统层面对它做什么,后来找到的解决方法是在每次需要切换视频时,需重新创建AVPlayer和AVPlayerItem。

另一种可以使用AVQueuePlayer播放多个items,AVQueuePlayer是AVPlayer的子类,可以用一个数组来初始化一个AVQueuePlayer对象。代码如下:

NSArray *items = <#An array of player items#>;
AVQueuePlayer *queuePlayer = [[AVQueuePlayer alloc] initWithItems:items];

和AVPlayer一样,直接调用play方法来播放,queue player顺序播放队列中的item,如果想要跳过一个item,播放下一个item,可以调用方法advanceToNextItem。

可以对队列进行插入和删除操作,调用方法insertItem:afterItem:, removeItem:, 和 removeAllItems。正常情况下当插入一个item之前,应该检查是否可以插入,通过使用canInsertItem:afterItem:方法,第二个参数传nil,代码如下:

AVPlayerItem *anItem = <#Get a player item#>;
if ([queuePlayer canInsertItem:anItem afterItem:nil]) {
   [queuePlayer insertItem:anItem afterItem:nil];
}

4、seekToTime指定从某一秒开始播放

可以使用seekToTime:定位播放头到指定的时间,如下代码:

CMTime fiveSecondsIn = CMTimeMake(5, 1);
[player seekToTime:fiveSecondsIn];

seekTime:不能精确定位,如果需要精确定位,可以使用seekToTime:toleranceBefore:toleranceAfter:,代码如下:

CMTime fiveSecondsIn = CMTimeMake(5, 1);
[player seekToTime:fiveSecondsIn toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

当tolerance=0的时候,framework需要进行大量解码工作,比较耗性能,所以,只有当你必须使用的时候才用这个方法,比如开发一个复杂的多媒体编辑应用,这需要精确的控制。

关于重播什么的就不用我多说了吧,点击重播seekToTime:kCMTimeZero。还有关于下次播放的时候从上次离开的那个时间开始播放,大家都有思路啦吧,当离开当前视频时候记录播放到哪一秒了,下次点开直接seekToTime到那一秒开始播放就好了嘛。

5、监听播放进度

使用addPeriodicTimeObserverForInterval:queue:usingBlock:来监听播放器的进度
(1)方法传入一个CMTime结构体,每到一定时间都会回调一次,包括开始和结束播放
(2)如果block里面的操作耗时太长,下次不一定会收到回调,所以尽量减少block的操作耗时
(3)方法会返回一个观察者对象,当播放完毕时需要移除这个观察者
添加观察者:

id timeObserve = [player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
    float current = CMTimeGetSeconds(time);
    float total = CMTimeGetSeconds(songItem.duration);
    if (current) {
        weakSelf.progress = current / total;
        weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
        weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];       
    }
}];

移除观察者:

if (timeObserve) {
   [player removeTimeObserver:_timeObserve];
   timeObserve = nil;
 }

6、监听改播放器状态

[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

播放器的三种状态,当playerItem的状态变为AVPlayerItemStatusReadyToPlay才会进行播放。

typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {
   AVPlayerItemStatusUnknown,
   AVPlayerItemStatusReadyToPlay,
   AVPlayerItemStatusFailed
};

播放完了需要移除观察者

[playerItem removeObserver:self forKeyPath:@"status"];

7、监听缓冲进度

[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

播放完了需要移除观察者

[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];

8、监听网络缓冲状态

// 缓冲区空了,需要等待数据
[playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
// 缓冲区有足够数据可以播放了
[playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];

播放完了需要移除观察者

[playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
[playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];

9、监听AVPlayer播放完成通知

监听通知AVPlayerItemDidPlayToEndTimeNotification,来处理一些播放完的事情

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; 

10、 系统音量相关

/**
 *  获取系统音量
 */
- (void)configureVolume
{
    MPVolumeView *volumeView = [[MPVolumeView alloc] init];
    _volumeViewSlider = nil;
    for (UIView *view in [volumeView subviews]){
        if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
            _volumeViewSlider = (UISlider *)view;
            break;
        }
    }
    
    // 使用这个category的应用不会随着手机静音键打开而静音,可在手机静音下播放声音
    NSError *setCategoryError = nil;
    BOOL success = [[AVAudioSession sharedInstance]
                    setCategory: AVAudioSessionCategoryPlayback
                    error: &setCategoryError];
    
    if (!success) { /* handle the error in setCategoryError */ }
    
    // 监听耳机插入和拔掉通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];
}

/**
 *  耳机插入、拔出事件
 */
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
{
    NSDictionary *interuptionDict = notification.userInfo;
    
    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    
    switch (routeChangeReason) {
            
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            // 耳机插入
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
        {
            // 耳机拔掉
            // 拔掉耳机继续播放
            [self play];
        }

            break;

        case AVAudioSessionRouteChangeReasonCategoryChange:
            // called at start - also when other audio wants to play
            NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
            break;
    }
}

设置系统音量

// 0 ... 1.0的数值, 1.0是最大的声音.
self.volumeViewSlider.value = ...

11、屏幕亮度相关

// 0 ... 1.0的数值, 1.0是最大的亮度.
[UIScreen mainScreen].brightness = ...

12、屏幕旋转相关

苹果手机除iPhone 4s(320*480)屏幕宽高比不是16:9外,其他都为16:9,所以横竖屏可以这样实现,这里必须使用autolayout,这里提供两种方法实现:

  • 使用Xib或者Storyboard的话,必须把播放器view的宽高比设置成16:9,4s的话可以单独适配加约束(使用sizeClasses)
  • 使用masonry,具体代码如下:
[self.playerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view).offset(20);
        make.left.right.equalTo(self.view);
        // 注意此处,宽高比16:9优先级比1000低就行,在因为iPhone 4S宽高比不是16:9
        make.height.equalTo(self.playerView.mas_width).multipliedBy(9.0f/16.0f).with.priority(750);
    }];

关于屏幕旋转可以这样强制让屏幕转屏,有人会问了,在我demo中为啥能转屏,而集成到自己项目中不能转屏,我可以明确的告诉你,是你们项目的横屏给禁止掉了,你可以看一下这里是否打钩啦:


设备方向

有人又会问了,我们想实现这么个需求,只有在播放器页面支持横屏,其他页面不支持横屏。好了,那下边我来告诉怎么实现,首先上图中的横屏必须勾选,其次在你需要转屏的ViewController中来实现三个方法:

//  是否支持自动转屏
- (BOOL)shouldAutorotate
{
    // 调用ZFPlayerSingleton单例记录播放状态是否锁定屏幕方向
    return !ZFPlayerShared.isLockScreen;
}

// 支持哪些转屏方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

// 页面展示的时候默认屏幕方向(当前ViewController必须是通过模态ViewController(模态带导航的无效)方式展现出来的,才会调用这个方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

ZFPlayer内部已经实现屏幕旋转的分类(UITabBarController+ZFPlayerRotation.h UINavigationController+ZFPlayerRotation UIViewController+ZFPlayerRotation),不管你项目的rootViewController的是UINavigationController还是UITabBarController,则只需要在支持除竖屏以外的控制器实现上边三个方法就行。

下边来说说强制屏幕旋转,即使用户的手机锁定了屏幕方法,调用这个方法照样可以旋转:

/**
 *  强制屏幕转屏
 *
 *  @param orientation 屏幕方向
 */
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation
{
    // arc下
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        SEL selector             = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val                  = orientation;
        // 从2开始是因为0 1 两个参数已经被selector和target占用
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
    /*
     // 非arc下
     if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
     [[UIDevice currentDevice] performSelector:@selector(setOrientation:)
     withObject:@(orientation)];
     }
     
     // 直接调用这个方法通不过apple上架审核
     [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
     */
}

监听设备旋转通知,来处理一些UI显示问题

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
 [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onDeviceOrientationChange)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil
];

未完待续....

打赏作者

你的支持就是我的动力,请作者喝杯奶茶吧!!


Demo

本文demo详见:https://github.com/renzifeng/ZFPlayer

广告时间

兼职接各种iOS外包,也可iOS技术支持,有需要的可以联系我!!

联系我

email:zifeng1300@gmail.com
weibo:@renzifeng

相关文章

网友评论

  • b6cf7996bff2:加密的m3u8文件可以播放吗
  • iOS_YXT:大佬,问一下,demo后台播放怎么不可以啊,明明/// 设置退到后台继续播放
    self.player.pauseWhenAppResignActive = NO;这个是允许后台播放的
  • 每天刷两次牙:大佬 ,,你那个git deom里 小窗视频,,为啥viewWillDisappear。将tableView.delegate= nil。?
  • 有bug的程序猿:zf_playerBackAction方法不走
  • Unity与iOS的灵魂小白:视频没有声音出来 用其他播放器有声音 是在哪里设置吗
    太阳和风与旅行者:我也碰到了这个问题,你找到原因了吗
  • Pusswzy:你好请问一下 切换播放链接的时候replaceCurrentItemWithPlayerItem会卡住当前线程, 那么使用AVQueuePlayer和重新创建一个avplayer那个切换速度会更快一点
  • iosiceice:请问一下,这个播放器 可以自己修改界面吗?
  • WGGHot:视频播放时,CPU占用率达到80以上,怎么搞得
  • SunnyLeong:为啥demo下载下来就报错 运行不起来 唉
  • narutog17:我用 ipad 测试 视频横屏的时候 视频的比例不对。。。
    narutog17:@Silence_广 没下载demo,我是直接用cocospod 导入的
    SunnyLeong:你下载的demo怎么运行起来的?
  • Monster_Lai:你好,最近运行demo的时候遇到一个bug。把手机旋转锁定解除,运行demo。第一个模块列表中选择最后一个视频进入,点击返回的同时手机横屏。控制器返回到了上一级,但是该视频没有结束,在最外层的列表控制器又出现了。
    SunnyLeong:你下载的Demo怎么运行起来的
  • 讨厌下雨的鱼:大神,请问这个怎么设置循环播放呀还有怎么监听是否播放完成
  • 金歌漫舞:http的m3u8可以放,下载到本地的m3u8不能放,怎么搞呀,有没有解
  • Cocoa_Vampire:你好,我想问你一下,你这个可以做直播么?还有一个小问题就是,什么叫流媒体流媒体播放呀,看了好多资料,没怎么搞懂,是不是AVplayer不支持流媒体播放,所以您的播放器没法做直播?
    EurekaFlutter:可以的 做直播的 换成http的流
  • 狮子汉堡:这个播放器加载过程中很难被销毁啊,怎么才能在播放器加载数据过程中销毁掉呢?
  • 84a013fc045a:zfplayer 不能播放多个视屏吗,就是像电视剧那样,播完之后播放下一集。。求解答
  • zl_xust:正在播放切入后台然后再唤醒,播放器会黑一下再接着播放时什么问题
    iOS_YXT:大佬,问一下,demo后台播放怎么不可以啊,明明/// 设置退到后台继续播放
    self.player.pauseWhenAppResignActive = NO;这个是允许后台播放的
  • de6ee014e59f:UIViewController (ZFPlayerRotation) 这个分类没有引用却在其他页面横屏时调用,而且,其他页面不能横屏了,为什么啊,我不只是视频页面又横屏,其他页面也有,这要好难过啊
  • de6ee014e59f:其他页面不能横屏,怎么样都不能,跪求怎么解决啊
  • 只因为趁年轻:我想问下,为什么侧滑返回,侧滑的时候前一个页面是黑色的,侧滑成功后,黑色就没了, 是跟什么冲突了吗
  • 皮乐皮儿:我如果想要一开始播放就横屏显示,这个可以控制吗?我是在源码中新增属性,同时手动调用全屏按钮点击事件才能实现,但这个很不好,大神可以在ZFPlayer中给一个属性来控制是否默认开启横屏吗?这个需求还是很常见的
  • 蜕变163:大神,请问全屏怎么适配iPhoneX呢?
  • IMKel:原来是我URL的创建方式出错了,可以播放本地视频的
  • IMKel:大神,我想请问下,你的框架支持播放本地视频吗?我有播放本地视频的需求,但是你的videoURL属性貌似不支持本地路径,能帮帮忙加上这个功能吗?谢谢啦
  • 52aa9d72cbfc:你好,请问下ZFPlayer播放不了本地视频,是什么原因呢,报错如下:error = Error Domain=NSURLErrorDomain Code=-1100 "The requested URL was not found on this server." UserInfo={NSLocalizedDescription=The requested URL was not found on this server., NSUnderlyingError=0x60000085a4f0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
  • 买了否冷_:请问怎么获取视频的全部长度和播放长度
  • Lovingers:有几个内存泄漏的问题,楼主有了解吗?
    EurekaFlutter:播放视频的时候,导致内存大量泄漏。 不知你是怎么解决的
  • 皮乐皮儿:你好,我用的zfplayer,个别用户反馈在iPad上横屏观看出现显示错乱,效果像是整体向左上方移动了,无法铺满全屏,而我用模拟器测了多种机型和系统版本,并没有重现问题,这个大神有碰到过吗?在iPad上适配是不是有问题呢?
  • LazyLoad:不明白 为什么要 在类别里写一个代理属性 直接写在controlView里面 不可以吗?
  • 3409608c2b57:这个播放器写的很好
  • 至恒之狐:我什么我打开的时候不能加载,显示加载失败,重新加载一下就好使了.
  • 饥渴的狗崽子:框架里没有播放进度的代理回调啊,该怎么获取当前playerView的播放进度
  • coder小鹏:为什么点击全屏播放之后,屏幕都变为灰色的了
  • 16fefcb190b5:大神请问能播放直播的拉流地址吗?我把videoUrl直接写成直播的拉留地址,弹出加载失败,点击重试的弹框,请问是不支持的原因吗?
  • 狗不理火锅:不能横屏 按住上面的方法也不能
    de6ee014e59f:怎么解决
  • IMKel:请问视频加载超时时间怎么设置,我找不到对应的属性
  • 书包里的码农:真羡慕你,长得这么好看还会写开源库.
  • LeoZzz:支持ogg格式吗
  • 042a0e1be73f:ZFPlayerDelegate 有调用吗?
    042a0e1be73f:控制层的显示和隐藏,没有调用啊
  • 不知蜕变的挣扎:状态栏不显示啊 要怎么做呢 ?
  • CarrieQ:哈哈哈,最后的打赏,做的好真实。
  • 伊人醉丶:不能播放flv格式的视频吗:flushed:
  • 06f43b0b52f7:大神你好,请问这个可以播放音乐吗
  • S型身材的猪:你好,我想请教一下,你为什么不直接在ZFPlayerView的.h里面写好所有控制按钮的接口,比如暂停、播放、下一集、滑动等接口,然后当用户自定义controlView时,布局好控件之后,直接调用这些接口方法就好了呀。为什么还要像现在这样设置那么多的代理,然后还要在ZFPlayerView里面遵循我自定义的controlView代理协议
  • 2ac58c3b90fa:丰哥 请问我想进入视频播放页面后直接是全屏状态该如何实现呢
    皮乐皮儿:请问你的问题解决了吗?我也想实现这种效果,如果不改动源码怎么实现呢?
  • e1a5546c727d:mark, 通过kvo滑动的时候会创建很多手势,手势会不断的累加
  • 你是我此世不渝的执着:如何清除缓存 路径在哪里
  • 疯狂的小码农:大神在吗?想请教个问题,我们项目中用的版本是老版本的,现在要在cell中放video,有以下问题:1、滑动cell时不想让底部出现小视频view;2、在点击全屏返回时尺寸变了,回不到cell的中心位置。不知道遇到这个问题怎么解决呢?期待大神的回复!
    陳生气:我也回不到中心位置, 解决了吗?
  • 原野de呼唤:iOS 8上全屏后右侧部分的按钮无法点击了, 不知道怎么解决
  • 美丽的巨兔12138:第二个页面是 播放器播放视频状态 当手指侧滑返回第一个页面时,停留,此时第一个页面没有完全展示出来,第二个页面没有完全退出,此时播放器卡顿,一秒一帧,博主注意到了吗?
  • 7fab0f2b95ff:大神你好,今天读了点你的代码发现一个问题请教一下。缓冲较差时候的回调(ZFPlayerView874行)里面的isBuffering设置为局部变量真的没问题么,再次调用这个方法不就又生成一个?
  • 最后还是个农:请教下只支持MP4格式吗
    零点开发:苹果支持的格式他都支持,比较是苹果原生API
  • child_cool:pod zfdownload 之后出现错误:
    Showing Recent Messages
    Desktop/LearnFriendEnterprise/Pods/ASIHTTPRequest/Classes/ASIDataCompressor.h:14:9: Include of non-modular header inside framework module 'ASIHTTPRequest.ASIDataCompressor': '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/usr/include/zlib.h'
    有没有大神指点一下
  • 96770837c5ba:丰哥点击暂停的时候 我想在主控制器是执行一些代码 可是点击暂停的方法在ZFPlayerView里,该怎么做
    96770837c5ba:已解决
  • 男人宫:大神,如果在这个播放器上加弹幕容易实现吗
    豆汁儿还是豆花儿:可以利用BarrageRenderer实现弹幕相关功能
  • 出来遛狗了:求问iOS8上横屏之后,点击全屏按钮没有响应,是什么问题?
    皮乐皮儿:@灰色Y幽默 这是iOS8上的一个bug,你可以试试在iOS8上手机或者iPad横屏状态下启动,然后你原生的控件都失效了,还有就是进入视频播放页面,全屏播放会出现布局错乱
    出来遛狗了:现在测试出来的问题是,横屏过后,右半屏的按钮都不会响应,不知道什么原因
  • 64b6dae6e34a:我想问一下,我就直接给播放视频的那一页赋值一个videoURL,然后仿照MoviePlayerViewController的代码写了一段,为什么告诉我加载失败呢?demo中这个视频资源是加载正常的。
  • 85cafbc20a9b:亲我的全屏旋转不行了,[[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:NO]; 改变status bar的这行代码没有生效,还有很奇怪,我pod完你的项目之后,app就不能旋转了
    de6ee014e59f:解决了吗,跪求
    de6ee014e59f:@陈晓明J 解决了吗
    85cafbc20a9b:还有,我非常明确是打了钩的,然后我还发现pod的不是你最新代码,你的最新代码我直接放到自己的app里面约束一直报错没法显示
  • 梦随兴飞:大神,还有在吗?强制屏幕转屏,这个方法是私有api么?这样审核不过么?最近我也在研究这个。希望大神回答一下。谢谢
  • xing_zhu: pod 'ZFPlayer', '~> 2.0.3'导入的,与您直接手动导入的有些方法和属性是不一样的。请教。
  • xing_zhu:请问 为什么不可以pod 'ZFPaler'?
  • 寂寞天琊:大神 为什么我swift掉用不到 OC的zfplayer 桥接都做好了 都能import 但就是 掉用不到
  • 81f21fe72de3:我想请教一下zfplayer+uitableviewcell使用的问题,zfplayerView放到cell里,cancelAutoFadeOutControlBar这个方法在哪里调用?
  • 鹏城冬阳:博主:横屏全屏播放的情况下点击下载会崩溃(您的demo),请问这个bug怎么解?求助!!!
    renzifeng:@7641e6e7f044 看分类里边新加的那个分类
    鹏城冬阳:现在更新了一下,没问题了。
  • 洁简:必须横屏打钩才支持横屏吗? 我之前用的一个播放器我没有打钩也支持横屏。
  • b944fafb361d:请教个问题如果视频只有10多秒甚至才7、8秒进度条播放是时候会一段一段的走,怎么解决呢?
  • b944fafb361d:请问 我已经pop到播放视频的上一级页面了。离开播放视频页面之后,我把手机横过来,这时候显示了横屏播放视频的View,如何修改呢?
  • TyLee:求助一个问题,我在用的时候用ZFPlayerView初始化一个类,用来播放本地视频,并且设置其静音播放(自己加了一个属性mute,在configZFPlayer方法里设置self.player.muted = self.mute)
    ZFPlayerView *playView = [ZFPlayerView new];
    playView.shouldPreventAdaptIPhone4S = YES;
    playView.playerLayerGravity = ZFPlayerLayerGravityResizeAspect;
    [playView setMute:YES];
    [self.view addSubview:playView];
    播放的时候进行一些mode的设置,在zfplayview的moviePlayDidEnd方法里进行一些设置使其循环播放。
    结果出现了一个问题,首次播放的时候还是有声音,后面几次可以静音,不知道是什么原因?希望能得到您的帮组,谢谢!!
  • ibiaoma:你好,ZFPlayer没有做缓存吗?
  • 嫌疑人zx:大神,有没有解决播放flv格式的方案
    零点开发:苹果系统的API肯定不支持的啦,你得用FFMpeg
  • WellCheng:调用私有 API 可能会出现这样子的问题。

    e.g.:
    A页面:支持横竖屏
    B页面:视频播放页面

    1、A 页面 Push 带有 Player 的 B 页面。
    2、B 页面 setOrientation 到横屏
    3、Pop 后发现 A 页面也被设置为横屏了。

    这个问题怎么解决呢?
    renzifeng:B页面刚进来时候就是横屏吗?如果不是,点击pop时候先切到竖屏,然后在pop
  • 嫌疑人zx:大神,我想向你请教一个问题,这儿有没有暂停缓存的功能,就是我发现用户突然切换网络到数据网络,避免用户花费大量的流量费用,我这里不但要停止播放,我还希望能停止缓存
    5a4be96ef48c:找到了么
    love断鸿:找到这种播放器了吗?
    a506053e8588:我也有这需求:joy: ,正在找个能停缓存的播放器
  • 一只霸天犬v:大神 我pod 最新版本的 拖拽slider的时候总是和导航控制器右滑返回冲突 求帮助
  • 伦敦乡下的小作家:楼主。这个能播放音频流媒体吗???只是音频
  • dose_爽:频繁进行前后台切换的时候,player有的时候显示画面,有的时候不显示画面,但是有声音,怎么解决啊,大神
    iOS_YXT:大佬,问一下,demo后台播放怎么不可以啊,明明/// 设置退到后台继续播放
    self.player.pauseWhenAppResignActive = NO;这个是允许后台播放的
  • 694cb92b5431:约束 好像 全报错了, xcode 8.2下 ?
  • iamgaoshuai:http://chuantu.biz/t5/45/1483959119x3031248113.png
    屏幕没有选择 造成这种情况的可能因素有哪些

    列表页是正常的
    iamgaoshuai:横竖屏只勾选的竖屏
  • 崠崠:作者 怎么你的demo 中的tableview 每次点击cell的话 不是调用button的block 而是tableview的didselectrow 
  • 042a0e1be73f:请问视频的下载链接应该怎么播放呢?
  • JaryWang:不用cocopod 只能拖项目文件 能集成吗
  • iamgaoshuai:怎么能让标题一开始就显示
  • 熊啊熊啊熊:xcode8 版本8.0 iphone(8.0)这个模拟器下运行 报约束错误,全屏就错乱了,楼主!!!
    最晴天:约束报错的问题,你找到了是哪里的代码问题吗?
  • 携一两本单色书来:大神,有没有什么办法能判断一个观察者是否存在再决定移除呢?想调用您的setOrientationLandscape,但是里面的观察者老是捣乱
    84a013fc045a:@renzifeng 大神 怎么 做连续播放视频呀,看你的框架没看到可以设置多个播放地址的地方。
    携一两本单色书来:大神,搞定了,要搞在cell上播放视频时能够旋转屏幕,走了一些误区,最后在旋转屏幕时用的通知走的全屏按钮方法。封装的太全面了,膜拜~~
    renzifeng:@携一两本单色书来 你指的是contentoffset吗
  • 5a38f7481378:最新版本2.0.3 Demo 在iphone6 , iOS10 上 有问题, 其他设备未测试. 问题是 只下载,不自动播放.但在模拟器上又是正常的
  • 尕宝11:我用这个ZFPlayer和(MMDrawerController抽屉)就无法横屏了,请大神帮解决一下,谢谢了
    尕宝11:@五锅锅 MM中有一个是否允许横屏的设置,返回值是bool的改一下就好了
    五锅锅:,我也遇到了:disappointed_relieved:
    风雨同舟xxyy:请问问题解决了吗
  • Fasa:手头没iOS7的机器,请问支持iOS7吗
  • Suneday:楼主,为啥实现那3个方法以后 屏幕旋转的时候 导航栏和tabbar还是没有隐藏呢!
  • 呵呵1798:你好,我想问您一下,这个支持iOS7么?
  • c066fe49abc4:你好,我想请问一下,如果正在播放的时候断开网络连接,之后再重新连接网络,那应该是重新进行播放吧,如果我希望接着之前的地方播放,我是应该记录断开网络时的播放进度,联网重新播放的时候让它重新播放URL,然后设置从上次断网的地方开始放么 :smile:
  • 只因为趁年轻:大神,我想问一下, 自定义playerView的高度,用masonry改成 1:1, 横屏后宽高怎么更改, 无论我在旋转后,怎么更改比例 ,都是无效的,请问怎么解决
  • 空转风:楼主你好,请问在UIwebView上点击一个视频播放按钮,系统总是会弹出自带的播放器,要怎么才能禁止系统弹出播放器调用自己的播放器呢?如何调用自己的播放器我知道可以通过js实现,但是要如何禁止系统自带播放器我却一直想不出来,求楼主大大教下
  • 空转风:因为要支持iOS7 ,所以自己写了个播放器,当然很多内容都是根据你的方法修改的,然后用到了ZFPlayerDownload,特地来跟你说下
    呵呵1798:@年光逝也被僵尸号占了 我们项目也要适配iOS7 有时间 能贴下你适配的代码么,感谢🙏?
    空转风:@呵呵1798 横屏适配啊……剩下的都可以在ios7上应用啊
    呵呵1798:@年光逝也被僵尸号占了 你好,能问下你这上面哪些都适配了iOS7?
  • hllcve_:在4G 状态下 快进 快退 不好用了 而且快进快退后 切换大小屏 会出现两个视频 有知道的吗?
  • 奋斗中的Kevin:下载完pod install 运行不了 找不到ZFHttpRequest ZFFileModel怎么解决啊大神
  • 21e790b8fb9e:挺不错的 ! 感谢你的开源精神!
  • smanx:类别导致项目屏幕无法旋转
    蛮小刀:@renzifeng 视频在cell上的,按照上面写的勾选、代码添加,点击全屏,界面有问题。直接横屏,视频也没有横屏播放。
    蛮小刀:类似操作,横屏确实有问题。
    renzifeng:@smanx 什么错误
  • __Lex:我用mac 共享的NAT64的wifi热点,播放网络视频的时候加载失败
    5bbe44965008:你好 请问现在解决了么
  • 38e282c64235:大神,你知道用AVPlayer刚播放音频的时候,锁屏会导致播放暂停,是什么原因吗?

本文标题:iOS视频播放器之ZFPlayer剖析

本文链接:https://www.haomeiwen.com/subject/ugmcjttx.html