【问题标题】:Can not generate thumbnail from url video in ios 13无法从 ios 13 中的 url 视频生成缩略图
【发布时间】:2019-10-06 20:01:41
【问题描述】:

我正在使用以下代码从视频 URL 生成帧。这段代码以前工作得很好。现在它不工作。它抛出无法解码的错误,文件可能已损坏。有人可以帮忙吗?

func previewImageFromVideo(url: NSURL) -> UIImage? {
        let url = url as URL
        let request = URLRequest(url: url)
        let cache = URLCache.shared

        if
            let cachedResponse = cache.cachedResponse(for: request),
            let image = UIImage(data: cachedResponse.data)
        {
            return image
        }

        let asset = AVAsset(url: url)
        let imageGenerator = AVAssetImageGenerator(asset: asset)
        imageGenerator.appliesPreferredTrackTransform = true
        imageGenerator.maximumSize = CGSize(width: 250, height: 120)

        var time = asset.duration
        time.value = min(time.value, 2)

        var image: UIImage?

        do {
            let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
            image = UIImage(cgImage: cgImage)
        } catch { }

        if
            let image = image,
            let data = UIImagePNGRepresentation(image),
            let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)
        {
            let cachedResponse = CachedURLResponse(response: response, data: data)

            cache.storeCachedResponse(cachedResponse, for: request)
        }

        return image
    }

此代码在从 URL 视频中捕获帧时引发错误。它说文件可能已损坏。

【问题讨论】:

  • 您使用的视频网址出现错误,请分享网址。

标签: swift swift4


【解决方案1】:

我在 Playground 上尝试了您的代码,它运行良好。如错误消息所述,文件可能已损坏。

import UIKit
import AVKit
import PlaygroundSupport

let container = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
container.addSubview(imageView)

PlaygroundPage.current.liveView = container
PlaygroundPage.current.needsIndefiniteExecution = true

func previewImageFromVideo(url: NSURL) -> UIImage? {
    let url = url as URL
    let request = URLRequest(url: url)
    let cache = URLCache.shared

    if
        let cachedResponse = cache.cachedResponse(for: request),
        let image = UIImage(data: cachedResponse.data)
    {
        return image
    }

    let asset = AVAsset(url: url)
    let imageGenerator = AVAssetImageGenerator(asset: asset)
    imageGenerator.appliesPreferredTrackTransform = true
    imageGenerator.maximumSize = CGSize(width: 250, height: 120)

    var time = asset.duration
    time.value = min(time.value, 2)

    var image: UIImage?

    do {
        let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
        image = UIImage(cgImage: cgImage)
    } catch { }

    if
        let image = image,
        let data = image.pngData(),
        let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)
    {
        let cachedResponse = CachedURLResponse(response: response, data: data)

        cache.storeCachedResponse(cachedResponse, for: request)
    }

    return image
}

imageView.image = previewImageFromVideo(url: NSURL(string: "https://www.w3schools.com/html/mov_bbb.mp4")!)

【讨论】:

    【解决方案2】:

    我对 Suh 的回答做了一些更改,并在后台线程中使用了它,这样在生成缩略图时我们的 UI 就不会被阻塞。

     func createVideoThumbnail( url: String?,  completion: @escaping ((_ image: UIImage?)->Void)) {
        
        guard let url = URL(string: url ?? "") else { return }
        DispatchQueue.global().async {
            
            let url = url as URL
            let request = URLRequest(url: url)
            let cache = URLCache.shared
            
            if
                let cachedResponse = cache.cachedResponse(for: request),
                let image = UIImage(data: cachedResponse.data)
            {
                DispatchQueue.main.async {
                    completion(image)
                }
            }
            
            let asset = AVAsset(url: url)
            let imageGenerator = AVAssetImageGenerator(asset: asset)
            imageGenerator.appliesPreferredTrackTransform = true
            
            var time = asset.duration
            time.value = min(time.value, 2)
            
            var image: UIImage?
            
            do {
                let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
                image = UIImage(cgImage: cgImage)
            } catch { DispatchQueue.main.async {
                completion(nil)
            } }
            
            if
                let image = image,
                let data = image.pngData(),
                let response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)
            {
                let cachedResponse = CachedURLResponse(response: response, data: data)
                
                cache.storeCachedResponse(cachedResponse, for: request)
            }
            
            DispatchQueue.main.async {
                completion(image)
            }
            
        }
        
    }
    

    用法:

          createVideoThumbnail(url: data.url ?? "") { [weak self] (img) in
                guard let strongSelf = self else { return }
                if let image = img {
                    strongSelf.mediaImg.image = image
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2019-05-06
      • 2017-03-01
      • 2016-04-06
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 2013-10-22
      • 1970-01-01
      • 2012-09-01
      相关资源
      最近更新 更多