|
13 | 13 |
|
14 | 14 | import cv2 |
15 | 15 | import exifread |
| 16 | +import ffmpeg |
16 | 17 | import httpx |
17 | 18 | import magic |
18 | 19 | import pymupdf |
@@ -186,6 +187,17 @@ def _handle_thumbnail_source_job(self, job: ThumbnailSourceJob, fileinfo: dict[s |
186 | 187 | exif[0x131] = self.clientinfo["client_version"] |
187 | 188 | job.exif = exif |
188 | 189 | return |
| 190 | + if fileinfo["filetype"] == "audio": |
| 191 | + # use ffmpeg to generate a picture of the waveform |
| 192 | + ss = self._get_audio_screenshot(job=job) |
| 193 | + job.images = [ss] |
| 194 | + exif = Image.Exif() |
| 195 | + exif[0x100] = job.images[0].width |
| 196 | + exif[0x101] = job.images[0].height |
| 197 | + exif[0x10E] = f"ThumbnailSource for BMA audio file {job.basefile_uuid}" |
| 198 | + exif[0x131] = self.clientinfo["client_version"] |
| 199 | + job.exif = exif |
| 200 | + return |
189 | 201 |
|
190 | 202 | # unsupported filetype |
191 | 203 | raise JobNotSupportedError(job=job) |
@@ -217,6 +229,19 @@ def _get_document_screenshot(self, job: ThumbnailSourceJob, page: int = 0) -> Im |
217 | 229 | pix = pdfpage.get_pixmap() |
218 | 230 | return Image.frombytes("RGB", (pix.width, pix.height), pix.samples) |
219 | 231 |
|
| 232 | + def _get_audio_screenshot(self, job: ThumbnailSourceJob) -> Image.Image: |
| 233 | + """Get a waveform screenshot. Requires ffmpeg as external dep.""" |
| 234 | + path = self.path / job.source_url[1:] |
| 235 | + output, _ = ( |
| 236 | + ffmpeg.input(str(path)) |
| 237 | + .filter("compand") |
| 238 | + .filter("showwavespic", s="1000x1000", split_channels=1) |
| 239 | + .output("pipe:", format="webp", vframes="1") |
| 240 | + # .overwrite_output() |
| 241 | + .run(capture_stdout=True) |
| 242 | + ) |
| 243 | + return Image.open(BytesIO(output)) |
| 244 | + |
220 | 245 | ############################################################################### |
221 | 246 |
|
222 | 247 | def _write_and_upload_result(self, job: Job, filename: str) -> None: |
|
0 commit comments