推荐页面

This commit is contained in:
zjx 2025-06-07 09:34:30 +08:00
parent 65f82d59e1
commit eaa1d76bbe
4 changed files with 211 additions and 27 deletions

View File

@ -150,6 +150,39 @@ class VPVideoAPI: NSObject {
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 {

View File

@ -22,8 +22,14 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
private var detailModel: VPVideoDetailModel?
///
private var lastUploadProgress: Int = 0
///
private lazy var recommandList: [VPShortModel] = []
///
private lazy var isShowRecommand = false
private var recommandTimer: Timer?
//MARK: UI
private lazy var backButton: UIButton = {
@ -52,7 +58,8 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
self.delegate = self
self.dataSource = self
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()
requestRecommandDataArr()
@ -67,6 +74,9 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func play() {
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
@ -84,27 +94,43 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController {
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() {
guard recommandList.count > 0 else {
guard recommandList.count > 0, isShowRecommand else {
self.handleBack()
return
}
self.pause()
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)
onRecommandView()
}
}
@ -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 --------------
@ -248,19 +311,34 @@ extension VPDetailPlayerViewController: VPPlayerListViewControllerDelegate {
}
//MARK: -------------- JXViewControllerPopDelegate --------------
extension VPDetailPlayerViewController: JXViewControllerPopDelegate {
func viewControllerPopShouldScrollBegan() -> Bool {
self.handleBackButton()
return false
////MARK: -------------- JXViewControllerPopDelegate --------------
//extension VPDetailPlayerViewController: JXViewControllerPopDelegate {
// func viewControllerPopShouldScrollBegan() -> Bool {
// self.handleBackButton()
// return false
// }
//}
//MARK: -------------- APP --------------
extension VPDetailPlayerViewController {
override func willResignActiveNotification() {
super.willResignActiveNotification()
uploadPlayProgress()
}
}
extension VPDetailPlayerViewController {
private func requestDetailData() {
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)
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
VPHUD.dismiss()

View File

@ -13,33 +13,77 @@ class VPDetailRecommandBannerCell: FSPagerViewCell {
var model: VPShortModel? {
didSet {
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 = {
let imageView = VPImageView()
imageView.layer.cornerRadius = 14
imageView.layer.masksToBounds = true
return imageView
}()
private lazy var playerView: UIView = {
let view = UIView()
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.layer.cornerRadius = 14
contentView.layer.masksToBounds = true
contentView.addSubview(playerView)
contentView.addSubview(coverImageView)
coverImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
playerView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
@MainActor required init?(coder aDecoder: NSCoder) {
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
}
}
}

View File

@ -28,6 +28,16 @@ class VPDetailRecommandView: HWPanModalContentView {
var clickCloseButton: (() -> 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
@ -117,6 +127,10 @@ class VPDetailRecommandView: HWPanModalContentView {
}()
deinit {
vpLog(message: "销毁")
}
override init(frame: CGRect) {
super.init(frame: frame)
@ -175,8 +189,16 @@ extension VPDetailRecommandView {
private func setVideoTitle() {
let index = self.bannerView.currentIndex
let cell = self.bannerView.cellForItem(at: index)
vpLog(message: cell)
guard self.dataArr.count > index else { return }
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]
videoTitleLabel.text = model.name
@ -279,6 +301,13 @@ extension VPDetailRecommandView: FSPagerViewDelegate, FSPagerViewDataSource {
}
func pagerViewDidEndDecelerating(_ pagerView: FSPagerView) {
let newCell = pagerView.cellForItem(at: pagerView.currentIndex)
if newCell == currentCell {
return
}
self.currentCell?.isCurrentPlayer = false
self.currentCell?.player.pause()
setVideoTitle()
}