瀏覽代碼

Attempt to fix Instagram returning 500 with certain videos

Use ffprobe to check to see if a video is not in the yuv420p format,
and if it is transcode it. And add yuv420p and faststart to the encoder
flags to improve the chances of Instagram accepting the video.
Scott Weber 2 年之前
父節點
當前提交
c62f5e132f
共有 1 個文件被更改,包括 32 次插入2 次删除
  1. 32 2
      mautrix_instagram/portal.py

+ 32 - 2
mautrix_instagram/portal.py

@@ -418,6 +418,25 @@ class Portal(DBPortal, BasePortal):
             allow_full_aspect_ratio="true",
         )
 
+    async def _needs_conversion(
+        self,
+        data: bytes,
+        mime_type: str,
+    ) -> bool:
+        if mime_type != "video/mp4":
+            self.log.info(f"Will convert: mime_type is {mime_type}")
+            return True
+        else:
+            probe = await ffmpeg.probe_bytes(data, input_mime=mime_type, logger=self.log)
+            is_there_correct_stream = any(
+                "pix_fmt" in stream and stream["pix_fmt"] == "yuv420p"
+                for stream in probe["streams"]
+            )
+            if not is_there_correct_stream:
+                self.log.info(f"Will convert: no yuv420p stream found")
+                return True
+            return False
+
     async def _handle_matrix_video(
         self,
         sender: u.User,
@@ -429,13 +448,24 @@ class Portal(DBPortal, BasePortal):
         width: int | None = None,
         height: int | None = None,
     ) -> CommandResponse:
-        if mime_type != "video/mp4":
+        if await self._needs_conversion(data, mime_type):
             data = await ffmpeg.convert_bytes(
                 data,
                 output_extension=".mp4",
-                output_args=("-c:v", "libx264", "-c:a", "aac"),
+                output_args=(
+                    "-c:v",
+                    "libx264",
+                    "-pix_fmt",
+                    "yuv420p",
+                    "-c:a",
+                    "aac",
+                    "-movflags",
+                    "+faststart",
+                ),
                 input_mime=mime_type,
+                logger=self.log,
             )
+            self.log.info(f"Uploaded video converted")
 
         self.log.trace(f"Uploading video from {event_id}")
         _, upload_id = await sender.client.upload_mp4(