Ik probeer een screenshot te maken van een AVPlayer
in een grotere weergave. Ik wil alleen een testraamwerk bouwen, dus privé APIs
of welke methode dan ook is goed, omdat het raamwerk niet wordt opgenomen bij het vrijgeven in de AppStore.
Ik heb het geprobeerd met
UIGetScreenImage()
: werkt goed op simulator maar niet op apparaatsnapshotviewafterscreenupdates
: het toont de weergave, maar ik kan daar geenUIImage
van maken.drawViewInHierarchy
enrenderInContext
werken niet metAVPlayer
- Ik wil
AVAssetGenerator
niet gebruiken om afbeeldingen uit video te halen, het is moeilijk om een goede coördinaat te krijgen of de videospeler als subweergave van andere weergaven
Antwoord 1, autoriteit 100%
Ik weet dat je de AVAssetImageGenerator niet wilt gebruiken, maar ik heb hier ook uitgebreid onderzoek naar gedaan en ik geloof dat de enige oplossing momenteel het gebruik van de AVAssetImageGenerator is. Het is niet zo moeilijk als je zegt om de juiste coördinaat te krijgen, omdat je de huidige tijd van je speler moet kunnen krijgen. In mijn App werkt de volgende code perfect:
-(UIImage *)getAVPlayerScreenshot
{
AVURLAsset *asset = (AVURLAsset *)self.playerItem.asset;
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
CGImageRef thumb = [imageGenerator copyCGImageAtTime:self.playerItem.currentTime
actualTime:NULL
error:NULL];
UIImage *videoImage = [UIImage imageWithCGImage:thumb];
CGImageRelease(thumb);
return videoImage;
}
Antwoord 2
AVPlayer die video’s rendert met GPU, dus u kunt deze niet vastleggen met de belangrijkste grafische methoden.
Het is echter mogelijk om afbeeldingen vast te leggen met AVAssetImageGenerator
, u moet een CMTime opgeven.
Bijwerken:
Vergeet een screenshot van het hele scherm te maken. AVPlayerItemVideoOutput
is mijn uiteindelijke keuze, het ondersteunt video-stoom.
Hier is mijn volledige implementatie: https:// /ZFPlayer/commit/a32c7244f630e69643336b65351463e00e712c7f#diff-2d23591c151edd3536066df7c18e59deR448
Antwoord 3
Hier is de code voor het maken van een screenshot van uw volledige scherm, inclusief de AVPlayer. Je hoeft alleen maar een UIImageView toe te voegen aan je videospeler, die verborgen blijft totdat we de screenshot maken en daarna weer verbergen.
func takeScreenshot() -> UIImage? {
//1 Hide all UI you do not want on the screenshot
self.hideButtonsForScreenshot()
//2 Create an screenshot from your AVPlayer
if let url = (self.overlayPlayer?.currentItem?.asset as? AVURLAsset)?.url {
let asset = AVAsset(url: url)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.requestedTimeToleranceAfter = CMTime.zero
imageGenerator.requestedTimeToleranceBefore = CMTime.zero
if let thumb: CGImage = try? imageGenerator.copyCGImage(at: self.overlayPlayer!.currentTime(), actualTime: nil) {
let videoImage = UIImage(cgImage: thumb)
//Note: create an image view on top of you videoPlayer in the exact dimensions, and display it before taking the screenshot
// mine is created in the storyboard
// 3 Put the image from the screenshot in your screenshotPhotoView and unhide it
self.screenshotPhotoView.image = videoImage
self.screenshotPhotoView.isHidden = false
}
}
//4 Take the screenshot
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
self.view.drawHierarchy(in: bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//5 show all UI again that you didn't want on your screenshot
self.showButtonsForScreenshot()
//6 Now hide the screenshotPhotoView again
self.screenshotPhotoView.isHidden = true
self.screenshotPhotoView.image = nil
return image
}
Antwoord 4
Als u een screenshot van het huidige scherm wilt maken, roept u gewoon de volgende methode aan bij een actiegebeurtenis die u een Image-object geeft.
-(UIImage *) screenshot
{
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//now we will position the image, X/Y away from top left corner to get the portion we want
UIGraphicsBeginImageContext(sourceImage.size);
[sourceImage drawAtPoint:CGPointMake(0, 0)];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//To write image on divice.
//UIImageWriteToSavedPhotosAlbum(croppedImage,nil, nil, nil);
return croppedImage;
}
Ik hoop dat dit je zal helpen.
Antwoord 5
CGRect grabRect = CGRectMake(0,0,320,568);// size you want to take screenshot of.
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(grabRect.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(grabRect.size);
}
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();