Repository: pytorch/vision

Issue:
Torchvision Python Setup Script Does not handle FFMPEG Version Properly 
## 🐛 Bug

<!-- A clear and concise description of what the bug is. -->

When building torchvision from source with ffmpeg support (I wanted to use `torchvision.io.VideoReader` class which needs the torchvisoin package installed from source with ffmpeg support), it seems that the setup script does not handle the version of ffmpeg correctly. In fact, the intsalled version of ffmpeg in my case was an ubuntu revision of ffmpeg (the exact version was `4.2.4-1ubuntu0.1`) and with this version the `setup.py` scripts crashes.

## To Reproduce

Steps to reproduce the behavior:

1. Install the ffmpeg library:
```
sudo apt-get update
sudo apt-get install ffmpeg
```

2. Build the torchvision package from source with FFMpeg supoprt:
```
export NO_FFMPEG=false
python setup.py install
```
The first few lines of the output are as follows:
```
Building wheel torchvision-0.11.0a0+8d54022
PNG found: True
libpng version: 1.6.37
Building torchvision with PNG image support
libpng include path: /usr/include/libpng16
Running build on conda-build: False
Running build on conda: False
JPEG found: True
Building torchvision with JPEG image support
NVJPEG found: True
Building torchvision with NVJPEG image support
Error fetching ffmpeg version, ignoring ffmpeg.
FFmpeg found: False

```
2. Although ffmpeg is already installed, the script cannot recognize its version. After some inspection, I found that the following try-catch block in setup.py raises the exception (lines 351-362 of setup.py on the master branch):

```
if has_ffmpeg:
    try:
        ffmpeg_version = subprocess.run(
            'ffmpeg -version | head -n1', shell=True,
            stdout=subprocess.PIPE).stdout.decode('utf-8')
        ffmpeg_version = ffmpeg_version.split('version')[-1].split()[0]
        if StrictVersion(ffmpeg_version) >= StrictVersion('4.3'):
            print(f'ffmpeg {ffmpeg_version} not supported yet, please use ffmpeg 4.2.')
            has_ffmpeg = False
    except (IndexError, ValueError):
        print('Error fetching ffmpeg version, ignoring ffmpeg.')
        has_ffmpeg = False
```
 
5.  This block simply tries to extract the ffmpeg version by running the `ffmpeg -version` command. When I run this command in my shell environment I get the following output:

```
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libavresample   4.  0.  0 /  4.  0.  0
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100
libpostproc    55.  5.100 / 55.  5.100
```

With this output from the version command, it is easy to check that the `ffmpeg_version` variable in the try-catch block becomes "4.2.4-1ubuntu0.1". Therefore, `StrictVersion` does not recognize this string as a valid input and raises a ValueError exception. 

<!-- If you have a code sample, error messages, stack traces, please provide it here as well -->

## Expected behavior

<!-- A clear and concise description of what you expected to happen. -->
When I removed the try-catch block from setup script, torchvision was built successfully and I could use the `io.VideoReader` class without any problems. Regarding the installed version of ffmpeg, the only restriction that I saw was that versions 4.3 and higher are not supported. Nothing was mentioned about the ubuntu revision package which was installed on my machine as the default.

## Environment

Please copy and paste the output from our
[environment collection script](https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py)
(or fill out the checklist below manually).

You can get the script and run it with:
```
wget https://raw.githubusercontent.com/pytorch/pytorch/master/torch/utils/collect_env.py
# For security purposes, please check the contents of collect_env.py before running it.
python collect_env.py
```
PyTorch version: 1.9.0+cu111
Is debug build: False
CUDA used to build PyTorch: 11.1
ROCM used to build PyTorch: N/A

OS: Ubuntu 20.04.2 LTS (x86_64)
GCC version: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Clang version: 10.0.0-4ubuntu1 
CMake version: version 3.16.3
Libc version: glibc-2.31

Python version: 3.8.10 (default, Jun  2 2021, 10:49:15)  [GCC 9.4.0] (64-bit runtime)
Python platform: Linux-5.8.0-63-generic-x86_64-with-glibc2.29
Is CUDA available: True
CUDA runtime version: 11.1.74
GPU models and configuration: GPU 0: Quadro P400
Nvidia driver version: 455.23.05
cuDNN version: Could not collect
HIP runtime version: N/A
MIOpen runtime version: N/A

Versions of relevant libraries:
[pip3] numpy==1.21.0
[pip3] torch==1.9.0+cu111
[pip3] torchaudio==0.9.0
[pip3] torchvision==0.11.0a0+8d54022
[conda] Could not collect



## Additional context

<!-- Add any other context about the problem here. -->



Discussion:
Thanks for the detailed report @mrsalehi 

Unfortunately I fear that we might not be able to catter to every single possible version format that exists in the world. One possible solution would be to support something like `TORCHVISION_FORCE_FFMPEG` to bypass all those checks. It would be up to the user to make sure that their version is compatible though.
Thoughts @fmassa?
If we assume that `ffmpeg` in general follows the `major.minor.patch` versioning scheme, we could use something like `ffmpeg_version = re.match(r"ffmpeg version (?P<version>\d+[.]\d+[.]\d+)", output).group("version")`

```python
if has_ffmpeg:
    output = subprocess.run("ffmpeg -version | head -n1", shell=True, stdout=subprocess.PIPE).stdout.decode("utf-8")
    match = re.match(r"ffmpeg version (?P<version>\d+[.]\d+[.]\d+)", output)
    if match and StrictVersion(match.group("version")) >= StrictVersion("4.3"):
        print(f'ffmpeg {match.group("version")} not supported yet, please use ffmpeg 4.2.')
        has_ffmpeg = False
```
cc-ing @andfoy as he also contributed to FFMPEG build
Thanks for your reply @NicolasHug. I believe what you say is totally legit. However, I also fear that the ubuntu revision versions of these packages prevail and become headache for the users who want to build Torchvision from source! I am saying this as I could reproduce this issue in a containerized Ubuntu 18 too.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
 import os
 import io
+import re
 import sys
 from setuptools import setup, find_packages
 from pkg_resources import parse_version, get_distribution, DistributionNotFound
@@ -350,10 +351,10 @@ def get_extensions():
     has_ffmpeg = ffmpeg_exe is not None
     if has_ffmpeg:
         try:
-            ffmpeg_version = subprocess.run(
-                'ffmpeg -version | head -n1', shell=True,
-                stdout=subprocess.PIPE).stdout.decode('utf-8')
-            ffmpeg_version = ffmpeg_version.split('version')[-1].split()[0]
+            # this splits on both dots and spaces as the output format differs across versions / platforms
+            ffmpeg_version_str = str(subprocess.check_output(["ffmpeg", "-version"]))
+            ffmpeg_version = re.split(r"ffmpeg version |\.| |-", ffmpeg_version_str)[1:3]
+            ffmpeg_version = ".".join(ffmpeg_version)
             if StrictVersion(ffmpeg_version) >= StrictVersion('4.3'):
                 print(f'ffmpeg {ffmpeg_version} not supported yet, please use ffmpeg 4.2.')
                 has_ffmpeg = False


Test patch: