urinieto / msaf

Music Structure Analysis Framework
MIT License
501 stars 79 forks source link

msaf.exceptions.NoAudioFileError: Couldn't find audio file inside Docker container #120

Closed mepc36 closed 1 year ago

mepc36 commented 1 year ago

MSAF is unable to locate both .wav and .mp3 files.

I'm attempting to call MSAF as a child process of Node.js inside a Docker container.

More specifically, I'm running this command...

python3 ./src/msaf/run-msaf.py my-uuid-job-id-here

...that calls this script:

from __future__ import print_function
import msaf
import librosa
import sys

import IPython.display

job_id = sys.argv[1]
audio_file = "/tmp/{}.mp3".format(job_id)
IPython.display.Audio(filename=audio_file)
boundaries, labels = msaf.process(audio_file)
print(boundaries)

IPython.display.Audio(filename=audio_file) evaluates into an Audio object fine, but when msaf.process(..) runs, the following error gets thrown:

req.files: [Object: null prototype] {
  audio_file: [
    {
      fieldname: 'audio_file',
      originalname: 'input.mp3',
      encoding: '7bit',
      mimetype: 'audio/wav',
      destination: '/tmp',
      filename: 'input.mp3',
      path: '/tmp/input.mp3',
      size: 1476019
    }
  ]
}
audioFileName: input.mp3
jobId: aff2625a-fa69-4344-9e0c-e51e7b60e9fb
comm: python3 ./src/msaf/run-msaf.py aff2625a-fa69-4344-9e0c-e51e7b60e9fb
### data: run_msaf.py > job_id: aff2625a-fa69-4344-9e0c-e51e7b60e9fb
run_msaf.py > audio_file: /tmp/aff2625a-fa69-4344-9e0c-e51e7b60e9fb.mp3

INFO: stderr.on('data'):
 Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 220, in read_features
    with open(self.file_struct.features_file) as f:
