//
//  PlayContoller6.swift
//  tdvideo
//
//  Created by mac on 2024/2/4.
//

import UIKit
import AVFoundation
import CoreImage
import Foundation
import Observation
import VideoToolbox


class PlayContoller6: UIViewController {
    private var player: AVPlayer!
    private var playerLayer: AVPlayerLayer!
    private var exportButton: UIButton!
    

    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.brown
        setupPlayer()
        setupExportButton()
    }
    
    private func setupPlayer() {
        
        let path = Bundle.main.path(forResource: "IMG_0071", ofType: "MOV")
        let videoURL = URL.init(filePath: path!)
        let playerItem = AVPlayerItem(url: videoURL)
        player = AVPlayer(playerItem: playerItem)
        playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height - 100)
        view.layer.addSublayer(playerLayer)
        player.play()
    }
    
    private func setupExportButton() {
        exportButton = UIButton(type: .system)
        exportButton.setTitleColor(UIColor.white, for: UIControl.State.normal)
        exportButton.setTitle("导出", for: .normal)
        exportButton.frame = CGRect(x: 0, y: view.bounds.height - 260, width: view.bounds.width, height: 100)
        exportButton.addTarget(self, action: #selector(exportButtonTapped), for: .touchUpInside)
        view.addSubview(exportButton)
    }
    
    @objc private func exportButtonTapped() {
        let path = Bundle.main.path(forResource: "IMG_0071", ofType: "MOV")
        let videoURL = URL.init(filePath: path!)
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let outputURL = documentsDirectory.appendingPathComponent("output_path.mp4")
        
        do {
            try FileManager.default.removeItem(atPath: outputURL.path)
            print("视频文件删除成功")
        } catch {
            print("删除视频文件出错：\(error)")
        }
        
        let width = 1280
        let height = 720
        let dataRate = 5000000
        let horizontalDisparity: Float = 0.0
        let horizontalFieldOfView: Float = 90.0
        
        exportVideo(url: videoURL, outputURL: outputURL, width: width, height: height, dataRate: dataRate, horizontalDisparity: horizontalDisparity, horizontalFieldOfView: horizontalFieldOfView) { exportedAsset in
            // 处理导出的新AVAsset对象
            // 在这里可以进行进一步的操作，比如播放导出的视频
            DispatchQueue.main.async {
                let exportedPlayerItem = AVPlayerItem(asset: exportedAsset!)
                self.player.replaceCurrentItem(with: exportedPlayerItem)
                self.player.play()
            }
        }
    }
    
    private func exportVideo(url: URL, outputURL: URL, width: Int, height: Int, dataRate: Int, horizontalDisparity: Float, horizontalFieldOfView: Float, completion: @escaping (AVAsset?) -> Void) {
        let asset = AVAsset(url: url)
        
        guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
            print("Failed to create export session")
            completion(nil)
            return
        }
        
        let composition = AVMutableComposition()
        let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
        
        guard let assetTrack = asset.tracks(withMediaType: .video).first else {
            print("Failed to get video track from asset")
            completion(nil)
            return
        }
        
        do {
            try videoTrack?.insertTimeRange(CMTimeRange(start: .zero, duration: asset.duration), of: assetTrack, at: .zero)
        } catch {
            print("Failed to insert video track into composition")
            completion(nil)
            return
        }
        
        var videoSettings = AVOutputSettingsAssistant(preset: .mvhevc1440x1440)?.videoSettings
        videoSettings?[AVVideoWidthKey] = width
        videoSettings?[AVVideoHeightKey] = height
        var compressionProperties = videoSettings?[AVVideoCompressionPropertiesKey] as! [String: Any]
        compressionProperties[AVVideoAverageBitRateKey] = dataRate
        compressionProperties[kVTCompressionPropertyKey_HorizontalDisparityAdjustment as String] = horizontalDisparity
        compressionProperties[kCMFormatDescriptionExtension_HorizontalFieldOfView as String] = horizontalFieldOfView
        compressionProperties[kCMFormatDescriptionExtension_HorizontalFieldOfView as String] = 180.0

        videoSettings?[AVVideoCompressionPropertiesKey] = compressionProperties
        
        let writerInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
        writerInput.expectsMediaDataInRealTime = false
        
        guard let writer = try? AVAssetWriter(outputURL: outputURL, fileType: AVFileType.mp4) else {
            print("Failed to create AVAssetWriter")
            completion(nil)
            return
        }
        
        writer.add(writerInput)
        
        guard let assetExportSession = exportSession as? AVAssetExportSession else {
            print("Failed to cast export session to AVAssetExportSession")
            completion(nil)
            return
        }
        
        assetExportSession.videoComposition = AVMutableVideoComposition(propertiesOf: composition)
        assetExportSession.outputFileType = AVFileType.mp4
        assetExportSession.outputURL = outputURL
        
        assetExportSession.exportAsynchronously {
            switch assetExportSession.status {
            case .completed:
                let exportedAsset = AVAsset(url: outputURL)
                completion(exportedAsset)
            case .failed:
                if let error = assetExportSession.error {
                    print("Export failed with error: \(error.localizedDescription)")
                } else {
                    print("Export failed")
                }
                completion(nil)
            case .cancelled:
                print("Export cancelled")
                completion(nil)
            default:
                break
            }
        }
    }

}
