PermissionError when accessing a data file (.exe) from background task

What I’m trying to do:
I have an app wherein the user enters the G-Drive folder link, and depending on which file is there in that folder, different background tasks are executed.
For the link to a video, I have a background task function that takes in the video’s link and returns it as a anvil Media object (that works very well) and then converts it to a TempFile, that is then split into multiple audio segments using PyDub, and stores the value of all those segments in a Buffer I/O object. [This is the part that doesn’t work]

The issue I’m facing is that as soon as the code reaches AudioSegment.from_file(file_path, format='mp4'), the server always exits unexpectedly.

What I’ve tried and what’s not working:
I saved the ffmpeg file that I had on my local computer as a data file (ffmpeg.exe) in anvil, but as soon as I pass AudioSegment.converter = data_files['ffmpeg.exe'], it returns this error:

PermissionError: [Errno 13] Permission denied: '/tmp/anvil-data-files/table-498304/ffmpeg.exe'
at /usr/local/lib/python3.10/subprocess.py, line 1863
called from /usr/local/lib/python3.10/subprocess.py, line 971
called from /home/anvil/.env/lib/python3.10/site-packages/pydub/audio_segment.py, line 766
called from Test_Functions, line 30

where line 30 in Test_Functions is AudioSegment.from_file(file_path, format='mp4').

Can anyone please tell me what the issue is, and how I can solve it?

Code Sample:
Here is the full server modules excluding the imports [all the libraries used in the code have been imported].

AudioSegment.converter = data_files['ffmpeg.exe']

@anvil.server.callable
def test(file_path):
    AudioSegment.from_file(file_path, format='mp4')

@anvil.server.background_task
def get_time_of_buffering_audio(url):
    media_obj = anvil.server.call('function_that_returns_gdrive_video_url_as_media_object', url)
    
    with anvil.media.TempFile(media_obj) as file_path:
        test(file_path)
        print('Got as TempFile')
        file_path = file_path.replace('\\', '\\\\')
        start_1 = time()
        print('Started Timer')
        file = AudioSegment.from_file(file_path, format='mp4')
        print(time()-start_1)
        file_segment_length = 10*60*1000
    
        files = file[::file_segment_length]
    
    buffers = []
    for file_segment in files:
        start_2 = time()
        buffer = BytesIO()
        file_segment.export(buffer, format='mp4')
        buffers.append(buffer)
        print(time()-start_2)


@anvil.server.callable
def launch_audio_buffering_timer(url):
    anvil.server.launch_background_task('get_time_of_buffering_audio', url)

This is how ffmpeg.exe is stored in the Data Tables:

Thanks in advance, to your response!

1 Like

.exe is the DOS/Windows file extension for an executable program, not a media file. I can think of no good reason to read, write, or run a DOS/Windows program on Anvil’s (non-DOS, non-Windows, i.e., Linux) servers, but quite a few nefarious ones.

Could you be running afoul of some security watchdog program?

1 Like

Lol no, I’m not doing any nefarious things, I swear.

I needed that file to be able to run the pydub library, but I ended up not using the library itself, so it doesn’t matter anymore.

Leaving this for the people who may want the answer to this question later:

For my use case, I ended up not using ffmpeg.exe at the end after all.

Instead, I used youtube-dl to extract the video and convert it in a mp4 file and then use moviepy’s VideoFileClip to divide the video in multiple segments and send that video segment to Whisper for transcription.
I would’ve liked to use the audio version, but since I wasn’t aware of how to do it at the time, I used the video version. For the audio version, I recently found this thread on the Forums that will help you to deal with that (the title is a bit misleading, so don’t let that concern you):

2 Likes