登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

基于AVPlayer的播放器,用swift4封装的支持react-native,适配PhoneX

[复制链接]
来自: easyui 分类: iOS精品源码 上传时间: 2017-11-1 09:47:18
Tag:

项目介绍:

github地址:https://github.com/easyui/EZPlayer

EZPlayer

Swift 4
Carthage Compatible
<img src="https://img.shields.io/cocoapods/v/EZPlayer.svg">| 5c7f381dd1ac894a6c9ea7ee052e31e84 |
Platform
License

介绍

基于AVPlayer封装的视频播放器,功能丰富,快速集成,可定制性强。

要求

  • iOS 8.0+

  • Xcode 9.0+

  • Swift 4.0+

特性

安装 

ExportFramework

执行项目中的ExportFramework脚本自动生成framework

Carthage

  1. 创建一个 Cartfile ,在这个文件中列出你想使用的 frameworks

    github "easyui/EZPlayer"  
  2. 运行 carthage update ,获取依赖到 Carthage/Checkouts 文件夹,逐个构建

  3. 在工程的 target-> General 选项下,拖拽 Carthage/Build 文件夹内想要添加的 framework 到 “Linked Frameworks and Libraries” 选项下。
    (如果不想拖动这个操作的话,可以设置Xcode自动搜索Framework的目录 Target—>Build Setting—>Framework Search Path—>添加路径"$(SRCROOT)/Carthage/Build/iOS")

  4. 在工程的 target-> Build Phases 选项下,点击 “+” 按钮,选择 “New Run Script Phase” ,填入如下内容:

    /usr/local/bin/carthage copy-frameworks

并在 “Input Files” 选项里添加 framework 路径

$(SRCROOT)/Carthage/Build/iOS/EZPlayer.framework

CocoaPods

  1. 创建一个 Podfile ,在这个文件中列出你想使用的 frameworks

    project 'EZPlayerExample.xcodeproj'
    platform :ios, '8.0'
    
    target '<Your Target Name>' do
      use_frameworks!
      pod 'EZPlayer' 
    end
  2. Podfile 文件目录下执行

    $ pod install

使用

  • 初始化播放器播放

func playEmbeddedVideo(mediaItem: MediaItem, embeddedContentView contentView: UIView? = nil , userinfo: [AnyHashable : Any]? = nil ) {
        //stop
        self.releasePlayer()
......       
        self.player!.backButtonBlock = { fromDisplayMode in
            if fromDisplayMode == .embedded {
                self.releasePlayer()
            }else if fromDisplayMode == .fullscreen {
                if self.embeddedContentView == nil && self.player!.lastDisplayMode != .float{
                    self.releasePlayer()
                }
                
            }else if fromDisplayMode == .float {
                self.releasePlayer()
            }
            
        }
        
        self.embeddedContentView = contentView
        //self.embeddedContentView为nil时就是全屏播放
        self.player!.playWithURL(mediaItem.url! , embeddedContentView: self.embeddedContentView)
    }

  • 全屏模式/嵌入模式/浮动模式随意切换(支持根据设备自动旋转)

  • 全屏模式支持横屏全屏和竖屏全屏

//根据设备横置自动全屏
open var autoLandscapeFullScreenLandscape = UIDevice.current.userInterfaceIdiom == .phone
//指定全屏模式是竖屏还是横屏
open var fullScreenMode = EZPlayerFullScreenMode.landscape

//进去全屏模式
open func toFull(_ orientation:UIDeviceOrientation = .landscapeLeft, animated: Bool = true ,completion: ((Bool) -> Swift.Void)? = nil) 
//进入嵌入屏模式
open func toEmbedded(animated: Bool = true , completion: ((Bool) -> Swift.Void)? = nil)
//进入浮动模式
open func toFloat(animated: Bool = true, completion: ((Bool) -> Swift.Void)? = nil) 

例子:EZPlayerExample-DisplayMode

  • 定制手势:播放/暂停(全屏/嵌入模式双击,浮动模式单击),浮动和全屏切换(双击),音量/亮度调节(上下滑动),进度调节(左右滑动)

//自定义皮肤只要实现这两个协议
public protocol EZPlayerHorizontalPan: class {
func player(_ player: EZPlayer ,progressWillChange value: TimeInterval)
func player(_ player: EZPlayer ,progressChanging value: TimeInterval)
func player(_ player: EZPlayer ,progressDidChange value: TimeInterval)
}

public protocol EZPlayerGestureRecognizer: class {
func player(_ player: EZPlayer ,singleTapGestureTapped singleTap: UITapGestureRecognizer)
func player(_ player: EZPlayer ,doubleTapGestureTapped doubleTap: UITapGestureRecognizer)
}
//点击事件还可以接受通知
static let EZPlayerTapGestureRecognizer = Notification.Name(rawValue: "com.ezplayer.EZPlayerTapGestureRecognizer")

  • 支持airPlay

