diff --git a/YouerLiveVideo/YouerLiveVideo.xcodeproj/project.pbxproj b/YouerLiveVideo/YouerLiveVideo.xcodeproj/project.pbxproj index 0571235..e89d35b 100644 --- a/YouerLiveVideo/YouerLiveVideo.xcodeproj/project.pbxproj +++ b/YouerLiveVideo/YouerLiveVideo.xcodeproj/project.pbxproj @@ -48,6 +48,8 @@ 599B2CE21DE52F7E00B4F7FD /* UMSocialShareScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 599B2CD01DE52F7E00B4F7FD /* UMSocialShareScrollView.m */; }; 599B2CE31DE52F7E00B4F7FD /* UMSocialUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 599B2CD21DE52F7E00B4F7FD /* UMSocialUIManager.m */; }; 59AE3DF91ECE8A90003E2C62 /* pinyin.c in Sources */ = {isa = PBXBuildFile; fileRef = 59AE3DF71ECE8A90003E2C62 /* pinyin.c */; }; + 59AE3DFB1ECECD7D003E2C62 /* LiveInforViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59AE3DFA1ECECD7D003E2C62 /* LiveInforViewController.swift */; }; + 59AE3DFD1ECED5B1003E2C62 /* MoivePlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59AE3DFC1ECED5B1003E2C62 /* MoivePlayerViewController.swift */; }; 59BA13251E25CF2B00540DE0 /* AliyunPlayerSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 59BA13241E25CF2B00540DE0 /* AliyunPlayerSDK.framework */; }; 59BA13271E25CF4B00540DE0 /* AliyunPlayerSDK.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 59BA13241E25CF2B00540DE0 /* AliyunPlayerSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 59BA13311E25D1C000540DE0 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 59BA13301E25D1C000540DE0 /* Reachability.m */; }; @@ -332,6 +334,8 @@ 599B2CD21DE52F7E00B4F7FD /* UMSocialUIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UMSocialUIManager.m; sourceTree = ""; }; 59AE3DF71ECE8A90003E2C62 /* pinyin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pinyin.c; sourceTree = ""; }; 59AE3DF81ECE8A90003E2C62 /* pinyin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pinyin.h; sourceTree = ""; }; + 59AE3DFA1ECECD7D003E2C62 /* LiveInforViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LiveInforViewController.swift; sourceTree = ""; }; + 59AE3DFC1ECED5B1003E2C62 /* MoivePlayerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoivePlayerViewController.swift; sourceTree = ""; }; 59BA13241E25CF2B00540DE0 /* AliyunPlayerSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AliyunPlayerSDK.framework; path = YouerLiveVideo/lib/AliyunPlayerSDK.framework; sourceTree = ""; }; 59BA132F1E25D1C000540DE0 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; 59BA13301E25D1C000540DE0 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; @@ -613,6 +617,8 @@ isa = PBXGroup; children = ( 5904FC471ECA8B8C00E631FF /* ResourceViewController.swift */, + 59AE3DFA1ECECD7D003E2C62 /* LiveInforViewController.swift */, + 59AE3DFC1ECED5B1003E2C62 /* MoivePlayerViewController.swift */, 597185B41ECA990C00D7F478 /* Resource.storyboard */, ); path = Resource; @@ -1499,6 +1505,7 @@ BF25DFF31DDAA36A003EC0C1 /* Timeline.swift in Sources */, BF25DFFE1DDAA36A003EC0C1 /* SDWebImageDownloader.m in Sources */, BF7B75A51E305A6D0011D5C7 /* MJRefreshConst.m in Sources */, + 59AE3DFB1ECECD7D003E2C62 /* LiveInforViewController.swift in Sources */, BF7B759B1E305A6D0011D5C7 /* MJRefreshAutoGifFooter.m in Sources */, BF7B75A81E305A6D0011D5C7 /* UIScrollView+MJRefresh.m in Sources */, BF25E0021DDAA36A003EC0C1 /* UIButton+WebCache.m in Sources */, @@ -1512,6 +1519,7 @@ BFDFDED21DD55C0D0040F102 /* network.swift in Sources */, 599B2CE11DE52F7E00B4F7FD /* UMShareMenuSelectionView.m in Sources */, BF25DFFF1DDAA36A003EC0C1 /* SDWebImageDownloaderOperation.m in Sources */, + 59AE3DFD1ECED5B1003E2C62 /* MoivePlayerViewController.swift in Sources */, BF25DFF01DDAA36A003EC0C1 /* SessionDelegate.swift in Sources */, BF25DFE31DDAA36A003EC0C1 /* Alamofire.swift in Sources */, BF25DFEC1DDAA36A003EC0C1 /* Response.swift in Sources */, diff --git a/YouerLiveVideo/YouerLiveVideo/controllers/Resource/LiveInforViewController.swift b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/LiveInforViewController.swift new file mode 100644 index 0000000..73764c6 --- /dev/null +++ b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/LiveInforViewController.swift @@ -0,0 +1,88 @@ +// +// LiveInforViewController.swift +// YouerLiveVideo +// +// Created by 左丞 on 2017/5/19. +// Copyright © 2017年 左丞. All rights reserved. +// + +import UIKit + +class LiveInforViewController: UIViewController { + + + @IBOutlet weak var player: UIView! + @IBOutlet weak var livePalyer: UIView! + @IBOutlet weak var updataPersonPhoto: UIImageView! + @IBOutlet weak var updataPersonName: UILabel! + @IBOutlet weak var updataTime: UILabel! + + var tvStation:TVStationSubject! + override func viewDidLoad() { + super.viewDidLoad() + AppDelegate.instance().httpServer.getResourceModel(parameters: ["f_id":"2be92331-ea5a-41c9-9025-c954d7df904c" as AnyObject]) { (str, error) in + httpJsonResule(jsonString: str, error: error, successHandler: { (json) in + self.tvStation = TVStationSubject(json: json.contentData()) + self.setAllInfor() + }, failHandler: { (error) in + + }) + } + // Do any additional setup after loading the view. + } + + func setAllInfor(){ + updataTime.text = setDateToString(date: dateFromISO8601(dateString: tvStation.f_CreatorTime)) + updataPersonName.text = "上传者: \(tvStation.f_CreatorName!)" + updataPersonPhoto.layer.cornerRadius = updataPersonPhoto.frame.size.height/2 + updataPersonPhoto.layer.masksToBounds = true + updataPersonPhoto.sd_setImage(with: URL(string: tvStation.f_Img), placeholderImage: #imageLiteral(resourceName: "defphoto.png")) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "player"{ + let vc = segue.destination as! MoivePlayerViewController + vc.mSourceURL = URL(string: "http://vote-weiyun.oss-cn-hangzhou.aliyuncs.com/Videos/c0b2ddd5-46df-41b1-ac4f-bf5e06ee50c0.mp4") + vc.isFullAndHiddenAllBtn = true + } + + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} + +extension LiveInforViewController:UITableViewDelegate,UITableViewDataSource{ + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! RemainCell + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 3 + } +} + +class RemainCell: UITableViewCell { + + + @IBOutlet weak var remainContent: UILabel! + @IBOutlet weak var remainName: UILabel! + @IBOutlet weak var remainPhoto: UIImageView! + +} + + diff --git a/YouerLiveVideo/YouerLiveVideo/controllers/Resource/MoivePlayerViewController.swift b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/MoivePlayerViewController.swift new file mode 100644 index 0000000..aa8d702 --- /dev/null +++ b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/MoivePlayerViewController.swift @@ -0,0 +1,599 @@ +// +// MoivePlayerViewController.swift +// XSTVideoPalyer +// +// Created by 左丞 on 16/11/23. +// Copyright © 2016年 左丞. All rights reserved. +// + +import UIKit +import Foundation +import MediaPlayer + +enum GestrueType { + case None + case Volume + case Brightness + case Progress +} + + +class MoivePlayerViewController: UIViewController,AliVcAccessKeyProtocol{ + + @IBOutlet weak var pauseImageBtn: UIButton! + @IBOutlet weak var endTime: UILabel! + @IBOutlet weak var startTime: UILabel! + @IBOutlet weak var slider: UISlider! + @IBOutlet weak var screenHorizontalBtn: UIButton! + var mPlayerView:UIView! + var activityBackgroundView:UIView! + var activityIndicator:UIActivityIndicatorView! + var mPlayer:AliVcMediaPlayer! + var systemBrightness:CGFloat!//屏幕亮度 + var conn:Reachability! + var isReplay:Bool = false + var mPaused:Bool = false + var mSourceURL:URL! + + var isLive:Bool = true + var accessKeyID = "LTAIDOJoPQejwtoF" + var accessKeySecret = "rCRMo1TFvBWIkKASB59DRmRJxm9GyK" + var liveTeacherPicture:String="" + var liveTeacherName:String! + var timer:Timer! + var activePersonNum:NSInteger = 0 + var mTimer:Timer! + var bSeeking:Bool = false + var gestureType:GestrueType = .None + var originalLocation:CGPoint! + var progressValue:CGFloat = 0 + var liveOrVideoUrlString:String = "" + var isAllBtnHidden:Bool = false + var isFullAndHiddenAllBtn:Bool = false + func getAccessKeyIDSecret() -> AliVcAccesskey! { + let accessKey = AliVcAccesskey() + accessKey.accessKeyId = accessKeyID + accessKey.accessKeySecret = accessKeySecret + return accessKey + } + override func viewDidLoad() { + super.viewDidLoad() + mSourceURL = URL(string:liveOrVideoUrlString) + AliVcMediaPlayer.setAccessKeyDelegate(self) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.becomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.resignActive), name: NSNotification.Name.UIApplicationWillResignActive, object: nil) + + playMoive() + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.networkStateChange), name: NSNotification.Name.reachabilityChanged, object: nil) + conn = Reachability.forInternetConnection() + conn.startNotifier() + hiddenAllBtn() + displayAllBtn() + + // Do any additional setup after loading the view. + } + + // 返回状态栏的样式 + override var preferredStatusBarStyle: UIStatusBarStyle{ + return UIStatusBarStyle.lightContent + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + if timer != nil{ + timer.invalidate() + timer = nil + } + if mTimer != nil{ + mTimer.invalidate() + mTimer = nil + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + displayAllBtn() + systemBrightness = UIScreen.main.brightness + + if mSourceURL == nil{ + self.dismiss(animated: true, completion: nil) + AppDelegate.instance().window?.makeToast("该直播或点播不存在") + return + } + + AppDelegate.instance().blockRotation = true + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + UIScreen.main.brightness = systemBrightness + } + + func becomeActive(){ + EnterForeGroundPlayVideo() + + } + + func resignActive(){ + EnterBackGroundPauseVideo() + } + + func EnterBackGroundPauseVideo(){ + if mPlayer != nil && !mPaused { + mPlayer.pause() + pauseImageBtn.isHidden = false + } + UIScreen.main.brightness = systemBrightness + } + + func EnterForeGroundPlayVideo(){ + if mPlayer != nil && !mPaused { + mPlayer.play() + + } + UIScreen.main.brightness = systemBrightness + } + + func networkStateChange(){ + if mSourceURL != nil && mSourceURL.isFileURL{ + checkNetworkState() + } + } + + func checkNetworkState(){ + let wifi = Reachability.forLocalWiFi() + conn = Reachability.forInternetConnection() + if wifi?.currentReachabilityStatus() != NotReachable{ + NSLog("有wifi") + }else if conn.currentReachabilityStatus() != NotReachable{ + NSLog("使用手机自带网络进行上网") + }else{ + NSLog("没有网络") + } + } + func displayAllBtn(){ + if isFullAndHiddenAllBtn{ + pauseImageBtn.isHidden = false + return + } + isAllBtnHidden = false + for i in 0...2{ + self.view.viewWithTag(200+i)?.isHidden = false + } + if !isLive{ + displaySlider() + } + if timer != nil{ + timer.invalidate() + timer = nil + } + timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(MoivePlayerViewController.hiddenAllBtn), userInfo: nil, repeats: false) + } + + func hiddenAllBtn(){ + isAllBtnHidden = true + for i in 0...6{ + self.view.viewWithTag(200+i)?.isHidden = true + } + } + + func displaySlider(){ + if isFullAndHiddenAllBtn{ + return + } + for i in 3...6{ + self.view.viewWithTag(200+i)?.isHidden = false + } + } + + func setupControls(){ + mPlayerView = UIView(frame: CGRect(x: 0, y: 0, width: getScreenWidth(), height: getScreenHeight())) + mPlayerView.backgroundColor = UIColor.clear + self.view.insertSubview(mPlayerView, at: 0) + //缓冲指示 + activityBackgroundView = UIView() + activityBackgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.5) + activityBackgroundView.alpha = 0 + activityBackgroundView.center = mPlayerView.center + activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) + activityIndicator.hidesWhenStopped = true + activityIndicator.center = mPlayerView.center + activityIndicator.alpha = 0 + } + + func playMoive(){ + if mSourceURL == nil{ + return + } + setupControls() + mPlayer = AliVcMediaPlayer() + mPlayer.create(mPlayerView) + mPlayer.scalingMode = scalingModeAspectFit + mPlayer.view.isUserInteractionEnabled = true + addPlayerObserver() + if isLive{ + mPlayer.mediaType = 1 + }else{ + mPlayer.mediaType = 0 + mTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MoivePlayerViewController.onTick(_:)), userInfo: nil, repeats: true) + + } + mPlayer.timeout = 25000 + mPlayer.dropBufferDuration = 8000 + mPlayer.scalingMode = scalingModeAspectFitWithCropping + isReplay = false + bSeeking = false + var err = mPlayer.prepare(toPlay: mSourceURL) + if err != ALIVC_SUCCESS{ + activityBackgroundView.removeFromSuperview() + activityIndicator.removeFromSuperview() + return + } + err = mPlayer.play() + if err != ALIVC_SUCCESS{ + return + } + changeMPlayFrame() + showLoadingIndicators() + mPlayer.pause() + pauseImageBtn.isHidden = false + } + func onTick(_ timer:Timer){ + if self.bSeeking { + return + } + if self.mPlayer != nil{ + self.slider.value = Float(self.mPlayer.currentPosition) + self.startTime.text = self.creatTime(timeInter: self.mPlayer.currentPosition) + self.endTime.text = self.creatTime(timeInter: self.mPlayer.duration) + } + } + func replayMoive(){ + mPlayer.prepare(toPlay: mSourceURL) + isReplay = false + bSeeking = false + mPlayer.play() + + } + + @IBAction func isHorScreenClickAction(_ sender: UIButton) { + screenHorizontalBtn.isSelected = !screenHorizontalBtn.isSelected + if screenHorizontalBtn.isSelected{ + screenHorizontalBtn.setBackgroundImage(#imageLiteral(resourceName: "screen_part"), for: .normal) + displayAllBtn() + UIApplication.shared.statusBarOrientation = .landscapeRight + UIApplication.shared.keyWindow?.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_2)) + UIApplication.shared.keyWindow?.frame = CGRect(x: 0, y: 0, width: getScreenHeight(), height: getScreenWidth()) + }else{ + screenHorizontalBtn.setBackgroundImage(#imageLiteral(resourceName: "screen_full"), for: .normal) + UIApplication.shared.statusBarOrientation = .portrait + UIApplication.shared.keyWindow?.transform = CGAffineTransform(rotationAngle: 0) + UIApplication.shared.keyWindow?.frame = CGRect(x: 0, y: 0, width: getScreenWidth(), height: getScreenHeight()) + } + changeMPlayFrame() + } + + override var shouldAutorotate: Bool{ + return false + } + + @IBAction func backBtnClickAction(_ sender: UIButton) { + if screenHorizontalBtn.isSelected{ + isHorScreenClickAction(screenHorizontalBtn) + displayAllBtn() + }else{ + UIApplication.shared.statusBarOrientation = .portrait + UIApplication.shared.keyWindow?.transform = CGAffineTransform(rotationAngle: 0) + UIApplication.shared.keyWindow?.frame = CGRect(x: 0, y: 0, width: getScreenWidth(), height: getScreenHeight()) + AppDelegate.instance().blockRotation = false + if mPlayer != nil{ + mPlayer.destroy() + } + removePlayerObserver() + mPlayer = nil + mSourceURL = nil + self.dismiss(animated: true, completion: nil) + } + } + + @IBAction func playPauseClickAction(_ sender: UIButton) { + if sender == pauseImageBtn{ + sender.isHidden = true + } + displayAllBtn() + if mPlayer != nil{ + if sender.isSelected{ + sender.setBackgroundImage(#imageLiteral(resourceName: "starLive"), for: .normal) + if isReplay { + if isLive{ + mPlayer.prepare(toPlay: mSourceURL) + }else{ + mPlayer.play() + } + isReplay = false + bSeeking = false + } + mPlayer.muteMode = false + }else{ + isReplay = true + sender.setBackgroundImage(#imageLiteral(resourceName: "pause"), for: .normal) + mPaused = true + mPlayer.pause() + pauseImageBtn.isHidden = false + } + sender.isSelected = !sender.isSelected + } + // self.perform(#selector(MoivePlayerViewController.hideControls(com)), with: nil, afterDelay: fadeDelay) + + } + + @IBAction func sliderPanAction(_ sender: UISlider) { + displayAllBtn() + bSeeking = true + startTime.text = creatTime(timeInter: TimeInterval(sender.value)) + if mPlayer != nil{ + mPlayer.seek(to: TimeInterval(sender.value)) + } + } + + func showLoadingIndicators(){ + self.view.addSubview(activityBackgroundView) + self.view.addSubview(activityIndicator) + activityIndicator.startAnimating() + UIView.animate(withDuration: 0.2, animations: { + self.activityBackgroundView.alpha = 1 + self.activityIndicator.alpha = 1 + }) + } + + func hideLoadingIndicators(){ + UIView.animate(withDuration: 0.2, delay: 0, options: .layoutSubviews, animations: { + self.activityBackgroundView.alpha = 0 + self.activityIndicator.alpha = 0 + + }) { (finish) in + self.activityBackgroundView.removeFromSuperview() + self.activityIndicator.removeFromSuperview() + + } + } + + func changeMPlayFrame(){ + if mPlayer != nil && mPlayer.videoWidth != 0{ + let widthbi = CGFloat(mPlayer.videoWidth)/getScreenWidth() + let heightBi = CGFloat(mPlayer.videoHeight)/getScreenHeight() + if widthbi < heightBi || getScreenWidth()>getScreenHeight(){ + mPlayerView.frame = CGRect(x: 0, y: 0, width: getScreenWidth(), height: getScreenHeight()) + }else{ + mPlayerView.frame = CGRect(x: 0, y: 0, width: getScreenWidth(), height: CGFloat(ceil(CGFloat(mPlayer.videoHeight)/widthbi))) + } + }else{ + mPlayerView.frame = CGRect(x: 0, y: 0, width: getScreenWidth(), height: getScreenWidth()/5*3) + } + mPlayerView.center = self.view.center + mPlayer.view = mPlayerView + activityIndicator.center = mPlayerView.center + activityBackgroundView.center = mPlayerView.center + } + + func OnVideoPrepared(noti:Notification){ + slider.maximumValue = Float(mPlayer.duration) + slider.value = Float(mPlayer.currentPosition) + timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(MoivePlayerViewController.hiddenAllBtn), userInfo: nil, repeats: false) + changeMPlayFrame() + endTime.text = creatTime(timeInter: mPlayer.duration) + hideLoadingIndicators() + } + + func creatTime(timeInter:TimeInterval)->String{ + if timeInter > 0{ + let seconds = Int(timeInter)/1000 + return "\(seconds/60/60):\(seconds/60%60):\(seconds%60)" + } + return "0:00:00" + } + + func OnVideoError(noti:Notification){ + isReplay = true + var error_msg = "未知的错误" + let error_code:AliVcMovieErrorCode = mPlayer.errorCode + switch error_code { + case ALIVC_ERR_FUNCTION_DENIED: + error_msg = "未授权" + case ALIVC_ERR_ILLEGALSTATUS: + error_msg = "非法的播放流程" + case ALIVC_ERR_INVALID_INPUTFILE: + error_msg = " 主播还未开播..." + hideLoadingIndicators() + case ALIVC_ERR_NO_INPUTFILE: + error_msg = "无输入文件" + hideLoadingIndicators() + case ALIVC_ERR_NO_NETWORK: + error_msg = "网络连接失败" + case ALIVC_ERR_NO_SUPPORT_CODEC: + error_msg = "不支持的视频编码格式" + hideLoadingIndicators() + case ALIVC_ERR_NO_VIEW: + error_msg = "无显示窗口" + hideLoadingIndicators() + case ALIVC_ERR_NO_MEMORY: + error_msg = "内存不足" + case ALIVC_ERR_DOWNLOAD_TIMEOUT: + error_msg = "网络超时" + case ALIVC_ERR_UNKOWN: + error_msg = "未知错误" + default: + break; + } + if error_code > 500||error_code == ALIVC_ERR_FUNCTION_DENIED{ + mPlayer.reset() + let alertView = UIAlertController(title: nil, message: error_msg, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil)) + self.present(alertView, animated: true, completion: nil) + } + if error_code == ALIVC_ERR_DOWNLOAD_TIMEOUT{ + mPlayer.pause() + pauseImageBtn.isHidden = false + + let alertView = UIAlertController(title: nil, message: error_msg, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: "等待", style: .cancel, handler: nil)) + alertView.addAction(UIAlertAction(title: "重新连接", style: .default, handler: { (action) in + self.mPlayer.stop() + self.showLoadingIndicators() + self.isReplay = true +// replay() + })) + self.present(alertView, animated: true, completion: nil) + + } + + } + + func OnVideoFinish(noti:Notification){ + isReplay = true + playPauseClickAction(self.view.viewWithTag(202) as! UIButton) + mPlayer.stop() + } + + func OnSeekDone(noti:Notification){ + bSeeking = false + } + + func OnStartCache(noti:Notification){ + showLoadingIndicators() + } + + func OnEndCache(noti:Notification){ + hideLoadingIndicators() + } + + + func addPlayerObserver(){ + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnVideoPrepared(noti:)), name: NSNotification.Name.AliVcMediaPlayerLoadDidPrepared, object: mPlayer) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnVideoError(noti:)), name: NSNotification.Name.AliVcMediaPlayerPlaybackError, object: mPlayer) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnVideoFinish(noti:)), name: NSNotification.Name.AliVcMediaPlayerPlaybackDidFinish, object: mPlayer) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnSeekDone(noti:)), name: NSNotification.Name.AliVcMediaPlayerSeekingDidFinish, object: mPlayer) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnStartCache(noti:)), name: NSNotification.Name.AliVcMediaPlayerStartCaching, object: mPlayer) + NotificationCenter.default.addObserver(self, selector: #selector(MoivePlayerViewController.OnEndCache(noti:)), name: NSNotification.Name.AliVcMediaPlayerEndCaching, object: mPlayer) + + } + + func removePlayerObserver(){ + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerLoadDidPrepared, object: mPlayer) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerPlaybackError, object: mPlayer) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerPlaybackDidFinish, object: mPlayer) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerSeekingDidFinish, object: mPlayer) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerStartCaching, object: mPlayer) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AliVcMediaPlayerEndCaching, object: mPlayer) + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + bSeeking = true + originalLocation = CGPoint(x: 0, y: 0) + progressValue = 0 + } + + override func touchesMoved(_ touches: Set, with event: UIEvent?) { + displayAllBtn() + let touch = touches.first + let currenLocation = touch!.location(in: self.view) + let offset_x = currenLocation.x - originalLocation.x + let offset_y = currenLocation.y - originalLocation.y + if __CGPointEqualToPoint(originalLocation, CGPointZero){ + originalLocation = currenLocation + return + } + originalLocation = currenLocation + if abs(offset_x) <= abs(offset_y){ + gestureType = .Volume + }else if abs(offset_x) > abs(offset_y) { + gestureType = .Progress + } + if gestureType == .Progress{ + if mPlayer != nil{ + if offset_x > 0{ + if slider.value+ProgressStep*1000 <= Float(mPlayer.duration){ + slider.value = slider.value+ProgressStep*1000 + startTime.text = creatTime(timeInter: TimeInterval(slider.value)) + }else{ + slider.value = Float(mPlayer.duration) + startTime.text = creatTime(timeInter: mPlayer.duration) + } + }else{ + if slider.value-ProgressStep*1000 >= 0{ + slider.value = slider.value-ProgressStep*1000 + startTime.text = creatTime(timeInter: TimeInterval(slider.value)) + }else{ + slider.value = 0 + startTime.text = "0:0:0" + } + } + } + }else if gestureType == .Volume{ + volumeAdd(step: offset_y > 0 ? -VolumeStep : VolumeStep) + } + + } + + var VolumeStep:CGFloat = 0.02 + var ProgressStep:Float = 5 + override func touchesEnded(_ touches: Set, with event: UIEvent?) { + switch gestureType { + case .None: + if !isAllBtnHidden{ + playPauseClickAction(self.view.viewWithTag(202) as! UIButton) + } + break + case .Brightness: + progressValue = 0 + gestureType = .None + + case .Progress: + gestureType = .None + if mPlayer != nil{ + mPlayer.seek(to: TimeInterval(slider.value)) + } + progressValue = 0 + default: + break + } + bSeeking = false + displayAllBtn() + } + + //func willShowComments(_ seek: Bool) -> CGFloat { + // return commentNUM + //} + + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func volumeAdd(step:CGFloat){ + let volumeView = MPVolumeView() + var volumeSlider:UISlider! + for view in volumeView.subviews { + if view.classForCoder.description() == "MPVolumeSlider"{ + volumeSlider = view as? UISlider + break + } + } + volumeSlider.value = volumeSlider.value+Float(step) + } + // MARK: - 销毁通知 + deinit { + NotificationCenter.default.removeObserver(self) + } + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/YouerLiveVideo/YouerLiveVideo/controllers/Resource/Resource.storyboard b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/Resource.storyboard index c26d9fd..4b61339 100644 --- a/YouerLiveVideo/YouerLiveVideo/controllers/Resource/Resource.storyboard +++ b/YouerLiveVideo/YouerLiveVideo/controllers/Resource/Resource.storyboard @@ -5,6 +5,304 @@ + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/SearchTVStationListViewController.swift b/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/SearchTVStationListViewController.swift index f88a724..73b09b5 100644 --- a/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/SearchTVStationListViewController.swift +++ b/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/SearchTVStationListViewController.swift @@ -150,12 +150,12 @@ extension SearchTVStationListViewController:UITableViewDataSource,UITableViewDel } func sectionIndexTitles(for tableView: UITableView) -> [String]? { - if tableView == selectTableView{ - return [] - }else{ - return allKeys+["#"] + if tableView != selectTableView{ + if allKeys.count > 0{ + return allKeys+["#"] + } } - + return [] } func numberOfSections(in tableView: UITableView) -> Int { @@ -182,10 +182,6 @@ extension SearchTVStationListViewController:UITableViewDataSource,UITableViewDel return 44 } } - - func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { - return 1 - } } class SearchTVStationListCell: UITableViewCell { diff --git a/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/TVStation.storyboard b/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/TVStation.storyboard index e3704a0..8cf70ce 100644 --- a/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/TVStation.storyboard +++ b/YouerLiveVideo/YouerLiveVideo/controllers/TVStation/TVStation.storyboard @@ -145,29 +145,34 @@ - + + + + + + - - + + - + - + - +