Repository: Zulko/moviepy
Pull request #1783 (2022-06-01 09:12:20)

Fix audio processing for streams with missing `audio_bitrate`
Set default `audio_bitrate` to `None`.

Similar to #1781 if the file is footage from Hikvision CCTV the bitrate is not available to read even if the `audio` stream is present.

https://user-images.githubusercontent.com/3527244/171369718-6feb18ef-29a5-49af-b5df-b1be03565916.mp4




- [x] I have provided code that clearly demonstrates the bug and that only works correctly when applying this fix
- [x] I have added suitable tests demonstrating a fixed bug or new/changed feature to the test suite in `tests/`
- [x] I have properly documented new or changed features in the documentation or in the docstrings
- [x] I have properly explained unusual or unexpected code in the comments around it


B3QL: @mondeja can you take a look? thanks!

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d301eb..995d3e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Fixed mono clips crashing when `audio_fadeout` FX applied [\#1578](https://github.com/Zulko/moviepy/pull/1578)
 - Fixed scroll FX not being scrolling [\#1591](https://github.com/Zulko/moviepy/pull/1591)
 - Fixed parsing FFMPEG streams with square brackets [\#1781](https://github.com/Zulko/moviepy/pull/1781)
+- Fixed audio processing for streams with missing `audio_bitrate` [\#1783](https://github.com/Zulko/moviepy/pull/1783)
 
 
 ## [v2.0.0.dev2](https://github.com/zulko/moviepy/tree/v2.0.0.dev2) (2020-10-05)
diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py
index 9dbc2c5..c94e058 100644
--- a/moviepy/video/io/ffmpeg_reader.py
+++ b/moviepy/video/io/ffmpeg_reader.py
@@ -577,12 +577,15 @@ class FFmpegInfosParser:
 
         # not default audio found, assume first audio stream is the default
         if self.result["audio_found"] and not self.result.get("audio_bitrate"):
+
+            self.result["audio_bitrate"] = None
             for streams_input in self.result["inputs"]:
                 for stream in streams_input["streams"]:
                     if stream["stream_type"] == "audio" and stream.get("bitrate"):
                         self.result["audio_bitrate"] = stream["bitrate"]
                         break
-                if self.result.get("audio_bitrate"):
+
+                if self.result["audio_bitrate"] is not None:
                     break
 
         result = self.result


Test patch:
diff --git a/tests/test_ffmpeg_reader.py b/tests/test_ffmpeg_reader.py
index 89365ba..fad0507 100644
--- a/tests/test_ffmpeg_reader.py
+++ b/tests/test_ffmpeg_reader.py
@@ -527,6 +527,22 @@ At least one output file must be specified"""
     assert d["inputs"][0]["streams"][1]["language"] is None
 
 
+def test_stream_missing_audio_bitrate():
+    infos = """
+Input #0, mpeg, from 'clip.mp4':
+  Duration: 00:02:15.00, start: 52874.498178, bitrate: 266 kb/s
+    Stream #0:0[0x1e0]: Video: ..., 25 tbr, 90k tbn, 50 tbc
+    Stream #0:1[0x1c0]: Audio: mp2, 0 channels, s16p
+At least one output file must be specified"""
+
+    d = FFmpegInfosParser(infos, "clip.mp4").parse()
+
+    assert d
+    assert len(d["inputs"][0]["streams"]) == 2
+    assert d["audio_found"]
+    assert d["audio_bitrate"] is None
+
+
 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.