Wallpaper_Home/wallpaper_project/Home/C/WA_LiveVideoVC.swift
忆海16 5ff1070967 mtg
2024-07-23 11:44:01 +08:00

698 lines
28 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// WA_LiveVideoVC.swift
// wallpaper_project
import UIKit
import AVFoundation
import MobileCoreServices
import FLAnimatedImage
import Photos
import PhotosUI
import SVProgressHUD
import Lottie
import AppLovinSDK
import Alamofire
import FirebaseRemoteConfig
import MTGSDKNewInterstitial
import MTGSDKBidding
import MTGSDK
struct FilePaths {
//
static let documentsPath : AnyObject = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.userDomainMask,true)[0] as AnyObject
struct VidToLive {
//
static var livePath = FilePaths.documentsPath.appending("/")
}
}
class WA_LiveVideoVC: WA_RootVC {
@IBOutlet weak var bgView: UIView!
@IBOutlet weak var tipLabel: UILabel!
var model = WA_3DModel()
var livePhotoView = PHLivePhotoView()
let activityView = UIActivityIndicatorView()
let btn = UIButton()
// let bgView = UIView()
var sizi:CGSize?
let Retrybtn = UIButton()
private var animationView: LottieAnimationView?
var animationDuration: TimeInterval = 1.0
var workProgress: Float = 0.0
var remoteConfig: RemoteConfig!
var isadshow:Bool = false
var bidToken:String?
var newInterstitialAdManager:MTGNewInterstitialBidAdManager?
override func viewDidLoad() {
super.viewDidLoad()
livePhotoView.frame = CGRect(x: 0, y: 0, width: Screen_Width, height: screenHeight);
btn.setImage(UIImage(named: "back_black"), for: .normal)
btn.backgroundColor = .white
btn.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) //
btn.layer.cornerRadius = 20
self.view.addSubview(self.livePhotoView)
self.livePhotoView.addSubview(btn)
btn.snp.makeConstraints { make in
make.left.equalTo(livePhotoView).offset(20)
make.top.equalTo(livePhotoView).offset(50)
make.height.equalTo(40)
make.width.equalTo(40)
}
Retrybtn.setTitle("Retry", for: .normal)
Retrybtn.setTitleColor(.white, for: .normal)
Retrybtn.backgroundColor = .black
Retrybtn.addTarget(self, action: #selector(Retrybtntapped), for: .touchUpInside)
Retrybtn.layer.cornerRadius = 10
Retrybtn.isHidden = true
self.livePhotoView.addSubview(Retrybtn)
Retrybtn.snp.makeConstraints { make in
make.centerX.equalTo(livePhotoView)
make.centerY.equalTo(livePhotoView)
make.height.equalTo(40)
make.width.equalTo(80)
}
animationView = .init(name: "loadProgress")
animationView!.frame = CGRect(x: 0, y: 100, width: Int(Screen_Width), height: Int(Screen_height) - 100)
animationView!.contentMode = .scaleAspectFit
// animationView!.loopMode = .loop
animationView!.loopMode = .autoReverse
self.livePhotoView.addSubview(animationView!)
// animationView!.play()
self.animationView!.currentProgress = 0.1
animationView!.sendSubviewToBack(btn)
self.steMoV()
activityView.center = CGPoint(x: self.view.center.x, y: self.view.center.y - kSafeArea_Top - 44)
//
activityView.hidesWhenStopped = true
activityView.color = .black;
activityView.style = UIActivityIndicatorView.Style.whiteLarge
self.view.addSubview(activityView)
self.view.bringSubviewToFront(tipLabel)
self.view.bringSubviewToFront(bgView)
self.bgView.isHidden = true
self.tipLabel.isHidden = true
// self.btn.isHidden = true
// self.activityView.startAnimating()
self.view.makeToast("Picture loading Please wait", duration: 1.5, position: .center)
// UIView
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(viewTapped))
livePhotoView.isUserInteractionEnabled = true
livePhotoView.addGestureRecognizer(tapGesture)
let model1 = WA_3DModel()
model1.preview = self.model.preview
model1.title = self.model.title
model1.thumbnail = self.model.thumbnail
model1.is_free = self.model.is_free
model1.category = self.model.category
model1.id = self.model.id
model1.cnt_like = self.model.cnt_like
liveManager.shared.addHistoryItem(item: model1)
}
@objc func buttonTapped(){
let issureready = newInterstitialAdManager?.isAdReady()
if self.isadshow == true{
if ((issureready) != nil) {
newInterstitialAdManager?.show(from: self)
self.setPostSHOW()
}else{
self.navigationController?.popViewController(animated: true)
}
}else{
self.navigationController?.popViewController(animated: true)
}
// navigationController?.popViewController(animated: true)
}
@objc func Retrybtntapped(){
// self.activityView.startAnimating()
self.animationView?.isHidden = false
self.Retrybtn.isHidden = true
steMoV()
}
//
@objc func viewTapped() {
// UIView
if bgView.frame.origin.y == UIScreen.main.bounds.height - bgView.frame.height {
// UIView
UIView.animate(withDuration: 0.5, animations: {
self.bgView.frame.origin.y += self.bgView.frame.height
self.tipLabel.frame.origin.y += self.bgView.frame.height - 20
self.bgView.alpha = 0
self.btn.isHidden = true
})
} else {
self.btn.isHidden = false
// UIView
UIView.animate(withDuration: 0.5, animations: {
self.bgView.frame.origin.y -= self.bgView.frame.height
self.tipLabel.frame.origin.y -= self.bgView.frame.height - 20
self.bgView.alpha = 1
})
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isHidden = true
let size = self.view.bounds.size
self.sizi = size
// Remote Config
remoteConfig = RemoteConfig.remoteConfig()
//
let settings = RemoteConfigSettings()
settings.minimumFetchInterval = 0
remoteConfig.configSettings = settings
// Fetch
remoteConfig.setDefaults(fromPlist: "isopen")
let param = MTGBiddingRequestParameter(placementId: "1636950", unitId: "3501963", basePrice: nil)
MTGBiddingRequest.getBidWith(param) { bidResponse in
if bidResponse.success{
self.bidToken = bidResponse.bidToken
bidResponse.notifyWin()
self.newInterstitialAdManager = MTGNewInterstitialBidAdManager(placementId: "1636950", unitId: "3501963", delegate: self)
StartManager.shared.ecpm = Float(bidResponse.price)
self.newInterstitialAdManager?.loadAd(withBidToken:self.bidToken!)
self.fetchRemoteConfig()
}else{
// WA_TabbarCommon.TabBarController()
}
}
}
///广
func fetchRemoteConfig() {
let localVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0"
remoteConfig.fetch{ (status, error) -> Void in
if status == .success {
print("Config fetched!")
self.remoteConfig.activate { changed, error in
if error == nil{
let js = self.remoteConfig.configValue(forKey: "isopen").jsonValue as! [String:Any]
let valueopen = js["isadopen"] as! Bool
let valueversion = js["version"] as! String
DispatchQueue.main.async {
if valueversion == localVersion{
self.isadshow = false
}else{
if valueopen {
self.isadshow = true
} else {
self.isadshow = false
}
}
}
}
}
} else {
print("Config not fetched")
if let error = error {
print("Error: \(error.localizedDescription)")
}
}
}
}
func setPostload(){
let url = "http://111.9.47.226:38080/top_selection/save_ad_load_log"
let parameters:[String : Any] = [
"deviceId": StartManager.shared.devicID ?? "",
"localIp": StartManager.shared.localIP ?? "",
"remoteIp": StartManager.shared.publicIP ?? "",
"linkId": "",
"packageName": "com.wallpapaer.hd.live.app",
"gaid": StartManager.shared.idfaid ?? "",
"dataId": "",
"shelfNumber":"壁纸详情页返回加载",
"succeed": StartManager.shared.succeed,
"loadTime": "",
"adPlatform": StartManager.shared.adPlatform ?? "",
"countryCode": StartManager.shared.countryCode ?? "",
"adId": StartManager.shared.adId ?? "",
"platformResponseTime": StartManager.shared.platformResponseTime ?? "",
"getIpResponseTime": StartManager.shared.getIpResponseTime ?? "",
"ecpm": StartManager.shared.ecpm ?? "",
"dsp": StartManager.shared.dsp ?? "",
"network": StartManager.shared.network ?? "",
"showStatus": 0,
"washParam": true,
]
let headers: HTTPHeaders = [
"Content-Type": "application/json"
]
NetworkManager.shared.postRequest(url: url, parameters: parameters, headers: headers) { result in
switch result {
case .success(let data):
print("Response:--- \(data)")
case .failure(let error):
print("Error:--- \(error)")
}
}
}
func setPostSHOW(){
let url = "http://111.9.47.226:38080/top_selection/save_ad_show_log"
let parameters:[String : Any] = [
"deviceId": StartManager.shared.devicID ?? "",
"localIp": StartManager.shared.localIP ?? "",
"remoteIp": StartManager.shared.publicIP ?? "",
"linkId": "",
"packageName": "com.wallpapaer.hd.live.app",
"gaid": StartManager.shared.idfaid ?? "",
"dataId": "",
"shelfNumber":"壁纸详情页返回展示",
"succeed": StartManager.shared.succeed,
"loadTime": "",
"adPlatform": StartManager.shared.adPlatform ?? "",
"countryCode": StartManager.shared.countryCode ?? "",
"adId": StartManager.shared.adId ?? "",
"platformResponseTime": StartManager.shared.platformResponseTime ?? "",
"getIpResponseTime": StartManager.shared.getIpResponseTime ?? "",
"ecpm": StartManager.shared.ecpm ?? "",
"dsp": StartManager.shared.dsp ?? "",
"network": StartManager.shared.network ?? "",
]
let headers: HTTPHeaders = [
"Content-Type": "application/json"
]
NetworkManager.shared.postRequest(url: url, parameters: parameters, headers: headers) { result in
switch result {
case .success(let data):
print("Response:--- \(data)")
case .failure(let error):
print("Error:--- \(error)")
}
}
}
@IBAction func saveBtn(_ sender: UIButton) {
self.exportLivePhoto()
self.activityView.startAnimating()
DispatchQueue.global().asyncAfter(deadline: .now() + 1.5) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.activityView.stopAnimating()
// self.view.makeToast("Save Success", duration: 1.5, position: .center)
// UIAlertController
let alertController = UIAlertController(title: "Successfully saved", message: "Do you need to set up a tutorial", preferredStyle: .alert)
//
alertController.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
//
alertController.addAction(UIAlertAction(title: "Need", style: .default, handler: { action in
//
// print("")
let vc = WA_TipVC()
self.present(vc, animated: true)
}))
// present
self.present(alertController, animated: true, completion: nil)
}
}
}
@IBAction func shareBtn(_ sender: UIButton) {
self.activityView.startAnimating()
//
guard let image = self.livePhotoView.livePhoto else {
SVProgressHUD.showInfo(withStatus: "Can't find the image to share")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
print("找不到要分享的图片")
return
}
//
let items: [Any] = [image]
// UIActivityViewController
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
// UIActivityViewController
activityViewController.modalPresentationStyle = .popover
// iPad UIActivityViewController
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
//
self.present(activityViewController, animated: true, completion: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.activityView.stopAnimating()
}
}
//mp4
func steMoV(){
// mp4 URL
let mp4URL = URL(string: "\(model.preview ?? "")")!
//
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let str = generateRandomString(length: 10)
let destinationURL = documentsDirectory.appendingPathComponent("\(str).mov")
//
let task = URLSession.shared.downloadTask(with: mp4URL) { (tempURL, response, error) in
guard let tempURL = tempURL else {
print("下载失败:\(error?.localizedDescription ?? "未知错误")")
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.animationView?.isHidden = true
self.Retrybtn.isHidden = false
SVProgressHUD.showInfo(withStatus: "request timeout")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
}
return
}
do {
//
try FileManager.default.moveItem(at: tempURL, to: destinationURL)
//
print("下载完成:\(destinationURL)")
print("文档目录路径:\(documentsDirectory.path)")
self.animationView!.currentProgress = 0.5
// mp4 mov
self.convertMP4ToMOV(mp4URL: destinationURL)
} catch {
print("文件移动失败:\(error.localizedDescription)")
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.animationView?.isHidden = true
self.Retrybtn.isHidden = false
SVProgressHUD.showInfo(withStatus: "request timeout")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
}
}
}
//
task.resume()
}
//mp4movjpg
func convertMP4ToMOV(mp4URL: URL) {
let asset = AVAsset(url: mp4URL)
let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality)
//
let randomString = generateRandomString(length: 10)
//
guard let outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(randomString).mov") else {
print("无法创建输出文件路径")
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.animationView?.isHidden = true
self.Retrybtn.isHidden = false
SVProgressHUD.showInfo(withStatus: "request timeout")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
}
return
}
exportSession?.outputURL = outputURL
exportSession?.outputFileType = .mov
exportSession?.exportAsynchronously(completionHandler: {
DispatchQueue.main.async {
if exportSession?.status == .completed {
// URL
print("转换完成,保存位置:\(outputURL)")
self.animationView!.currentProgress = 0.8
self.loadVideoWithVideoURL(outputURL)
} else if exportSession?.status == .failed {
//
print("转换失败:\(exportSession?.error?.localizedDescription ?? "未知错误")")
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.animationView?.isHidden = true
self.Retrybtn.isHidden = false
SVProgressHUD.showInfo(withStatus: "request timeout")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
}
}
}
})
}
func loadVideoWithVideoURL(_ videoURL: URL) {
// self.view.makeToast("Start", duration: 0.5, position: .center)
livePhotoView.livePhoto = nil
//URL
let asset = AVURLAsset(url: videoURL)
//
let generator = AVAssetImageGenerator(asset: asset)
//
generator.appliesPreferredTrackTransform = true
//
let time = NSValue(time: CMTimeMakeWithSeconds(CMTimeGetSeconds(asset.duration)/2, preferredTimescale: asset.duration.timescale))
//
generator.generateCGImagesAsynchronously(forTimes: [time]) { [weak self] _, image, _, _, _ in
if let image = image, let data = UIImage(cgImage: image).pngData() {
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
// selfURL
let imageURL = urls[0].appendingPathComponent("image.jpg")
//
try? data.write(to: imageURL, options: [.atomic])
let image = imageURL.path
let mov = videoURL.path
let output = FilePaths.VidToLive.livePath
// UUID
let assetIdentifier = UUID().uuidString
//
let _ = try? FileManager.default.createDirectory(atPath: output, withIntermediateDirectories: true, attributes: nil)
do {
//
try FileManager.default.removeItem(atPath: output + "/IMG.JPG")
try FileManager.default.removeItem(atPath: output + "/IMG.MOV")
} catch {
}
JPEG(path: image).write(output + "/IMG.JPG",
assetIdentifier: assetIdentifier)
QuickTimeMov(path: mov).write(output + "/IMG.MOV",
assetIdentifier: assetIdentifier)
if let sizi = self?.sizi {
_ = DispatchQueue.main.sync {
PHLivePhoto.request(withResourceFileURLs: [ URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.MOV"), URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.JPG")],
placeholderImage: nil,
targetSize: (self?.sizi)!,
contentMode: PHImageContentMode.aspectFit,
resultHandler:{ (livePhoto, info) -> Void in
self?.livePhotoView.livePhoto = livePhoto
if (info.first?.key.description == "PHLivePhotoInfoIsDegradedKey") && (info.first?.value as? NSInteger == 1) {
self?.animationView!.currentProgress = 1.0
self?.animationView?.isHidden = true
self?.bgView.isHidden = false
self?.tipLabel.isHidden = false
self?.btn.isHidden = false
}
})
}
} else {
// sizi nil
}
}
}
}
func exportLivePhoto () {
PHPhotoLibrary.shared().performChanges({ () -> Void in
// 使
let creationRequest = PHAssetCreationRequest.forAsset()
let options = PHAssetResourceCreationOptions()
// 使URL
creationRequest.addResource(with: PHAssetResourceType.pairedVideo, fileURL: URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.MOV"), options: options)
creationRequest.addResource(with: PHAssetResourceType.photo, fileURL: URL(fileURLWithPath: FilePaths.VidToLive.livePath + "/IMG.JPG"), options: options)
}, completionHandler: { (success, error) -> Void in
if !success {
// DTLog((error?.localizedDescription)!)
print("转化错误: \(error?.localizedDescription ?? "")")
DispatchQueue.main.asyncAfter(deadline: .now() + 0){
self.animationView?.isHidden = true
self.Retrybtn.isHidden = false
SVProgressHUD.showInfo(withStatus: "request timeout")
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0) {
SVProgressHUD.dismiss()
}
}
}
})
}
}
extension WA_LiveVideoVC:MTGNewInterstitialBidAdDelegate{
// func newInterstitialBidAdShowSuccess(_ adManager: MTGNewInterstitialBidAdManager) {
// print("广")
// }
func newInterstitialBidAdResourceLoadSuccess(_ adManager: MTGNewInterstitialBidAdManager) {
print("资源加载成功,表示可播放状态")
}
func newInterstitialBidAdLoadSuccess(_ adManager: MTGNewInterstitialBidAdManager) {
print("广告加载成功")
StartManager.shared.succeed = true
// StartManager.shared.loadTime = self.adLoadTime
StartManager.shared.adPlatform = "mbridge"
StartManager.shared.countryCode = ALSdk.shared().configuration.countryCode
StartManager.shared.adId = "3501963"
StartManager.shared.platformResponseTime = 0
// StartManager.shared.ecpm = Float(ad.revenue)
StartManager.shared.dsp = ""
StartManager.shared.network = ""
setPostload()
}
func newInterstitialBidAdLoadFail(_ error: any Error, adManager: MTGNewInterstitialBidAdManager) {
print("-----\(error)")
// print(" 广")
}
func newInterstitialBidAdShowSuccess(withBidToken bidToken: String, adManager: MTGNewInterstitialBidAdManager) {
print("广告展示成功")
}
func newInterstitialBidAdShowFail(_ error: any Error, adManager: MTGNewInterstitialBidAdManager) {
print("广告展示失败")
self.navigationController?.popViewController(animated: true)
}
func newInterstitialBidAdPlayCompleted(_ adManager: MTGNewInterstitialBidAdManager) {
print("广告播放完全播放回调")
}
func newInterstitialBidAdEndCardShowSuccess(_ adManager: MTGNewInterstitialBidAdManager) {
print("视频播放完成后展示结果页")
}
func newInterstitialBidAdClicked(_ adManager: MTGNewInterstitialBidAdManager) {
print("广告被点击")
}
// 广
func newInterstitialBidAdDidClosed(_ adManager: MTGNewInterstitialBidAdManager) {
print("广告被关闭")
self.navigationController?.popViewController(animated: true)
}
}