0

Does anyone know a working solution to make a screenshot of a youtube video on iOS ? A standard "UIView to UIImage" solutions like snapshotting current graphic context or a layer of the view don't work as I get only a black, empty video player with Youtube logo on it, without the actual video.

I tried to snapshot the view's presentationLayer but then I get the BAD_ACCESS error. I heard it has something to do with CSS/HTML5 inside the UIWebView (which is used to display the youtube player).

Has anyone succeeded on that ?

Bartek Uchański
  • 119
  • 1
  • 12
  • I've encountered the same issue, i.e. trying to grab a screen snap of the current video frame as a UIImage and all the solutions I've found and tried yield a black frame on device (some work on the Simulator but none on device). Two more URLs (in addition to this one) asking the same question, and no one seems to have a working solution: https://github.com/youtube/youtube-ios-player-helper/issues/60 https://stackoverflow.com/questions/32095532/screenshot-of-my-app-shows-blank-youtube-video Any working solution would be greatly appreciated. – Joe Rosen Sep 25 '17 at 23:00
  • 2
    Try this framework: https://cocoapods.org/pods/XCDYouTubeKit It's a custom library that loads youtube videos into MPMoviePlayerController. Then you can grab a certain frame with method [player thumbnailImageAtTime:] – Bartek Uchański Sep 26 '17 at 23:42
  • Will give it a try and report back, THANK YOU! – Joe Rosen Sep 27 '17 at 05:40

1 Answers1

1

Bartek Uchanski, thank you again, your response pointed me in the right direction.

For my particular application I still needed to rely on Google's YouTube iOS Player Helper API for video playback, however to extract a thumbnail (which seems to be impossible directly with the Google YouTube API) I loaded a separate "shadow" mp4 stream from YouTube, relying on both the XCDYouTubeClient library and AVAsset/AVFoundation framework to extract and save a thumbnail image. (Unfortunately [player thumbnailImageAtTime:] is deprecated hence my workaround below.)

1) Use the XCDYouTubeClient API to extract an e.g. mp4 video stream URL from a YouTube 11 character video identifier; you could also parse the YouTube video's HTML page for the same stream URL(s) but I found it (much) easier to simply use the XCDYouTubeClient API.

2) Once you've retrieved the URL to the video stream then use the AVAsset/AVFoundation framework to extract a thumbnail.

(I've shorthanded my actual app code here, but the general concept is as follows.)

NSString *videoid = @"9bZkp7q19f0"; // youtube 11 character video identifier
[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:videoid completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
  if (video) {
    // available youtube urls; e.g. itag=160 mp4 video only, 256x144
    if (video.streamURLs[[NSNumber numberWithInt:160]]) {
      // grab thumbnail from specified video stream @ specified time, e.g. @ 30 secs
      AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:[[video.streamURLs[[NSNumber numberWithInt:160]] description] stringByRemovingPercentEncoding]]];
      AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
      CGImageRef imageRef = [imageGenerator copyCGImageAtTime:CMTimeMakeWithSeconds(30.0,NSEC_PER_SEC) actualTime:NULL error:NULL];
      UIImage *ytvideo_thumbnail = [UIImage imageWithCGImage:imageRef];
      CGImageRelease(imageRef);
      // save thumbnail to camera roll
      UIImageWriteToSavedPhotosAlbum(ytvideo_thumbnail,nil,nil,nil);
    }
  }
}];
Joe Rosen
  • 171
  • 1
  • 9