问题
I am developing a video based Application in Swift3. Where I have one video url and a Range Slider according to the video duration and user can select any minimum and maximum value from slider. If suppose user has selected min value 3 Sec and Max Value 7 Sec, So for this duration I need to generate a Video Thumbnail Image. For this I am using AVAssetImageGenerator
to generate this, I tried below both code to achieve this :
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
}
But the problem is I am getting same thumbnail image using both above methods, bcos I am not setting duration here in both methods. How can I add minimum and maximum duration to generate different thumbnail image for each different duration. Please help me resolve my problem. Thank you!
Edit: I tried to set duration like :
let time: CMTime = CMTimeMakeWithSeconds(rangeSlider!.lowerValue, 1)
Then I am getting different thumbnail image but for some slider ranges I am getting nil thumbnail image also. Can anyone have some idea how to set preferredTimeScale value in CMTimeMakeWithSeconds
?
回答1:
Assume, your trimmed video URL is videoURL
. After successfully trimming a video, add this code snippet. Actually this code snippet will help you to extract images from trimmed video at each second (meaning, if the duration of your trimmed video is 10 second, this code will extract 10 images at each second and all of these images are saved in an array, named videoFrames
). Lastly, you can do whatever you want with these images. You can also add an activity indicator while this process is going on. Hope this helps.
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
}
}
来源:https://stackoverflow.com/questions/47617130/getting-same-video-thumbnail-image-every-time-from-the-url-in-swift-ios