Is it possible to only download a single frame from a youtube video?

Let me explain what I had set up. I've been using pytube (Python module) to download videos from YouTube. I would then extract a few random frames from the video and save them as jpegs. I don't need the audio, nor the video.

Now, I've been downloading tens of thousands of videos and then deleting them just to grab a couple of random frames per video. This seemed wasteful and cost a fair bit too. Is there a way to just download the frames themselves without having to download the video?

I would guess something like youtube-dl combined with ffmpeg would do the trick, but I can't find an example online to do that. There is a solution to download a random sample of video which would reduce network bandwidth consumption a good deal, but I want something more efficient and less time consuming. Any help would be appreciated.

WARNING: Could not send HEAD request to https://www.youtube.com/watch\?v\=oHg5SJYRHA0: HTTP Error 404: Not Found ERROR: Unable to download webpage: HTTP Error 404: Not Found (caused by HTTPError()); please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output. ffmpeg version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 7 (Ubuntu 7.3.0-16ubuntu3) configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared WARNING: library configuration mismatch avcodec configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared --enable-version3 --disable-doc --disable-programs --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libtesseract --enable-libvo_amrwbenc libavutil 55. 78.100 / 55. 78.100 libavcodec 57.107.100 / 57.107.100 libavformat 57. 83.100 / 57. 83.100 libavdevice 57. 10.100 / 57. 10.100 libavfilter 6.107.100 / 6.107.100 libavresample 3. 7. 0 / 3. 7. 0 libswscale 4. 8.100 / 4. 8.100 libswresample 2. 9.100 / 2. 9.100 libpostproc 54. 7.100 / 54. 7.100 -vframes: No such file or directory

Using a combination of this answer and this answer the following should be able to do what you want:

ffmpeg -ss "$screenshot_time" -i $(youtube-dl -f 22 --get-url "$youtube_url") -vframes 1 -q:v 2 "$output_file"
  • ffmpeg's -ss option is used here as an input option which is the fastest method available. It can be used as an output option, which will take a lot more time, but avoids the accidental artifact creation that the input version occasionally generates.

-ss position (input/output)

When used as an input option (before -i), seeks in this input file to position. Note the in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it will be preserved.

When used as an output option (before an output filename), decodes but discards input until the timestamps reach position.

position may be either in seconds or in hh:mm:ss[.xxx] form.

  • The -i option means to use the following as input to ffmpeg, here we use Bash's command substitution to use the output of youtube-dl.
  • -vframes 1 sets the number of output frames to 1.
  • -q:v 2 controls output quality. The full range is a linear scale of 1-31 where a lower value results in a higher quality. 2-5 is the range recommended in the source answer used for the ffmpeg part of this answer.
  • "$screenshot_time" should be replaced with the timestamp of the clip you wish to capture in the from shown above.
  • "$output_file" should be replaced with the path to your output file, screenshot.jpeg or similar perhaps.

In terms of the youtube-dl command, -f 22 downloads as the best possible quality mp4 format, and the "$youtube_url" should be replaced with the URL of the video.


The plumber tool offers the ability to grab a screenshot of a single frame in a youtube video. To install the tool, type the following in a terminal window:

sudo snap install plumber

Paste the youtube url in the box marked in yellow, or use the built-in search function by clicking the icon marked in red.

You can then find the desired frame in the video and click the icon marked in pink, followed by the icon marked in green, which will open another window to show a preview of the screenshot and allow you to save it as an image file.

The tool can also be used to save videos/gifs of a clip of a youtube video.

plumber main screen

screenshot window