ios - Crea una miniatura desde una URL de video en el SDK de iPhone
objective-c thumbnails (8)
Intento adquirir una miniatura de una URL de video. El video es una secuencia (HLS) con el formato m3u8. Ya he intentado requestThumbnailImagesAtTimes desde el MPMoviePlayerController, pero eso no funcionó. ¿Alguien tiene una solución para ese problema? Si es así, ¿cómo lo hiciste?
Adquiera una miniatura de una URL de video.
NSString *strVideoURL = @"http://www.xyzvideourl.com/samplevideourl";
NSURL *videoURL = [NSURL URLWithString:strVideoURL] ;
MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:videoURL]autorelease];
UIImage *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
player = nil;
Reemplace su cadena de URL de video con strVideoURL
. Obtendrá una miniatura como resultado del video
. ¡Y la miniatura es datos de tipo UIImage
!
Código de Swift 2 con AVAssetImageGenerator:
func thumbnailImageForVideo(url:NSURL) -> UIImage?
{
let asset = AVAsset(URL: url)
let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true
var time = asset.duration
//If possible - take not the first frame (it could be completely black or white on camara''s videos)
time.value = min(time.value, 2)
do {
let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
return UIImage(CGImage: imageRef)
}
catch let error as NSError
{
print("Image generation failed with error /(error)")
return nil
}
}
Para Swift 3.0:
func generateThumbnailForVideoAtURL(filePathLocal: NSString) -> UIImage? {
let vidURL = NSURL(fileURLWithPath:filePathLocal as String)
let asset = AVURLAsset(url: vidURL as URL)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
let timestamp = CMTime(seconds: 1, preferredTimescale: 60)
do {
let imageRef = try generator.copyCGImage(at: timestamp, actualTime: nil)
let frameImg : UIImage = UIImage(cgImage: imageRef)
return frameImg
} catch let error as NSError {
print("Image generation failed with error ::/(error)")
return nil
}
}
Tal vez esto sea útil para alguien más que enfrenta el mismo problema. Necesitaba una solución fácil para crear una miniatura para imágenes, archivos PDF y videos. Para resolver ese problema, he creado la siguiente Biblioteca (en Swift).
https://github.com/prine/ROThumbnailGenerator
El uso es muy sencillo: var thumbnailImage = ROThumbnail.getThumbnail (url)
Tiene internamente tres implementaciones diferentes y, dependiendo de la extensión del archivo, crea la miniatura. Puede agregar fácilmente su propia implementación si necesita un creador de miniaturas para otra extensión de archivo.
Versión de Swift 3:
func createThumbnailOfVideoFromFileURL(videoURL: String) -> UIImage? {
let asset = AVAsset(url: URL(string: videoURL)!)
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
let time = CMTimeMakeWithSeconds(Float64(1), 100)
do {
let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
let thumbnail = UIImage(cgImage: img)
return thumbnail
} catch {
// Set a default image if Image is not acquired
return UIImage(named: "ico_placeholder")
}
}
puedes obtener la miniatura de tu URL de video con el uso del código siguiente
MPMoviePlayerController *player = [[[MPMoviePlayerController alloc] initWithContentURL:videoURL]autorelease];
UIImage *thumbnail = [player thumbnailImageAtTime:0.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
Si no quiere usar MPMoviePlayerController
, puede hacer esto:
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
Aquí hay un ejemplo en Swift:
func thumbnail(sourceURL sourceURL:NSURL) -> UIImage {
let asset = AVAsset(URL: sourceURL)
let imageGenerator = AVAssetImageGenerator(asset: asset)
let time = CMTime(seconds: 1, preferredTimescale: 1)
do {
let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil)
return UIImage(CGImage: imageRef)
} catch {
print(error)
return UIImage(named: "some generic thumbnail")!
}
}
Prefiero usar AVAssetImageGenerator
sobre MPMoviePlayerController
porque es seguro para subprocesos y puede tener más de una instancia al mismo tiempo.
-(UIImage *)loadThumbNail:(NSURL *)urlVideo
{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:urlVideo options:nil];
AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generate.appliesPreferredTrackTransform=TRUE;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 60);
CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err];
NSLog(@"err==%@, imageRef==%@", err, imgRef);
return [[UIImage alloc] initWithCGImage:imgRef];
}
Agregue el marco AVFoundation
en su proyecto y no olvide importar <AVFoundation/AVFoundation.h>
y debe pasar la ruta de su video guardada en el directorio del documento como un parámetro y recibir la imagen como UIImage
.