Why am I getting the above error message when I run this program? I'm running this program with an mp3 file as an argument, the mp3 file is in the same directory as the python program. There are 30 space reserved for the Title at positoin 125 from the end of an mp3 file, what the title doesn't take up is padded with '\x00', I'm trying to get the title and avoid the 0('\x00') values.

#!/usr/bin/env python3

import sys

file = sys.argv[1]
f = open(file, 'rb')

f.seek(-125, 2)

char = f.read(30)
newchar = ''
counter = 0

while char[counter] is not 0:
    newchar = newchar + char[counter]
    counter = counter + 1

print(newchar)

f.close()

Recommended Answers

All 9 Replies

You're getting the error because char is of type bytes, and char[counter] is an integer. Also you initiliazed newchar as a str. At line 15, you can't add a str and an int. You could write

newchar = b'' # initialize as bytes
counter = 0

while counter < 30 and char[counter]:
    newchar = newchar + char[counter:counter +1] # bytes + bytes
    counter = counter + 1

However there is a much simpler way to remove trailing zero bytes:

newchar = char.rstrip(b'\x00')

Last, but not least, I tried with pygame/examples/data/house_lo.mp3 and the 125 last bytes are all space characters followed by exactly 1 null character.

Slice it out can be another option.

with open('06 Rooster.mp3', 'rb') as f:
    f.seek(-128,2)
    tag_content = f.read(128)
    title = tag_content[3:33]
    print title # Rooster

You do know that there are several libraries that can do this(Mutagen,eyeD3...)?

import eyed3

audiofile = eyed3.load("06 Rooster.mp3")
print audiofile.tag.title
print audiofile.tag.artist
print audiofile.info.bit_rate_str

'''Output-->
Rooster
Alice In Chains
~195 kb/s
'''

Your other post.
http://www.daniweb.com/software-development/python/threads/479773/mp3-meta-data

Gribouillis shouldn't char[counter] give me the byte residing at the index of counter, and not an actual int? I also tried your rstrip example but this is what I got. ->

builtins.TypeError: Type str doesn't support the buffer API

#!/usr/bin/env python3

import sys

file = sys.argv[1]
f = open(file, 'rb')

f.seek(-125, 2)
artist = f.read(30)

newartist = artist.rstrip('\x00')

print(new)

f.close()

I think you are mistaking str for bytes in python 3. In python 3, str are unicode strings (sequences of abstract unicode code points) and bytes are arrays of small integers. Use b'\x00' when bytes are needed and '\x00' when str are needed. The key to survival is to separate clearly the 2 things. After f.read(), artist is a bytes. You can add comments to indicate this.

Do you mean that you can not explicitly change to string like:

#!/usr/bin/env python3

import sys

file = sys.argv[1]
f = open(file, 'rb')

f.seek(-125, 2)
artist = f.read(30)

newartist = str(artist, 'UTF8').rstrip('\x00')

print(new)

f.close()

There is also artist.decode().

Gribouillis thanks, this line worked ->
newchar = newchar + char[counter:counter + 1] The only problem now is that the title is wrapped in b'', so it comes out like this b'Rooster'. Any idea how I can get rid of it? Could you explain the line above a little to me though please? I thought my line would simply select the byte residing at the index held by the counter variable. What does it mean to have counter:counter? And why the + 1? If you could point me towards a good resource for reading about the differences between the bytes and strings that would be helpfull as well. I think that's going to continue to byte me in the future.

snippsat, A simple slice would have workd but I'll have no way of knowing how long each title or artist is going to be for any given mp3. If I slice all 30 bytes I'll end up with all the extra '\x00' junk, which so far I've had no luck getting rid of with rstrip. I know there are libraries but I kinda wanted to do this myself. In the end I hope to have a program to auto move all my mp3, ogg, and flac files into their appropriate artist and album directories within /home/garrett/Music/.

#!/usr/bin/env python3

import sys

file = sys.argv[1]
f = open(file, 'rb')

f.seek(-125, 2)

char = f.read(30)

newchar = b''
counter = 0

while char[counter] is not 0:
    newchar = newchar + char[counter:counter + 1]
    counter = counter + 1

print(newchar)

f.close()

Here is an explanation, first with a list, then with a bytes. char[counter:counter+1] is a slice, which has the same type as char, while char[counter] is an element.

>>> L = list(range(100, 110))
>>> L
[100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
>>> L[4]
104
>>> L[4:5]
[104]
>>> counter = 7
>>> L[counter]
107
>>> L[counter:counter+1]
[107]
>>> x = b'abcdefghijk'
>>> x[4]
101
>>> x[4:5]
b'e'
>>> print(x)
b'abcdefghijk'
>>> print(x.decode('utf-8'))
abcdefghijk

Thanks Gribourillis, I think I've got it now.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.