xcode 在当前时间创建AVPlayer的缩略图或图像

3npbholx  于 2023-01-02  发布在  其他
关注(0)|答案(8)|浏览(134)

我已经实现了一个AVPlayer,我想采取一个图像或缩略图时,点击工具栏按钮,并在一个新的UIViewController打开与UIImageView。图像应缩放完全一样的AVPlayersegue已经工作,我只需要实现,我得到的图像在当前播放时间。
谢谢!

oiopk7p5

oiopk7p51#

    • 目标-C**
AVAsset *asset = [AVAsset assetWithURL:sourceURL];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
CMTime time = CMTimeMake(1, 1);
CGImageRef imageRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);  // CGImageRef won't be released by ARC
    • 雨燕**
var asset = AVAsset.assetWithURL(sourceURL)
var imageGenerator = AVAssetImageGenerator(asset: asset!)
var time = CMTimeMake(1, 1)
var imageRef = try! imageGenerator!.copyCGImageAtTime(time, actualTime: nil)
var thumbnail = UIImage.imageWithCGImage(imageRef)
CGImageRelease(imageRef) // CGImageRef won't be released by ARC
    • 雨燕3.0**
var sourceURL = URL(string: "Your Asset URL")
var asset = AVAsset(url: sourceURL!)
var imageGenerator = AVAssetImageGenerator(asset: asset)
var time = CMTimeMake(1, 1)
var imageRef = try! imageGenerator.copyCGImage(at: time, actualTime: nil)
var thumbnail = UIImage(cgImage:imageRef)
    • 注:**根据您的swift版本解释Swift代码。
rn0zuynd

rn0zuynd2#

试试这个

- (UIImage*)takeScreeenShot {

 AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:vidURL
 options:nil];

 AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

 imageGenerator.appliesPreferredTrackTransform = YES;

 NSError *err = NULL;

 CMTime time = CMTimeMake(1, 60); // time range in which you want
 screenshot

 CGImageRef imgRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL
 error:&err];

 return [[UIImage alloc] initWithCGImage:imgRef];

 }

希望这对你有帮助!

wqsoz72f

wqsoz72f3#

斯威夫特2.x:

let asset = AVAsset(...)
let imageGenerator = AVAssetImageGenerator(asset: asset)
let screenshotTime = CMTime(seconds: 1, preferredTimescale: 1)
if let imageRef = try? imageGenerator.copyCGImageAtTime(screenshotTime, actualTime: nil) {

    let image = UIImage(CGImage: imageRef)

    // do something with your image
}
ct3nt3jp

ct3nt3jp4#

添加以下代码,从视频生成缩略图。

AVURLAsset *assetURL = [[AVURLAsset alloc] initWithURL:partOneUrl options:nil]; 

AVAssetImageGenerator *assetGenerator = [[AVAssetImageGenerator alloc] initWithAsset:assetURL]; 

assetGenerator.appliesPreferredTrackTransform = YES;  

NSError *err = NULL; 

CMTime time = CMTimeMake(1, 2);     

CGImageRef imgRef = [assetGenerator copyCGImageAtTime:time actualTime:NULL error:&err]; 

UIImage *one = [[UIImage alloc] initWithCGImage:imgRef];
h7wcgrx3

h7wcgrx35#

这是我如何在Swift中获取场景中当前可见帧的镜头:
关键在于
1.获取类型为CMTime的播放器的当前时间
1.将该时间转换为Float64类型的秒
1.使用CMTimeMake将secondss切换回CMTime。第一个参数(即秒的位置)应强制转换为Int64
代码:

var myImage: UIImage?

guard let player = player else { return }

let currentTime: CMTime = player.currentTime() // step 1.
let currentTimeInSecs: Float64 = CMTimeGetSeconds(currentTime) // step 2.
let actionTime: CMTime = CMTimeMake(Int64(currentTimeInSecs), 1) // step 3.

let asset = AVAsset(url: fileUrl)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true // prevent image rotation

do{
    let imageRef =  try imageGenerator.copyCGImage(at: actionTime, actualTime: nil)

     myImage = UIImage(cgImage: imageRef)
}catch let err as NSError{
    print(err.localizedDescription)
}
xggvc2p6

xggvc2p66#

用于从视频生成缩略图的Swift扩展

extension AVPlayer {
    func generateThumbnail(time: CMTime) -> UIImage? {
        guard let asset = currentItem?.asset else { return nil }
        let imageGenerator = AVAssetImageGenerator(asset: asset)

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

        return nil
    }
}
dgtucam1

dgtucam17#

当你需要一次创建多个缩略图时,类AVAssetImageGenerator是最好的,因为它提供了一种异步方式。
如果您需要播放器当前帧的缩略图图像,只需渲染其视图(特定于平台)或其层(独立于平台):

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGSize frameSize = _playerLayer.frame.size;
CGContextRef thumbnailContext = CGBitmapContextCreate(nil, frameSize.width, frameSize.height, 8, 0, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
[_playerLayer renderInContext:thumbnailContext];
CGImageRef playerThumbnail = CGBitmapContextCreateImage(thumbnailContext);
CGContextRelease(thumbnailContext);

这是超快和同步工作。

yc0p9oo0

yc0p9oo08#

2022年代码:

seconds = .. the normal human-meaning desired time position in the video

guard let pl = .. your player ..
guard let ite = pl.currentItem ..

let testGen = AVAssetImageGenerator(asset: ite.asset)
testGen.maximumSize = CGSize(width: 0, height: .. height of your preview box)

testGen.requestedTimeToleranceBefore = .zero // during development
// or something like ... CMTime(value: .. your tolerance .., timescale: 600)

testGen.requestedTimeToleranceAfter = .zero // during development
// ditto

if #available(tvOS 16, *) {
    Task { [weak self] ..
        do {
            let ct = CMTime(value: CMTimeValue(seconds), timescale: 1)
            // NOTE THE "1"

            let (foundImage, foundTime) = try await testGen.image(at: ct)
            
            let foundAsSecs = CMTimeGetSeconds(foundTime)
            print("tried gen at \(seconds) found as \(foundAsSecs) \n")
            
            self. .. your preview .image = UIImage(cgImage: foundImage)
            
        } catch {
            print("gen err \(error)")
        }
    }
}

谷歌称,设定这两个容差是一个复杂的问题。
注意其中CMTime需要timescale为1的陷阱。

相关问题