FileNotFoundError: [Errno 2] No such file or directory: '.features_msaf_tmp.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 415, in features
    self.read_features()
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 281, in read_features
    raise NoFeaturesFileError("Could not find features file %s",
msaf.exceptions.NoFeaturesFileError: ('Could not find features file %s', '.features_msaf_tmp.json')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/soundfile.py", line 161, in <module>
    import _soundfile_data  # ImportError if this doesn't exist
ModuleNotFoundError: No module named '_soundfile_data'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/soundfile.py", line 170, in <module>
    raise OSError('sndfile library not found using ctypes.util.find_library')
OSError: sndfile library not found using ctypes.util.find_library

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 419, in features
    self._compute_all_features()
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 360, in _compute_all_features
    self._audio, _ = librosa.load(self.file_struct.audio_file,
  File "/usr/local/lib/python3.9/site-packages/lazy_loader/__init__.py", line 77, in __getattr__
    attr = getattr(submod, name)
  File "/usr/local/lib/python3.9/site-packages/lazy_loader/__init__.py", line 76, in __getattr__
    submod = importlib.import_module(submod_path)
  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked

INFO: stderr.on('data'):
   File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module

INFO: stderr.on('data'):
   File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/usr/local/lib/python3.9/site-packages/librosa/core/audio.py", line 10, in <module>

INFO: stderr.on('data'):
     import soundfile as sf
  File "/usr/local/lib/python3.9/site-packages/soundfile.py", line 192, in <module>

INFO: stderr.on('data'):
     _snd = _ffi.dlopen(_explicit_libname)
OSError: cannot load library 'libsndfile.so': libsndfile.so: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/app/./src/msaf/run-msaf.py", line 13, in <module>

INFO: stderr.on('data'):
     boundaries, labels = msaf.process(audio_file)
  File "/usr/local/lib/python3.9/site-packages/msaf/run.py", line 342, in process

INFO: stderr.on('data'):
     est_times, est_labels = run_algorithms(file_struct, boundaries_id,
  File "/usr/local/lib/python3.9/site-packages/msaf/run.py", line 199, in run_algorithms

INFO: stderr.on('data'):
     if config["features"].features.shape[0] <= msaf.config.minimum_frames:
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 430, in features

INFO: stderr.on('data'):
     raise NoAudioFileError(msg % self.file_struct.audio_file)
msaf.exceptions.NoAudioFileError: Couldn't find audio file in /tmp/aff2625a-fa69-4344-9e0c-e51e7b60e9fb.mp3

I'm also running this inside a Docker container. This is that container's Dockerfile:

FROM nikolaik/python-nodejs:python3.9-nodejs17

WORKDIR /usr/src/app

COPY . /usr/src/app

RUN pip install msaf
RUN pip install ipython

RUN yarn cache clean
RUN yarn install

RUN apt-get update
RUN apt-get install vim

EXPOSE 3037
CMD [ "node", "./src/swagger/swagger.js"]

Yes, this means I have to manually edit vol.py & sivm_search.py to fix the import of factorial in scipy (see #119 for more info).

When I ls the tmp folder where the audio file is supposed to be located, the file is indeed there:

root@a9fdff73fa12:/tmp# ls
12c61b40-1d4d-4c9d-a685-13ad8fe047ef.mp3
573010de-eeb3-4c26-a7bd-bea1b6e7b65b.mp3
aff2625a-fa69-4344-9e0c-e51e7b60e9fb.mp3
tmpu66kjsswcacert.pem
tmpug4kav8dcacert.pem
v8-compile-cache-0

And when I call path.is_file() inside Python as well, the file also exists.

Any help? Thank you!

mepc36 commented 1 year ago

If I install ffmpeg I get new errors, although with the same first one (about .features_tmp.json` not existing):

>>> boundaries, labels = msaf.process(audio_file)

/usr/local/lib/python3.9/site-packages/msaf/base.py:360: UserWarning: PySoundFile failed. Trying audioread instead.
  self._audio, _ = librosa.load(self.file_struct.audio_file,
/usr/local/lib/python3.9/site-packages/librosa/core/audio.py:184: FutureWarning: librosa.core.audio.__audioread_load
     Deprecated as of librosa version 0.10.0.
     It will be removed in librosa version 1.0.
  y, sr_native = __audioread_load(path, offset, duration, dtype)
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 220, in read_features
    with open(self.file_struct.features_file) as f:
FileNotFoundError: [Errno 2] No such file or directory: '.features_msaf_tmp.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 415, in features
    self.read_features()
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 281, in read_features
    raise NoFeaturesFileError("Could not find features file %s",
msaf.exceptions.NoFeaturesFileError: ('Could not find features file %s', '.features_msaf_tmp.json')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/site-packages/msaf/run.py", line 342, in process
    est_times, est_labels = run_algorithms(file_struct, boundaries_id,
  File "/usr/local/lib/python3.9/site-packages/msaf/run.py", line 199, in run_algorithms
    if config["features"].features.shape[0] <= msaf.config.minimum_frames:
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 419, in features
    self._compute_all_features()
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 370, in _compute_all_features
    self._compute_framesync_times()
  File "/usr/local/lib/python3.9/site-packages/msaf/base.py", line 353, in _compute_framesync_times
    self._framesync_times = librosa.core.frames_to_time(
TypeError: frames_to_time() takes 1 positional argument but 3 were given
urinieto commented 1 year ago

The .features_msaf_tmp.json is a temporary file created by MSAF to store the features of the given audio file during single mode. My guess is that you don't have write permissions on that given folder. You can update the path of that file by doing the following:

import msaf
msaf.config.features_tmp_file = "<desired/path>"
boundaries, labels = msaf.process(audio_file)

See more info here: https://pythonhosted.org/msaf/config.html

wsxcvfre commented 1 year ago

I also found temp feature file does not exist problem, I tried to configure features_tmp_file but it still can't create temp feature file.

Is there any other suggestion? BTW, I use python 3.7

urinieto commented 1 year ago

That's weird, can you double check that your tmp file is properly created? If so, can you actually open it? (Maybe it's corrupt?)

wsxcvfre commented 1 year ago

No, the temp file didn't create. No matter what path I set.

urinieto commented 1 year ago

Can you verify that MSAF has writing permissions wherever you're trying to create the file?

wsxcvfre commented 1 year ago

I think it has writing permission because there's no warning message from my macOS while I run the program. I also tried to run it in Visual Studio Code, Terminal, and Terminal Sudo mode, but none of it worked. And I tried to run it on my Windows desktop, it's the same.

File "/.venv/lib/python3.7/site-packages/msaf/base.py", line 220, in read_features with open(self.file_struct.features_file) as f: FileNotFoundError: [Errno 2] No such file or directory: 'features_msaf_tmp.json'

wsxcvfre commented 1 year ago

Hi Urinieto, I fixed this issue. The root cause is that when using some functions in librosa, we need to modify our code like below (Maybe it's because I use the newer librosa version.)

from S = librosa.feature.melspectrogram(self._audio, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels)

self._framesync_times = librosa.core.frames_to_time( np.arange(self._framesync_features.shape[0]), self.sr, self.hop_length)

to S = librosa.feature.melspectrogram(y=self._audio, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels)

self._framesync_times = librosa.core.frames_to_time( frames=np.arange(self._framesync_features.shape[0]), sr=self.sr, self.hop_length)

to prevent positional arguments error. The error causes json file didn't write properly because the feature didn't generate.

urinieto commented 1 year ago

Oh, good finding! Yeah, MSAF requires librosa 0.6.1, as stated in the requirements.txt. Closing this for now.