gpt4 book ai didi

ios - AVFoundation - 视频合并但仅播放最后一个视频

转载 作者:行者123 更新时间:2023-12-02 02:11:04 44 4
gpt4 key购买 nike

我有一个[AVAsset]()数组。每当我以不同的持续时间录制不同的视频时,下面的代码会将所有持续时间合并为 1 个视频,但它只会循环播放最后一个视频。

例如。视频1时长1分钟,显示一只狗在散步,视频2时长1分钟,显示一只鸟在飞翔,视频3时长1分钟,显示一匹马奔跑。视频将合并并播放 3 分钟,但只会显示马连续运行 3 次,每次 1 分钟。

我哪里出错了?

var movieFileOutput = AVCaptureMovieFileOutput()
var arrayVideos = [AVAsset]()
var videoFileUrl: URL?

// button to record video
@objc func recordButtonTapped() {

// Stop recording
if movieFileOutput.isRecording {

movieFileOutput.stopRecording()

print("Stop Recording")

} else {

// Start recording
movieFileOutput.connection(with: AVMediaType.video)?.videoOrientation = videoOrientation()

movieFileOutput.maxRecordedDuration = maxRecordDuration()

videoFileUrl = URL(fileURLWithPath: videoFileLocation())

if let videoFileUrlFromCamera = videoFileUrl {
movieFileOutput.startRecording(to: videoFileUrlFromCamera, recordingDelegate: self)
}
}
}

func videoFileLocation() -> String {
return NSTemporaryDirectory().appending("videoFile.mov")
}

// button to save the merged video
@objc func saveButtonTapped() {

mergeVids()
}

// function to merge and save videos
func mergeVids() {

let mixComposition = AVMutableComposition()

let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: .video,
preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

compositionVideoTrack?.preferredTransform = CGAffineTransform(rotationAngle: .pi / 2)

let soundtrackTrack = mixComposition.addMutableTrack(withMediaType: .audio,
preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

var insertTime = CMTime.zero

for videoAsset in arrayVideos {

do {

try compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero,
duration: videoAsset.duration),
of: videoAsset.tracks(withMediaType: .video)[0],
at: insertTime)

try soundtrackTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero,
duration: videoAsset.duration),
of: videoAsset.tracks(withMediaType: .audio)[0],
at: insertTime)

insertTime = CMTimeAdd(insertTime, videoAsset.duration)

} catch let error as NSError {
print("\(error.localizedDescription)")
}
}

let outputFileURL = URL(fileURLWithPath: NSTemporaryDirectory() + "merge.mp4")
let path = outputFileURL.path
if FileManager.default.fileExists(atPath: path) {
try! FileManager.default.removeItem(atPath: path)
}

let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)

exporter!.outputURL = outputFileURL
exporter!.outputFileType = AVFileType.mp4
exporter!.shouldOptimizeForNetworkUse = true
exporter!.exportAsynchronously { [weak self] in

let cameraVideoURL = exporter!.outputURL!

PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: cameraVideoURL)
}) { (saved, error) in

if let error = error { return }

if !saved { return }

// url is saved

self?.videoFileUrl = nil
self?.arrayVideos.removeAll()
}
}
}

// AVCaptureFileOutputRecording Delegates
func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {

print("+++++++++++++++Started")
print("*****Started recording: \(fileURL)\n")
}

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

if error == nil {

let asset = AVAsset(url: outputFileURL)

arrayVideos.append(asset)
print(arrayVideos.count)

} else {

print("Error recording movie: \(error!.localizedDescription)")
}

func cleanUp() {

let path = outputFileURL.path

if FileManager.default.fileExists(atPath: path) {
do {
try FileManager.default.removeItem(atPath: path)
} catch {
print("Could not remove file at url: \(outputFileURL)")
}
}
}
}

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
print("++++++Frame Drop: \(connection.description)")
}

最佳答案

感谢 @alxlives 测试了合并功能,并指出由于在他的机器上一切正常,问题一定出在其他地方。

问题出在这里:

func videoFileLocation() -> String {
return NSTemporaryDirectory().appending("videoFile.mov")
}

在 recordButtonTapped 中,当它使用上述代码时,它继续使用相同的“videoFile.mov”扩展名:

videoFileUrl = URL(fileURLWithPath: videoFileLocation()) // <<< it gets called here every time a new video runs

if let videoFileUrlFromCamera = videoFileUrl {
movieFileOutput.startRecording(to: videoFileUrlFromCamera, recordingDelegate: self)
}

为了解决这个问题,我需要使每个扩展都是唯一的:

func videoFileLocation() -> String {
let uuid = UUID().uuidString
return NSTemporaryDirectory().appending("videoFile_\(uuid).mov")
}

关于ios - AVFoundation - 视频合并但仅播放最后一个视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58323683/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com