Получение одного и того же изображения миниатюры видео каждый раз с URL-адреса в Swift iOS

Я разрабатываю приложение на основе видео в Swift3. Где у меня есть один URL-адрес видео и ползунок диапазона в соответствии с продолжительностью видео, и пользователь может выбрать любое минимальное и максимальное значение из ползунка. Если предположим, что пользователь выбрал минимальное значение 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
    }

Но проблема в том, что я получаю одно и то же миниатюрное изображение, используя оба вышеуказанных метода, потому что я не устанавливаю здесь продолжительность в обоих методах. Как я могу добавить минимальную и максимальную продолжительность для создания разных эскизов для каждой разной продолжительности. Пожалуйста, помогите мне решить мою проблему. Спасибо!

Изменить: я попытался установить продолжительность, например:

let time: CMTime = CMTimeMakeWithSeconds(rangeSlider!.lowerValue, 1)

Затем я получаю другое миниатюрное изображение, но для некоторых диапазонов ползунков я также получаю нулевое миниатюрное изображение. Может у кого-нибудь есть идея, как установить значение selectedTimeScale в CMTimeMakeWithSeconds?


person Anand Gautam    schedule 03.12.2017    source источник


Ответы (2)


Попробуйте этот код

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
    }
}
person Mayur Rathod    schedule 10.12.2019

Предположим, URL вашего обрезанного видео — 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
        }
    }
person pigeon_39    schedule 03.12.2017
comment
Спасибо за ваш ответ, здесь у меня нет URL-адреса обрезки видео. У меня есть только один основной URL-адрес видео и ползунок диапазона, где пользователь будет выбирать минимальное и максимальное значение из ползунка. Используя значения этого диапазона, мне нужно создать изображение миниатюры. Любые предложения... Вы понимаете? - person Anand Gautam; 03.12.2017
comment
хорошо... вам нужно преобразовать минимальное и максимальное значение из ползунка в CMTimeMakeWithSeconds и передать это значение в вышеуказанную функцию. fromTime: здесь параметр Float64. - person pigeon_39; 03.12.2017
comment
Можете ли вы показать мне в коде, я изменил значения CMTimeMake, но каждый раз один и тот же эскиз. - person Anand Gautam; 03.12.2017
comment
пусть lowerVal = Float64(rangeSlider.lowerValue) и передайте это значение в вышеуказанную функцию. Вы получите уменьшенное изображение с меньшим значением. То же самое будет работать и для rangeSlider.upperValue. Я предполагаю, что вы используете здесь собственный слайдер, поэтому здесь сложно ответить на ваш вопрос, не видя вашего полного свойства пользовательского слайдера. - person pigeon_39; 03.12.2017
comment
У меня есть rangeSlider.lowerValue и rangeSlider.upperValue. Как я могу добавить эти два значения в CMTimeMakeWithSeconds? Я понятия не имею об этом. - person Anand Gautam; 03.12.2017
comment
попробуйте это, пусть lowerVal = Float64 (rangeSlider.lowerValue) и пусть upperVal = Float64 (rangeSlider.upperValue) и передайте это значение в вышеуказанную функцию. - person pigeon_39; 03.12.2017
comment
Давайте продолжим обсуждение в чате. - person pigeon_39; 03.12.2017
comment
Давайте продолжим обсуждение в чате. - person pigeon_39; 04.12.2017