推荐页面
This commit is contained in:
parent
65f82d59e1
commit
eaa1d76bbe
@ -150,6 +150,39 @@ class VPVideoAPI: NSObject {
|
|||||||
completer?(response.data?.list)
|
completer?(response.data?.list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///视频观看结束
|
||||||
|
static func requestViewingFinish(shortPlayId: String, videoId: String, activityId: String) {
|
||||||
|
var param = VPNetworkParameters(path: "/activeAfterWatchingVideo")
|
||||||
|
param.isLoding = false
|
||||||
|
param.isToast = false
|
||||||
|
param.parameters = [
|
||||||
|
"short_play_video_id" : videoId,
|
||||||
|
"short_play_id" : shortPlayId,
|
||||||
|
"activity_id" : activityId
|
||||||
|
]
|
||||||
|
|
||||||
|
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///上报播放时长
|
||||||
|
static func requestUploadPlayProgress(shortPlayId: String, videoId: String, seconds: Int) {
|
||||||
|
|
||||||
|
var param = VPNetworkParameters(path: "/uploadHistorySeconds")
|
||||||
|
param.isLoding = false
|
||||||
|
param.isToast = false
|
||||||
|
param.parameters = [
|
||||||
|
"video_id" : videoId,
|
||||||
|
"short_play_id" : shortPlayId,
|
||||||
|
"play_seconds" : seconds
|
||||||
|
]
|
||||||
|
|
||||||
|
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<String>) in
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension VPVideoAPI {
|
extension VPVideoAPI {
|
||||||
|
@ -22,8 +22,14 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
|
|||||||
|
|
||||||
private var detailModel: VPVideoDetailModel?
|
private var detailModel: VPVideoDetailModel?
|
||||||
|
|
||||||
|
///上一次上报播放时长的节点
|
||||||
|
private var lastUploadProgress: Int = 0
|
||||||
|
|
||||||
///推荐列表
|
///推荐列表
|
||||||
private lazy var recommandList: [VPShortModel] = []
|
private lazy var recommandList: [VPShortModel] = []
|
||||||
|
///是否展示推荐
|
||||||
|
private lazy var isShowRecommand = false
|
||||||
|
private var recommandTimer: Timer?
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
private lazy var backButton: UIButton = {
|
private lazy var backButton: UIButton = {
|
||||||
@ -52,7 +58,8 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
|
|||||||
self.delegate = self
|
self.delegate = self
|
||||||
self.dataSource = self
|
self.dataSource = self
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: VPIAPManager.buyVipFinishNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: VPIAPManager.buyVipFinishNotification, object: nil)
|
||||||
self.jx_popDelegate = self
|
// self.jx_popDelegate = self
|
||||||
|
self.jx_popGestureType = .disabled
|
||||||
|
|
||||||
requestDetailData()
|
requestDetailData()
|
||||||
requestRecommandDataArr()
|
requestRecommandDataArr()
|
||||||
@ -67,6 +74,9 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
|
|||||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
|
super.viewWillDisappear(animated)
|
||||||
|
}
|
||||||
|
|
||||||
override func play() {
|
override func play() {
|
||||||
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
|
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
|
||||||
@ -84,28 +94,44 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
|
|||||||
VPVideoAPI.requestCreatePlayHistory(videoId: videoInfo.short_play_video_id, shortPlayId: videoInfo.short_play_id)
|
VPVideoAPI.requestCreatePlayHistory(videoId: videoInfo.short_play_video_id, shortPlayId: videoInfo.short_play_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func currentPlayFinish() {
|
||||||
|
if let videoInfo = self.viewModel.currentPlayer?.videoInfo, let shortPlayId = videoInfo.short_play_id, let videoId = videoInfo.short_play_video_id {
|
||||||
|
if let activityId = self.activityId {
|
||||||
|
//播放完成统计
|
||||||
|
VPVideoAPI.requestViewingFinish(shortPlayId: shortPlayId, videoId: videoId, activityId: activityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
//播放完成上报进度为0
|
||||||
|
VPVideoAPI.requestUploadPlayProgress(shortPlayId: shortPlayId, videoId: videoId, seconds: 0)
|
||||||
|
self.viewModel.currentPlayer?.videoInfo?.play_seconds = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
super.currentPlayFinish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func currentPlayTimeDidChange(time: Int) {
|
||||||
|
super.currentPlayTimeDidChange(time: time)
|
||||||
|
|
||||||
|
//每播放5秒上报一次 播放时长小于上次上报时间也需要上报
|
||||||
|
if (time >= lastUploadProgress + 5 || time < lastUploadProgress) && time >= 5 {
|
||||||
|
lastUploadProgress = time
|
||||||
|
uploadPlayProgress()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc func handleBackButton() {
|
@objc func handleBackButton() {
|
||||||
guard recommandList.count > 0 else {
|
guard recommandList.count > 0, isShowRecommand else {
|
||||||
self.handleBack()
|
self.handleBack()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pause()
|
self.pause()
|
||||||
|
|
||||||
let view = VPDetailRecommandView()
|
onRecommandView()
|
||||||
view.dataArr = recommandList
|
|
||||||
view.clickCloseButton = { [weak self] in
|
|
||||||
self?.handleBack()
|
|
||||||
}
|
|
||||||
view.clickLookButton = { [weak self] model in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.shortPlayId = model.short_play_id
|
|
||||||
self.activityId = nil
|
|
||||||
self.requestDetailData()
|
|
||||||
}
|
|
||||||
view.present(in: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension VPDetailPlayerViewController {
|
extension VPDetailPlayerViewController {
|
||||||
@ -213,6 +239,43 @@ extension VPDetailPlayerViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///上报播放进度
|
||||||
|
private func uploadPlayProgress() {
|
||||||
|
let videoInfo = self.viewModel.currentPlayer?.videoInfo
|
||||||
|
let currentTime = self.viewModel.currentPlayer?.currentPosition ?? 0
|
||||||
|
let duration = self.viewModel.currentPlayer?.duration ?? 0
|
||||||
|
|
||||||
|
var time = currentTime
|
||||||
|
if currentTime >= duration {
|
||||||
|
time = 0
|
||||||
|
}
|
||||||
|
self.viewModel.currentPlayer?.videoInfo?.play_seconds = time * 1000
|
||||||
|
|
||||||
|
guard let shortPlayId = videoInfo?.short_play_id, let videoId = videoInfo?.short_play_video_id else { return }
|
||||||
|
//上报播放时长
|
||||||
|
VPVideoAPI.requestUploadPlayProgress(shortPlayId: shortPlayId, videoId: videoId, seconds: time * 1000)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private func onRecommandView() {
|
||||||
|
let view = VPDetailRecommandView()
|
||||||
|
view.dataArr = recommandList
|
||||||
|
view.clickCloseButton = { [weak self] in
|
||||||
|
self?.handleBack()
|
||||||
|
}
|
||||||
|
view.clickLookButton = { [weak self] model in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.shortPlayId = model.short_play_id
|
||||||
|
self.activityId = nil
|
||||||
|
self.requestDetailData()
|
||||||
|
}
|
||||||
|
view.present(in: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handleRecommandTimer() {
|
||||||
|
self.isShowRecommand = true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: -------------- VPPlayerListViewControllerDataSource --------------
|
//MARK: -------------- VPPlayerListViewControllerDataSource --------------
|
||||||
@ -248,19 +311,34 @@ extension VPDetailPlayerViewController: VPPlayerListViewControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: -------------- JXViewControllerPopDelegate --------------
|
////MARK: -------------- JXViewControllerPopDelegate --------------
|
||||||
extension VPDetailPlayerViewController: JXViewControllerPopDelegate {
|
//extension VPDetailPlayerViewController: JXViewControllerPopDelegate {
|
||||||
func viewControllerPopShouldScrollBegan() -> Bool {
|
// func viewControllerPopShouldScrollBegan() -> Bool {
|
||||||
self.handleBackButton()
|
// self.handleBackButton()
|
||||||
return false
|
// return false
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//MARK: -------------- APP生命周期 --------------
|
||||||
|
extension VPDetailPlayerViewController {
|
||||||
|
|
||||||
|
override func willResignActiveNotification() {
|
||||||
|
super.willResignActiveNotification()
|
||||||
|
uploadPlayProgress()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension VPDetailPlayerViewController {
|
extension VPDetailPlayerViewController {
|
||||||
|
|
||||||
private func requestDetailData() {
|
private func requestDetailData() {
|
||||||
guard let shortPlayId = shortPlayId else { return }
|
guard let shortPlayId = shortPlayId else { return }
|
||||||
|
|
||||||
|
isShowRecommand = false
|
||||||
|
recommandTimer?.invalidate()
|
||||||
|
recommandTimer = nil
|
||||||
|
recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false)
|
||||||
|
|
||||||
|
|
||||||
VPHUD.show(containerView: self.view)
|
VPHUD.show(containerView: self.view)
|
||||||
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
|
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
|
||||||
VPHUD.dismiss()
|
VPHUD.dismiss()
|
||||||
|
@ -13,33 +13,77 @@ class VPDetailRecommandBannerCell: FSPagerViewCell {
|
|||||||
var model: VPShortModel? {
|
var model: VPShortModel? {
|
||||||
didSet {
|
didSet {
|
||||||
coverImageView.vp_setImage(url: model?.image_url)
|
coverImageView.vp_setImage(url: model?.image_url)
|
||||||
|
|
||||||
|
player.setPlayUrl(url: model?.video_url ?? "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private lazy var player: VPPlayer = {
|
var isCurrentPlayer: Bool = false {
|
||||||
//
|
didSet {
|
||||||
// }()
|
if !isCurrentPlayer {
|
||||||
|
coverImageView.isHidden = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private(set) lazy var player: VPPlayer = {
|
||||||
|
let player = VPPlayer()
|
||||||
|
player.playerView = playerView
|
||||||
|
player.delegate = self
|
||||||
|
return player
|
||||||
|
}()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private lazy var coverImageView: VPImageView = {
|
private lazy var coverImageView: VPImageView = {
|
||||||
let imageView = VPImageView()
|
let imageView = VPImageView()
|
||||||
imageView.layer.cornerRadius = 14
|
|
||||||
imageView.layer.masksToBounds = true
|
|
||||||
return imageView
|
return imageView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
private lazy var playerView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
contentView.layer.cornerRadius = 14
|
||||||
|
contentView.layer.masksToBounds = true
|
||||||
|
|
||||||
|
contentView.addSubview(playerView)
|
||||||
contentView.addSubview(coverImageView)
|
contentView.addSubview(coverImageView)
|
||||||
|
|
||||||
coverImageView.snp.makeConstraints { make in
|
coverImageView.snp.makeConstraints { make in
|
||||||
make.edges.equalToSuperview()
|
make.edges.equalToSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor required init?(coder aDecoder: NSCoder) {
|
@MainActor required init?(coder aDecoder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- SPPlayerDelegate --------------
|
||||||
|
extension VPDetailRecommandBannerCell: VPPlayerDelegate {
|
||||||
|
func vp_player(_ player: VPPlayer, loadStateDidChange state: VPPlayer.LoadState) {
|
||||||
|
updateCoverShowState()
|
||||||
|
}
|
||||||
|
|
||||||
|
func vp_player(_ player: VPPlayer, playStateDidChanged state: VPPlayer.PlayState) {
|
||||||
|
updateCoverShowState()
|
||||||
|
}
|
||||||
|
|
||||||
|
///更新封面显示状态
|
||||||
|
private func updateCoverShowState() {
|
||||||
|
let loadState = self.player.loadState
|
||||||
|
let playState = self.player.playState
|
||||||
|
if isCurrentPlayer && (loadState == .playable || loadState == .playthroughOK) && (playState == .playing) {
|
||||||
|
self.coverImageView.isHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -28,6 +28,16 @@ class VPDetailRecommandView: HWPanModalContentView {
|
|||||||
var clickCloseButton: (() -> Void)?
|
var clickCloseButton: (() -> Void)?
|
||||||
var clickLookButton: ((_ model: VPShortModel) -> Void)?
|
var clickLookButton: ((_ model: VPShortModel) -> Void)?
|
||||||
|
|
||||||
|
private var currentCell: VPDetailRecommandBannerCell? {
|
||||||
|
didSet {
|
||||||
|
if oldValue == currentCell { return }
|
||||||
|
|
||||||
|
oldValue?.isCurrentPlayer = false
|
||||||
|
oldValue?.player.pause()
|
||||||
|
|
||||||
|
currentCell?.isCurrentPlayer = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
@ -117,6 +127,10 @@ class VPDetailRecommandView: HWPanModalContentView {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
vpLog(message: "销毁")
|
||||||
|
}
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
@ -175,8 +189,16 @@ extension VPDetailRecommandView {
|
|||||||
|
|
||||||
private func setVideoTitle() {
|
private func setVideoTitle() {
|
||||||
let index = self.bannerView.currentIndex
|
let index = self.bannerView.currentIndex
|
||||||
let cell = self.bannerView.cellForItem(at: index)
|
guard self.dataArr.count > index else { return }
|
||||||
vpLog(message: cell)
|
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
let cell = self.bannerView.cellForItem(at: index) as? VPDetailRecommandBannerCell
|
||||||
|
self.currentCell = cell
|
||||||
|
self.currentCell?.player.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
let model = self.dataArr[index]
|
let model = self.dataArr[index]
|
||||||
videoTitleLabel.text = model.name
|
videoTitleLabel.text = model.name
|
||||||
@ -279,6 +301,13 @@ extension VPDetailRecommandView: FSPagerViewDelegate, FSPagerViewDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func pagerViewDidEndDecelerating(_ pagerView: FSPagerView) {
|
func pagerViewDidEndDecelerating(_ pagerView: FSPagerView) {
|
||||||
|
let newCell = pagerView.cellForItem(at: pagerView.currentIndex)
|
||||||
|
if newCell == currentCell {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.currentCell?.isCurrentPlayer = false
|
||||||
|
self.currentCell?.player.pause()
|
||||||
|
|
||||||
setVideoTitle()
|
setVideoTitle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user