我正在Swift3中开发基于视频的应用程序。我根据视频持续时间有一个视频网址和一个范围滑块,用户可以从滑块中选择任何最小值和最大值。如果假设用户选择了最小值3秒和最大值7秒,那么在此期间我需要生成视频缩略图图像。为此,我使用AVAssetImageGenerator
生成此代码,我在下面的两个代码中尝试实现此目的:
func createThumbnailOfVideoFromFileURL(_ strVideoURL: URL) -> UIImage?{
let asset = AVAsset(url: strVideoURL)
let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
let time = CMTimeMake(1, 30)
let img = try? assetImgGenerate.copyCGImage(at: time, actualTime: nil)
guard let cgImage = img else { return nil }
let frameImg = UIImage(cgImage: cgImage)
return frameImg
}
func generateThumbnailForUrl(vidUrl:URL) -> UIImage {
let asset = AVURLAsset(url: vidUrl, options: nil)
let imgGenerator = AVAssetImageGenerator(asset: asset)
var thmbnlImg = UIImage()
do{
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(0, 1), actualTime: nil)
thmbnlImg = UIImage(cgImage: cgImage)
thmbnlImg = thmbnlImg.imageRotatedByDegrees(degrees: 90.0, flip: false)
}
catch{
print(error)
}
// !! check the error before proceeding
return thmbnlImg
}
但问题是我使用上述两种方法得到相同的缩略图,bcos我没有在这两种方法中设置持续时间。如何为每个不同的持续时间添加最小和最大持续时间以生成不同的缩略图图像。请帮我解决我的问题。谢谢!
编辑:我尝试将持续时间设置为:
let time: CMTime = CMTimeMakeWithSeconds(rangeSlider!.lowerValue, 1)
然后我得到不同的缩略图,但对于一些滑块范围我也得到零缩略图。任何人都可以知道如何在CMTimeMakeWithSeconds
中设置preferredTimeScale值吗?
答案 0 :(得分:0)
尝试此代码
static func generateThumbnail(videoUrl: String) -> UIImage? {
do {
let url = URL(string: videoUrl)
let asset = AVURLAsset(url: url!)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true
let cgImage = try imageGenerator.copyCGImage(at: CMTime(seconds: 2.0, preferredTimescale: 60),
actualTime: nil)
return UIImage(cgImage: cgImage)
} catch {
print(error.localizedDescription)
return nil
}
}
答案 1 :(得分:-1)
假设您的剪裁视频网址为videoURL
。成功修剪视频后,添加此代码段。实际上,这段代码片段将帮助您每秒从裁剪后的视频中提取图像(意思是,如果裁剪视频的持续时间为10秒,此代码将每秒提取10张图像,所有这些图像都保存在一个数组中,名为videoFrames
)。最后,您可以使用这些图像执行任何操作。您还可以在此过程进行时添加活动指示器。希望这会有所帮助。
var videoFrames = [UIImage]()
let asset : AVAsset = AVAsset(url: videoURL as URL)
let videoDuration = CMTimeGetSeconds(asset.duration)
let integerValueOFVideoDuration = Int(videoDuration)
//start activity indicator here
for index in 0..<integerValueOFVideoDuration + 1 {
self.generateFrames(url: videoURL, fromTime: Float64(index))
}
func generateFrames(url: NSURL, fromTime: Float64) {
if videoFrames.count == integerValueOFVideoDuration {
//end activity indicator here
return
}
let asset: AVAsset = AVAsset(url: url as URL)
let assetImgGenerate: AVAssetImageGenerator = AVAssetImageGenerator(asset: asset)
assetImgGenerate.maximumSize = CGSize(width: 300, height: 300)
assetImgGenerate.appliesPreferredTrackTransform = true
let time: CMTime = CMTimeMakeWithSeconds(fromTime, 600)
var img: CGImage?
do {
img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
} catch {
}
if img != nil {
let frameImg: UIImage = UIImage(cgImage: img!)
videoFrames.append(frameImg)
} else {
//return nil
}
}