1

I'm trying to use pydub to convert uploaded mp3s to a certain bitrate, using this code:

from pydub import AudioSegment

def process_mp3(mp3, id):
    print(mp3) # media/track1-original
    audio = AudioSegment.from_mp3(mp3)
    bitrates = [128, 192, 256, 320]

    for bitrate in bitrates:
        audio.export(settings.MEDIA_ROOT + '/' + 'track' + id + '-' + bitrate, format="mp3", bitrate=bitrate + 'k')

def save_file(file, name):

    with open(default_storage.path(settings.MEDIA_ROOT + '/' + name), 'wb+') as destination:
        for chunk in file.chunks():
            destination.write(chunk)

    return name

I'm getting this error:

FileNotFoundError: [WinError 2] Systemet finner ikke angitt fil

And the code that calls process_mp3 is (Note: track_obj is a Django model object and the ID is from a database):

from mutagen.mp3 import MP3

....

mp3 = save_file(mp3, 'track' + str(track_obj.id) + '-' + 'original')

mp3_info = MP3('media/' + mp3); # This works

process_mp3('media/' + mp3, str(track_obj.id)) # This does not

Apparently, mutagen can read the file just fine, but pydub cannot. What gives?

Anil_M
  • 10,893
  • 6
  • 47
  • 74
Sebastian Olsen
  • 10,318
  • 9
  • 46
  • 91

2 Answers2

0

I haven't played much with mutagen and hence was not able to get track_obj.id to work. Is it a mutagen attribute?

Also, since track_obj.id was not working, It was substituted with track using audio["TIT2"].text[0] by calling mutagen.id3

I removed all explicit references to external paths as well and simplified the paths and the code for testing purpose.

I also noticed that you were trying to concatenate string (path, names etc) with int ( bitrate ). That needed some fixing.

This code does not use save_file function so I can't comment on that.

Anyway, after all this, below code works and is able to save mp3 files with different bitrate by feeding it through pydub.

Here is working code , Hope this helps

Working Code:

from mutagen.mp3 import MP3
from mutagen.id3 import ID3
from pydub import AudioSegment



def process_mp3(mp3, id):
    print(mp3) # media/track1-original
    audio = AudioSegment.from_mp3(mp3)
    bitrates = [128, 192, 256, 320]

    for bitrate in bitrates:
        export_file = my_media_path  + '/' + 'track_' + id + '-' + str(bitrate) +'.mp3'
        print ("exporting %s" % export_file)
        audio.export(export_file, format="mp3", bitrate= str(bitrate) + 'k')

def save_file(file, name):

    with open(default_storage.path(settings.MEDIA_ROOT + '/' + name), 'wb+') as destination:
        for chunk in file.chunks():
            destination.write(chunk)


mp3 = "test.mp3"

mp3_info = MP3('media/' + mp3); # This works

my_media_path = 'media'
audio = ID3('media/' + 'test.mp3')
#print "audio_info = ",audio
track = audio["TIT2"].text[0]
process_mp3('media/' + mp3, str(track))

Output:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>> 
media/test.mp3
exporting media/track_End Matter-128.mp3
exporting media/track_End Matter-192.mp3
exporting media/track_End Matter-256.mp3
exporting media/track_End Matter-320.mp3
>>> 
Anil_M
  • 10,893
  • 6
  • 47
  • 74
  • I forgot to add that this is from a django project, `track_obj` is a django model instance/object and the id is from that instance's database id. Sorry! – Sebastian Olsen Apr 14 '16 at 18:31
  • Yeah it still does not work, I don't understand why though cause I am passing the exact same thing to `process_mp3` that I am passing to mutagen's MP3 function, mutagen works, pydub does not. – Sebastian Olsen Apr 14 '16 at 19:04
  • You may not be passing same thing to `process_mp3`, `str(track_obj.id) is an extra parameter thats passed to that function. Have you tried to check if you get proper value for `"str(track_obj.id)"`before feeding it to `process_mp3` ? Probably do some print statements to see what's being passed and executed. – Anil_M Apr 14 '16 at 19:17
  • The second parameter is just to insert the object id into the exported file name, ie "track1-128.mp3", it has nothing to do with actually getting the file, and besides the error happens on `audio = AudioSegment.from_mp3(mp3)` – Sebastian Olsen Apr 14 '16 at 19:23
  • Can you try with just `audio = AudioSegment.from_mp3("")` , like I did? I had mp3 file in root folder hence did not give any `absolute` or `relative` path. What OS are you using? – Anil_M Apr 14 '16 at 19:33
  • I'm using Windows (Cannot download vm because of internet limitations) and doing that just threw this error: The program cannot start because "libgcc_s_sjlj-1.dll" is missing on the computer. – Sebastian Olsen Apr 14 '16 at 19:43
  • Windows need "//" instead of single "/". So path for `media` will be `media//". Its trivial, but just wanted to make sure you are aware of that. – Anil_M Apr 14 '16 at 19:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/109192/discussion-between-sebastian-olsen-and-anil-m). – Sebastian Olsen Apr 14 '16 at 19:48
0

This may not solve your problem, but pydub also accepts file handles (rather than paths):

try this?

with open("media/test.mp3", "rb") as f:
    AudioSegment.from_mp3(f)
Jiaaro
  • 74,485
  • 42
  • 169
  • 190
  • Tried it, same excact error, this just refuses to work no matter what it seems. Everything else file related in my script works fine, but pydub just can't. – Sebastian Olsen Apr 15 '16 at 14:30
  • @SebastianOlsen are you getting a warning that pydub can't find ffmpeg/avlib? It could be the file that is missing is the ffmpeg executable (which is used to decode the mp3) – Jiaaro Apr 15 '16 at 17:41
  • I installed ffmpeg though, but it did give me an error once saying it couldn't find fmmpeg, but that wasn't even when I was trying to have it read the file – Sebastian Olsen Apr 15 '16 at 17:52
  • @SebastianOlsen try setting the location of the ffmpeg binary with `AudioSegment.converter = "/path/to/ffmpeg"` ? – Jiaaro Apr 15 '16 at 18:17
  • I should mention that I am using a virtualenv, could that maybe be the source of the problem? I have ffmpeg in the PATH env variable. – Sebastian Olsen Apr 15 '16 at 18:26
  • @SebastianOlsen I don't think that would affect anything - ffmpeg is just a binary file, e.g., `ffmpeg.exe` (on windows at least) – Jiaaro Apr 15 '16 at 18:55