Parisson / TimeSide

scalable audio processing framework and server written in Python
https://timeside.ircam.fr/docs/
GNU Affero General Public License v3.0
367 stars 60 forks source link

Aubio encoder fails on particular stream coming from youtube #290

Closed yomguy closed 1 year ago

yomguy commented 2 years ago

For example, retrieving the audio stream of this video with youtube-dl:

https://www.youtube.com/watch?v=04854XqcfCY

results to this:

https://timeside.ircam.fr/media/items/download/Queen_-_We_Are_The_Champions_Official_Video-04854XqcfCY.m4a

and encoding it to FLAC with timeside returns:

[2022-07-05 10:10:35,435: INFO/ForkPoolWorker-14] timeside.server.tasks.experience_run[2f60ffe0-d989-4a91-b844-e7dbab116a45]: Run flac_aubio_encoder-{} on Queen - We are the champions_00af                     
2022-07-05 10:10:35,435 - 2f60ffe0-d989-4a91-b844-e7dbab116a45 - timeside.server.tasks.experience_run - timeside.server.models - INFO - Run flac_aubio_encoder-{} on Queen - We are the champions_00af           
[2022-07-05 10:10:35,435: WARNING/ForkPoolWorker-14] setting up aubio with with
[2022-07-05 10:10:35,435: WARNING/ForkPoolWorker-14] 44100
[2022-07-05 10:10:35,436: WARNING/ForkPoolWorker-14] 8192
[2022-07-05 10:10:36,470: ERROR/ForkPoolWorker-14] Task timeside.server.tasks.experience_run[2f60ffe0-d989-4a91-b844-e7dbab116a45] raised unexpected: ValueError('input array dimension 1 should be greater than 0
')
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/srv/lib/timeside/timeside/server/tasks.py", line 130, in experience_run
    raise e
  File "/srv/lib/timeside/timeside/server/tasks.py", line 111, in experience_run
    item.run(experience, task=task, item=item)
  File "/srv/lib/timeside/timeside/server/models.py", line 628, in run
    pipe.run()
  File "/srv/lib/timeside/timeside/core/processor.py", line 562, in run
    eod
  File "/srv/lib/timeside/timeside/core/aubio_encoder.py", line 81, in process
    self.sink.do_multi(f_slice.T.copy(), write_frames)
ValueError: input array dimension 1 should be greater than 0
piem commented 2 years ago

hello,

when decoding the last frame of a compressed file, aubio.source may return one empty block with no frames at all.

here is a patch to let the encoder ignore such empty blocks:

index 2c8a649b..e75daaba 100644
--- a/timeside/core/aubio_encoder.py
+++ b/timeside/core/aubio_encoder.py
@@ -78,6 +78,9 @@ class AubioEncoder(Processor):
         indices = range(max_write, frames.shape[0], max_write)
         for f_slice in np.array_split(frames, indices):
             write_frames = f_slice.shape[0]
-            self.sink.do_multi(f_slice.T.copy(), write_frames)
-            self.num_samples += write_frames
+            if write_frames > 0:
+                self.sink.do_multi(f_slice.T.copy(), write_frames)
+                self.num_samples += write_frames
+            elif write_frames < 0:
+                raise ValueError ("can not encode a negative number of frames")
         return frames, eod
yomguy commented 2 years ago

thanks @piem could you commit this?