/// 支持airplay
open var allowsExternalPlayback = true
/// airplay连接状态
open var isExternalPlaybackActive: Bool 

  • 支持UITableview自动管理嵌入和浮动模式切换

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...       MediaManager.sharedInstance.playEmbeddedVideo(url:URL.Test.localMP4_0, embeddedContentView: cell?.contentView)

//主要是设置indexPath和scrollView 属性
MediaManager.sharedInstance.player?.indexPath = indexPath
        MediaManager.sharedInstance.player?.scrollView = tableView
    }

  • 视频比例填充(videoGravity)切换

//设置
open var videoGravity = EZPlayerVideoGravity.aspect

  • 字幕/CC切换

  • 音频切换

主要通过下面两个extension来设置,查看
AVAsset+EZPlayer.swift
//获取所有cc
public var closedCaption: [AVMediaSelectionOption]? 
//获取所有subtitle
public var subtitles: [(subtitle: AVMediaSelectionOption,localDisplayName: String)]? 
//获取所有audio
public var audios: [(audio: AVMediaSelectionOption,localDisplayName: String)]? 

AVPlayerItem+EZPlayer.swift
/// 获取/设置当前subtitle/cc
public var selectedMediaCharacteristicLegibleOption:AVMediaSelectionOption?
/// 获取/设置当前cc
public var selectedClosedCaptionOption:AVMediaSelectionOption?
/// 获取/设置当前subtitle
public var selectedSubtitleOption:AVMediaSelectionOption?
/// 获取/设置当前audio
public var selectedMediaCharacteristicAudibleOption:AVMediaSelectionOption?

  • 拖动进度显示预览图(m3u8不支持)

//不支持m3u8
open func generateThumbnails(times: [TimeInterval],maximumSize: CGSize, completionHandler: @escaping (([EZPlayerThumbnail]) -> Swift.Void ))
//支持m3u8
func snapshotImage() -> UIImage?

  • 播放器控件皮肤自定义(自带一套浮动皮肤,嵌入和全屏用的一套皮肤)

    • EZPlayer一共三套皮肤可以设置:

 /// 嵌入模式的控制皮肤
open  var controlViewForEmbedded : UIView?
/// 浮动模式的控制皮肤
open  var controlViewForFloat : UIView?
/// 浮动模式的控制皮肤
open  var controlViewForFullscreen : UIView?
  • 默认controlViewForFullscreen为空的时候会默认使用controlViewForEmbedded皮肤

  • EZPlayer初始化的时候可以设置controlViewForEmbedded皮肤

    public init(controlView: UIView? )

例子:EZPlayerExample-Skin(ad)

  • 支持广告功能

假如播放过程中进入广告,那需要临时设置广告皮肤,可以设置属性:

open  var controlViewForIntercept : UIView?

例子:EZPlayerExample-Skin(ad)

  • 支持React Native

可以参考EZPlayerExample_RN项目,使用最新的swift4和最新的react native版本对EZPlayer的封装,实现EZPlayer的大部分功能。

react-native-ezplayer 文件:

EZRNPlayerView.swift : 对EZPlayer的封装,对接javascript

EZRNPlayerViewManager.swift : EZPlayer组件管理器

EZRNPlayerViewBridge.h & EZRNPlayerViewBridge.m : oc桥接

EZPlayer.js : 对EZPlayer封装的js api

属性

| key | description | value |
| --- | --- | --- |
| source | 视频数据源 | PropTypes.object |
| autoPlay|设置数据源后自动播放| PropTypes.bool |
| useDefaultUI|使用EZPlayer自带皮肤| PropTypes.bool |
| videoGravity|视频画面比例| PropTypes.string(aspect,aspectFill,scaleFill) |
| fullScreenMode|全屏模式是竖屏还是横屏| PropTypes.string(portrait,landscape) |
| onPlayerHeartbeat|播放器声明周期心跳| PropTypes.func |
| onPlayerPlaybackTimeDidChange|addPeriodicTimeObserver方法的触发| PropTypes.func |
| onPlayerStatusDidChange|播放器状态改变| PropTypes.func |
| onPlayerPlaybackDidFinish|视频结束| PropTypes.func |
| onPlayerLoadingDidChange|loading状态改变| PropTypes.func |
| onPlayerControlsHiddenDidChange|播放器控制条隐藏显示| PropTypes.func |
| onPlayerDisplayModeDidChange|播放器显示模式改变了(全屏,嵌入屏,浮动)| PropTypes.object |
| onPlayerDisplayModeChangedWillAppear |播放器显示模式动画开始| PropTypes.func |
| onPlayerDisplayModeChangedDidAppear |播放器显示模式动画结束| PropTypes.func |
| onPlayerTapGestureRecognizer |点击播放器手势通知| PropTypes.func |
| onPlayerDidPersistContentKey |FairPlay DRM| PropTypes.func |

