- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的目标是让用户从照片中选择视频,然后让他在上面添加标签。
这是我得到的:
let audioAsset = AVURLAsset(url: selectedVideoURL)
let videoAsset = AVURLAsset(url: selectedVideoURL)
let mixComposition = AVMutableComposition()
let compositionVideoTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
let clipVideoTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
let clipAudioTrack = audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoAsset.duration), of: clipVideoTrack, at: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioAsset.duration), of: clipAudioTrack, at: kCMTimeZero)
compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform
} catch {
print(error)
}
var videoSize = clipVideoTrack.naturalSize
if isVideoPortrait(asset: videoAsset) {
videoSize = CGSize(width: videoSize.height, height: videoSize.width)
}
let parentLayer = CALayer()
let videoLayer = CALayer()
parentLayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
videoLayer.frame = CGRect(x: 0, y: 0, width: videoSize.width, height: videoSize.height)
parentLayer.addSublayer(videoLayer)
// adding label
let helloLabelLayer = CATextLayer()
helloLabelLayer.string = "Hello"
helloLabelLayer.font = "Signika-Semibold" as CFTypeRef?
helloLabelLayer.fontSize = 30.0
helloLabelLayer.contentsScale = mainScreen.scale
helloLabelLayer.alignmentMode = kCAAlignmentNatural
helloLabelLayer.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 50.0)
parentLayer.addSublayer(helloLabelLayer)
// creating composition
let videoComp = AVMutableVideoComposition()
videoComp.renderSize = videoSize
videoComp.frameDuration = CMTimeMake(1, 30)
videoComp.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, mixComposition.duration)
let layerInstruction = videoCompositionInstructionForTrack(track: compositionVideoTrack, asset: videoAsset)
instruction.layerInstructions = [layerInstruction]
videoComp.instructions = [instruction]
if let assetExport = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPreset640x480) {
let filename = NSTemporaryDirectory().appending("video.mov")
if FileManager.default.fileExists(atPath: filename) {
do {
try FileManager.default.removeItem(atPath: filename)
} catch {
print(error)
}
}
let url = URL(fileURLWithPath: filename)
assetExport.outputURL = url
assetExport.outputFileType = AVFileTypeMPEG4
assetExport.videoComposition = videoComp
print(NSDate().timeIntervalSince1970)
assetExport.exportAsynchronously {
print(NSDate().timeIntervalSince1970)
let library = ALAssetsLibrary()
library.writeVideoAtPath(toSavedPhotosAlbum: url, completionBlock: {
(url, error) in
switch assetExport.status {
case AVAssetExportSessionStatus.failed:
p("failed \(assetExport.error)")
case AVAssetExportSessionStatus.cancelled:
p("cancelled \(assetExport.error)")
default:
p("complete")
p(NSDate().timeIntervalSince1970)
if FileManager.default.fileExists(atPath: filename) {
do {
try FileManager.default.removeItem(atPath: filename)
} catch {
p(error)
}
}
print("Exported")
}
})
}
isVideoPortrait
函数的实现:
func isVideoPortrait(asset: AVAsset) -> Bool {
var isPortrait = false
let tracks = asset.tracks(withMediaType: AVMediaTypeVideo)
if tracks.count > 0 {
let videoTrack = tracks[0]
let t = videoTrack.preferredTransform
if t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0 {
isPortrait = true
}
if t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0 {
isPortrait = true
}
if t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0 {
isPortrait = false
}
if t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0 {
isPortrait = false
}
}
return isPortrait
}
视频合成层指令
的最后一个函数:
func videoCompositionInstructionForTrack(track: AVCompositionTrack, asset: AVAsset) -> AVMutableVideoCompositionLayerInstruction {
let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
let assetTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
let transform = assetTrack.preferredTransform
instruction.setTransform(transform, at: kCMTimeZero)
return instruction
}
代码运行良好,输出视频有标签,但如果我选择 1 分钟视频,导出需要 28 秒。
我搜索过它并尝试删除 layerInsctuction
转换,但没有效果。
尝试添加:assetExport.shouldOptimizeForNetworkUse = false
也没有影响。
此外,尝试为 AVAssetExportSession
设置 AVAssetExportPresetPassthrough
,在这种情况下,视频导出时间为 1 秒,但标签已消失。
任何帮助将不胜感激,因为我陷入困境。感谢您的宝贵时间。
最佳答案
我能想到的唯一方法是通过比特率和分辨率降低质量。
这是通过应用于 AssetExporter 的 videoSettings 的字典完成的,为此我必须使用一个名为 SDAVAssetExportSession
然后通过更改 videoSettings 我可以播放质量以获得最佳质量/速度。
let compression = [AVVideoAverageBitRateKey : 2097152(DESIRED_BITRATE),AVVideoProfileLevelKey : AVVideoProfileLevelH264BaselineAutoLevel]
let videoSettings = [AVVideoCodecKey : AVVideoCodecH264, AVVideoWidthKey : maxWidth, AVVideoHeightKey : maxHeight, AVVideoCompressionPropertiesKey:compression]
这是我加快速度的唯一方法。
关于ios - AVAssetExportSession 导出需要很多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40878004/
我有一个应用程序,允许附加多个视频资源并向合成添加一个或多个音轨。一切似乎都有效,我可以使用 AVPlayer 播放生成的作品(尽管音频级别似乎很低)。将乐曲导出到文件后,音轨丢失。 我的代码主要基于
我有一个应用程序,可以将 AVMutableComposition 导出到 .mov 文件中,我希望用户可以使用进度条与发送短信或上传文件时的进度条相同。 当我知道任务的持续时间(例如播放音频文件)时
当应用程序在后台运行时,我尝试管理 AVAssetExportSession 工作。我有 iOS 6 设备并在那里进行测试。所以我正在制作音频混合并尝试导出音频。当应用程序在前台时,我一切正常,但如果
我正在尝试使用以下代码将2个预先存在的mpeg4视频加入到ipad2上。 -(void)mergeTestVideos { //setup asset NSString *firsta
我正在创建一个视频文件,并在其上添加动画图像。我跟踪导出进度和状态,但是在导出进度达到1.0后,不会调用回调,并且导出状态仍等于'AVAssetExportSessionStatusExporting
我想合并视频和音频文件。我的程序在调试/单步模式下按我想要的方式工作,但在运行时不工作。我想这可能是“exportAsynchronously”函数的问题,我在加载之前访问了一些值。这是我的代码。 合
AVAssetExportSession 从来没有告诉我导出何时完成,但它确实很快并且文件出现在应该出现的位置......我正在使用 exportAsynchronouslyWithCompletio
我正在尝试在应用程序中裁剪和合并多个视频。我在步骤的最后部分遇到问题,我需要将视频保存到相机卷轴并且 UIVideoAtPathIsCompatibleWithSavedPhotosAlbum 返回
我想在自定义 View 中录制视频,所以我按照以下代码使用 AVFoundation。 if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum
我正在使用 AVAssetExportSession 将多个视频合并在一起,但视频是立体声的,生成的视频是双单声道的。是否可以使用 AVAssetExportSession 合并视频并保持立体声 ch
我有一个应用程序可以将视频文件组合在一起制作一个长视频。视频之间可能会有延迟(例如,V1 从 t=0s 开始并运行 5 秒,V1 从 t=10s 开始)。在这种情况下,我希望视频卡住 V1 的最后一帧
我正在使用 AVAssetExportSession 以 640x480 的分辨率导出一些东西,这些文件有点怪异——可以预见的是怪异,但仍然怪异,因为我们需要通过 3G 网络从手机上传它们。除了降低分
我的目标是让用户从照片中选择视频,然后让他在上面添加标签。 这是我得到的: let audioAsset = AVURLAsset(url: selectedVideoURL) let videoAs
我有一个错误和一个问题。我想将修改后的视频导出到相机胶卷,但导出的视频与相机胶卷不兼容。 我也想删除最初录制的视频,以便我可以录制不止一次,但它会产生错误并且没有意义。如果我取消注释代码,则会出现错误
我正在尝试在视频的 AVMutableComposition 上应用 AVMutableVideoCompositionLayerInstruction。问题是当使用 AVAssetExportSes
我正在尝试将 2 个音频文件和 1 个视频文件合并为 1 个 .mov 文件。我用下一个代码实现它: -(void)combineData{ AVMutableComposition *mixComp
当应用程序在后台时,我无法让 AVAssetExportSession 工作。 我的应用程序启用了后台模式“Background Fetch”。 当这个 UIApplicationDelegate 方
我正在尝试对共享扩展中选择的视频使用 AVAssetExportSession 并获取 Error Domain=NSURLErrorDomain Code=-3000 "Cannot create
AVAssetExportSession 将预设作为其初始化参数之一: AVAssetExportSession(asset: AVAsset, presetName: String) 其中预设是 A
我正在使用 AVAssetExportSession 修剪音频文件,但无法在保存的文件中实现淡入淡出效果。这是我正在使用的代码。 [[NSFileManager defaultManag
我是一名优秀的程序员,十分优秀!