Repository: Zulko/moviepy

Issue:
Changes in FFmpeg libavformat break FFmpegInfosParser
#### Expected Behavior
`FFmpegInfosParser.parse` can parse FFmpeg output.

#### Actual Behavior
`FFmpegInfosParser.parse` fails to parse FFmpeg output starting with commit [b7251ae](https://github.com/FFmpeg/FFmpeg/commit/b7251aed46f5ac96fe65c1c68ddac44b07429467), which reduced indentation for streams.

#### Steps to Reproduce the Problem
Point MoviePy to FFmpeg executable with the mentioned revision or newer and run `FFmpegInfosParser.parse`.

#### Specifications
- Python Version: 3.9.9
- Moviepy Version: 2.0.0.dev2 8eaf3f0
- Platform Name: Linux
- Platform Version: Fedora 34

#### Additional Info
ffmpeg 4.2.2 (imageio) output:
```
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'clip.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.12.100
  Duration: 01:00:00.00, start: 0.000000, bitrate: 1222 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1221 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
At least one output file must be specified
```
ffmpeg 4.4.1 (system) output:
```
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'clip.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.12.100
  Duration: 01:00:00.00, start: 0.000000, bitrate: 1222 kb/s
  Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1221 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
At least one output file must be specified
```
There are other commits changing the output format too, but the mentioned one is the most problematic one.

Discussion:
B3QL: Thanks for the quick feedback loop! Do you have some ETA for the next release?

Patch:
diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py
index 3e24557..e961017 100644
--- a/moviepy/video/io/ffmpeg_reader.py
+++ b/moviepy/video/io/ffmpeg_reader.py
@@ -415,14 +415,14 @@ class FFmpegInfosParser:
                 else:
                     self._last_metadata_field_added = field
                 self.result["metadata"][field] = value
-            elif line.startswith("    Stream "):
+            elif line.lstrip().startswith("Stream "):
                 # exit stream "    Metadata:"
                 if self._current_stream:
                     self._current_input_file["streams"].append(self._current_stream)
 
                 # get input number, stream number, language and type
                 main_info_match = re.search(
-                    r"^\s{4}Stream\s#(\d+):(\d+)\(?(\w+)?\)?:\s(\w+):", line
+                    r"^Stream\s#(\d+):(\d+)\(?(\w+)?\)?:\s(\w+):", line.lstrip()
                 )
                 (
                     input_number,


Test patch:
diff --git a/tests/test_ffmpeg_reader.py b/tests/test_ffmpeg_reader.py
index da40ef5..a1a5cce 100644
--- a/tests/test_ffmpeg_reader.py
+++ b/tests/test_ffmpeg_reader.py
@@ -487,6 +487,30 @@ def test_not_default_audio_stream_audio_bitrate():
     assert d["audio_bitrate"] == 139
 
 
+def test_stream_deidentation_not_raises_error():
+    """Test libavformat reduced streams identation to 2 spaces.
+
+    See https://github.com/FFmpeg/FFmpeg/commit/b7251aed
+    """
+    infos = """Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'clip.mp4':
+  Metadata:
+    major_brand     : isom
+    minor_version   : 512
+    compatible_brands: isomiso2avc1mp41
+    encoder         : Lavf58.12.100
+  Duration: 01:00:00.00, start: 0.000000, bitrate: 1222 kb/s
+  Stream #0:0(und): Video: ..., 30 tbr, 60 tbc
+    Metadata:
+      handler_name    : VideoHandler
+      vendor_id       : [0][0][0][0]
+At least one output file must be specified"""
+
+    d = FFmpegInfosParser(infos, "clip.mp4").parse()
+
+    assert d
+    assert len(d["inputs"][0]["streams"]) == 1
+
+
 def test_sequential_frame_pos():
     """test_video.mp4 contains 5 frames at 1 fps.
     Each frame is 1x1 pixels and the sequence is Red, Green, Blue, Black, White.