VPCamera/tdvideo/tdvideo/PlayContoller6.swift
2024-03-05 11:44:34 +08:00

161 lines
6.2 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.

//
// 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
}
}
}
}