方法

| function | description |
| --- | --- |
| play() | 播放 |
| pause() | 暂停 |
| stop() | 结束 |
| seek(time, callback) | 设置播放进度,单位秒 |
| replaceToPlay(source) | 替换播放源 |
| rate(rate) | 设置播放速率 |
| autoPlay(autoPlay) | 设置自动播放,autoPlay是PropTypes.bool |
| videoGravity(videoGravity) | 设置视频画面比例,videoGravity:aspect,aspectFill,scaleFill |
| toEmbedded(animated = true, callback) | 进入嵌入屏模式 |
| toFloat(animated = true, callback) | 进入悬浮屏模式 |
| toFull(orientation = 'landscapeLeft', animated = true, callback) | 进入全屏模式,orientation: landscapeLeft , landscapeRight |
| fullScreenMode(fullScreenMode)| 设置全屏的模式,fullScreenMode:portrait , landscape |

demo文件:

BasePlayerExample.js : EZPlayer的基础功能演示

TablePlayerExample.js :EZPlayer 在列表中的演示

TablePlayerCell.js : 列表的cell

EZCustomPlayer.js : 对EZPlayer.js进行封装,使用自定义ui,自定义ui可参考

Utils.js : 工具类

使用

//基本使用
//BasePlayerExample.js
        <EZPlayer
          ref={(e) => this._ezPlayer = e}
          style={styles.player}
          source={this.state.source }

          autoPlay={true}
          videoGravity={'aspect'} 
          fullScreenMode={'landscape'}
        />
//自定义ui
//EZCustomPlayer.js
          <TouchableWithoutFeedback onPress={this.action.onScreenTouch}>
                <View>
                    <EZPlayer
                        {...this.props}
                        useDefaultUI={false}
                        ref={(nativePlayer) => this.player.ref = nativePlayer}
                        style={this.props.style}
                        onPlayerHeartbeat={this.events.onPlayerHeartbeat}
                        onPlayerPlaybackTimeDidChange={this.events.onPlayerPlaybackTimeDidChange}
                        onPlayerStatusDidChange={this.events.onPlayerStatusDidChange}
                        onPlayerPlaybackDidFinish={this.events.onPlayerPlaybackDidFinish}
                        onPlayerLoadingDidChange={this.events.onPlayerLoadingDidChange}
                        onPlayerControlsHiddenDidChange={this.events.onPlayerControlsHiddenDidChange}
                        onPlayerDisplayModeDidChange={this.events.onPlayerDisplayModeDidChange}
                        onPlayerDisplayModeChangedWillAppear={this.events.onPlayerDisplayModeChangedWillAppear}
                        onPlayerDisplayModeChangedDidAppear={this.events.onPlayerDisplayModeChangedDidAppear}
                        onPlayerTapGestureRecognizer={this.events.onPlayerTapGestureRecognizer}
                        onPlayerDidPersistContentKey={this.events.onPlayerDidPersistContentKey}
                    />
                    {this.renderLoader()}
                    {this.renderBottomControls()}
                </View>
            </TouchableWithoutFeedback>

ps: react-native-ezplayer整理中

Todo

  • 支持VR

  • 支持iPad pip

  • 支持本地m3u8

  • 支持多码率控制

  • 支持3d touch截图,截图后简单处理

  • 支持边缓存边下载

  • 支持视频解密播放

  • 支持tvOS

  • 支持播放百分比触发

  • 国际化

  • 记忆播放

  • 支持滤镜

License

EZPlayer遵守MIT协议,具体请参考MIT

相关源码推荐:

我来说两句
*滑动验证:
所有评论(12)
逆鳞九霄 2017-11-1 11:09:31
学习学习!
回复
phoiu 2017-11-1 11:09:55
支持,感谢,祝code4app越来越好~
回复
kengsir 2017-11-1 11:10:06
mark,收藏了
回复
BlueManlove 2017-11-1 11:11:10
code4app好的内容真的很多~赞
回复
littleRed 2017-11-1 11:11:35
感谢分享,code4app有你更精彩
回复
AlonMessi 2017-11-1 11:12:12
内容很好,棒棒哒
回复
hellokenken 2017-11-1 11:12:33
写的真的很不错
回复
code4app热心网友 2017-11-1 16:25:09
淡定,淡定,淡定……
回复
code4app热心网友 2017-11-2 11:11:18
精华内容,楼主V5!
回复
12下一页
提取码:  下载次数:51 状态:已购或VIP 售价:0(原价:0)金钱 下载权限:初级码农 
1906 0 51
联系我们
首页/微信公众账号投稿

帖子代码编辑/版权问题

QQ:435399051,742864542

如何获得代码达人称号?

代码贡献英雄榜
用户名 下载数
通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

快速回复 返回顶部 返回列表