Duet-并排合并2个视频 [英] Duet - Merge 2 Videos Side by Side
问题描述
注意:-并排合并视频而不会降低视频质量
NOTE:- Merge Videos Side By Side WITHOUT Losing Video Quality
我认为这是一个非常重要问题,经过大量搜索&谷歌搜索,没有找到与此问题相关的任何有用材料.
I think that is a Very Very Important Question, After a lot of searches & Googling, didn't find any helpful material related to this Question.
我正在一个项目中,我需要将视频并排合并到一个文件中.
I'm working on a Project where I need to MERGE Videos Side-By-Side in a single file.
我已经使用AVFoundation完成了合并视频,但是问题是FIRST Video显示为SECOND视频的叠加层(与 SMULE App/Karaoke App或Tiktok App合并不正确) ).
I had done Merged Videos using AVFoundation But the problem is FIRST Video is showing as an Overlay to a SECOND video(not Merging properly as same as SMULE App/Karaoke App or Tiktok App).
func mergeVideosFilesWithUrl(savedVideoUrl: URL, newVideoUrl: URL, audioUrl:URL)
{
let savePathUrl : NSURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/camRecordedVideo.mp4")
do { // delete old video
try FileManager.default.removeItem(at: savePathUrl as URL)
} catch { print(error.localizedDescription) }
var mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition()
var mixComposition : AVMutableComposition = AVMutableComposition()
let aNewVideoAsset : AVAsset = AVAsset(url: newVideoUrl)
let asavedVideoAsset : AVAsset = AVAsset(url: savedVideoUrl)
let aNewVideoTrack : AVAssetTrack = aNewVideoAsset.tracks(withMediaType: AVMediaType.video)[0]
let aSavedVideoTrack : AVAssetTrack = asavedVideoAsset.tracks(withMediaType: AVMediaType.video)[0]
let mutableCompositionNewVideoTrack : AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)!
do{
try mutableCompositionNewVideoTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aNewVideoAsset.duration), of: aNewVideoTrack, at: CMTime.zero)
}catch { print("Mutable Error") }
let mutableCompositionSavedVideoTrack : AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)!
do{
try mutableCompositionSavedVideoTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: asavedVideoAsset.duration), of: aSavedVideoTrack , at: CMTime.zero)
}catch{ print("Mutable Error") }
let mainInstruction = AVMutableVideoCompositionInstruction()
mainInstruction.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: CMTimeMaximum(aNewVideoAsset.duration, asavedVideoAsset.duration) )
let newVideoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: mutableCompositionNewVideoTrack)
let newScale : CGAffineTransform = CGAffineTransform.init(scaleX: 0.7, y: 0.7)
let newMove : CGAffineTransform = CGAffineTransform.init(translationX: 230, y: 230)
newVideoLayerInstruction.setTransform(newScale.concatenating(newMove), at: CMTime.zero)
let savedVideoLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: mutableCompositionSavedVideoTrack)
let savedScale : CGAffineTransform = CGAffineTransform.init(scaleX: 1.2, y: 1.5)
let savedMove : CGAffineTransform = CGAffineTransform.init(translationX: 0, y: 0)
savedVideoLayerInstruction.setTransform(savedScale.concatenating(savedMove), at: CMTime.zero)
mainInstruction.layerInstructions = [newVideoLayerInstruction, savedVideoLayerInstruction]
mutableVideoComposition.instructions = [mainInstruction]
mutableVideoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
mutableVideoComposition.renderSize = CGSize(width: 1240 , height: self.camPreview.frame.height)
finalPath = savePathUrl.absoluteString
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
assetExport.videoComposition = mutableVideoComposition
assetExport.outputFileType = AVFileType.mov
assetExport.outputURL = savePathUrl as URL
assetExport.shouldOptimizeForNetworkUse = true
assetExport.exportAsynchronously { () -> Void in
switch assetExport.status {
case AVAssetExportSession.Status.completed:
print("success")
case AVAssetExportSession.Status.failed:
print("failed \(assetExport.error)")
case AVAssetExportSession.Status.cancelled:
print("cancelled \(assetExport.error)")
default:
print("complete")
}
}
}
这是我的输出
还有我想要的
由于我不知道制作"SIDE BY SIDE VIDEO/DUET VIDEO"的最佳方法是什么...到目前为止,我已经使用了AVFoundation.我没有使用任何第三者框架或任何POD.
As I don't know what is the best approach to make a SIDE BY SIDE VIDEO/DUET VIDEO... As for now, I have used AVFoundation. I have not used any 3rd party framework or any POD.
我想问,实现此目标的最佳方法是什么?视频应该在服务器端还是在应用程序上合并?还有我应该使用哪种方法?
I would like to ask, what is the BEST Approach to implement this? Videos should Merge on Server side or an App? Also which Approach I should use?
任何帮助都会受到高度赞赏.谢谢
推荐答案
要实现这一点,我将创建一个新的AVMutableComposition
对象,其中包含2条轨道,并在每条轨道上设置transform使其并排放置:
To achieve this, I would create a new AVMutableComposition
object containing 2 tracks, and set transform on each to place them side by side:
let composition = AVMutableComposition(urlAssetInitializationOptions: <your options>)
let videoTrackA = composition.addMutableTrack(withMediaType:.video, preferredTrackID:kCMPersistentTrackID_Invalid);
let videoTrackB = composition.addMutableTrack(withMediaType:.video, preferredTrackID:kCMPersistentTrackID_Invalid);
videoTrackA.preferredTransform = CGAffineTransform(translationX: <yourX_for_A>, y:0.0)
videoTrackB.preferredTransform = CGAffineTransform(translationX: <yourX_for_B>, y:0.0)
然后.使用以下方法保存它:
Then. save it using:
let exporter = AVAssetExportSession(asset:<yourAsset>, presetName:<yourPresetName>)
exporter.exportAsynchronously(completionHandler: <yourCompletionHandler>)
(未测试Swift代码).
(Swift code not tested).
这篇关于Duet-并排合并2个视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!