0

I'm trying to rename my media file names based on the metadata.

File name format is song name - artist name

import os
from tinytag import TinyTag
import re

for root, dirs, files in os.walk("C:/Users/username/Desktop/Music/"):
    for name in files:
        tag = TinyTag.get(root + "\\" + name)
        if tag.artist != "":
            if name.endswith((".mp3",".m4a")):
                # try:
                file_ext = os.path.splitext(name)[-1]
                old_name = os.path.join(root, name)
                new_name = re.sub(' +', ' ', os.path.join(root, tag.title + " - " + tag.artist + file_ext))
                print(new_name)
                os.rename(old_name, new_name)
                # except:
                    # pass

Every file works except for Little Red Corvette by Prince:

C:/Users/username/Desktop/Music/1973 - James Blunt.mp3
C:/Users/username/Desktop/Music/Little Red Corvette  - Prince .mp3
Traceback (most recent call last):
  File "C:/Users/username/PycharmProjects/Practice/editAudioFileNames.py", line 15, in <module>
    os.rename(old_name, new_name)
ValueError: rename: embedded null character in dst

What does the ValueError mean? I noticed that there is an extra space after Corvette. I did use re.sub in my code to trim the file names.

Ignore the try, except for now because the code does work with it. I could change the file name manually since this is the only one out of 850 songs but I want to know for my future understanding.

As a side note, this is my first ever useful code! Optimization critiques are most welcome.

Julian
  • 411
  • 4
  • 18
  • Can you use `strip` to remove both the leading and trailing whitespaces ? More information here : https://www.programiz.com/python-programming/methods/string/strip - thanks – Gagan Apr 13 '19 at 23:23
  • `ValueError` is (for example) when function expects string but you use number. It seems `new_name` has char with code zero (null character) and it is not allowed in file names. You create `new_name` using `root`, `tag.title`, `tag.artist`, `file_ext` - remove one of this element and see if you get working code, if not then remove another element, etc. This way you can find element which have `"null character"`. Or you can use `ord(char)` with every char in `new_name` to see which char has code `zero`. – furas Apr 13 '19 at 23:41
  • So I used your ord(char) method and it does seem there is an extra after the words "Corvette" and "Prince". But I'm not sure why strip() doesn't remove it. At this point, I'm probably going to leave it. – Julian Apr 14 '19 at 00:15

1 Answers1

0

Can you please try replacing these lines

old_name = os.path.join(root, name)
new_name = re.sub(' +', ' ', os.path.join(root, tag.title + " - " + tag.artist + file_ext))

with these lines

old_name = os.path.join(root, name.strip())
new_name = re.sub(' +', ' ', os.path.join(root, tag.title.strip() + " - " + tag.artist.strip() + file_ext.strip()))

Thanks

Gagan
  • 5,416
  • 13
  • 58
  • 86