"TypeError: byte indices must be integers or slices, not str" Converting bytes to ints

24,849

Solution 1

matches = str(re.search(b"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()).encode()

is weird. By converting the result of the regex match to a string, you're causing the error (because now matches['hours'] will fail).

By encoding that string to a bytes object (why?), you're complicating things even further.

matches = re.search(r"Duration:\s(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout).groupdict()

should do (although I'm uncertain about using stdout as input...)

Solution 2

It seems you have a byte object there. In order to use it you can do the following**:

Decode it:

matches = matches.decode("utf-8")

Then, by using ast.literal_eval, translate the str to what it truly is, a dict:

matches = ast.literal_eval(matches)

Then you can access the contents of matches as you normally would:

int(matches['hours']) # returns 0

**Of course this simply fixes an error that really shouldn't be here in the first place as @Tim points out.

Share:
24,849
Lewis Menelaws
Author by

Lewis Menelaws

Python and Web Developer since 2014. I focus in Django, React and AWS.

Updated on July 21, 2022

Comments

  • Lewis Menelaws
    Lewis Menelaws almost 2 years

    I am using a different program (ffmpeg) to grab the length of a youtube video that was downloaded in order to randomize a specific point in the video. However I am getting this error when I am trying to execute this code:

    def grabTimeOfDownloadedYoutubeVideo(youtubeVideo):
        process = subprocess.Popen(['/usr/local/bin/ffmpeg', '-i', youtubeVideo], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        stdout, stderr = process.communicate()
        matches = str(re.search(b"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()).encode()
        print(matches)
        hours = int(matches['hours'])
        minutes = int(matches['minutes'])
        seconds = int(matches['seconds'])
        total = 0
        total += 60 * 60 * hours
        total += 60 * minutes
        total += seconds
        print(total)
    

    The matches variable prints out to this:

    b"{'minutes': b'04', 'hours': b'00', 'seconds': b'24.94'}"
    

    So all of the output comes out with a 'b' at the beginning of it. How do I remove the 'b' and just get the number?

    Full error message here:

    Traceback (most recent call last):
      File "bot.py", line 87, in <module>
        grabTimeOfDownloadedYoutubeVideo("videos/1.mp4")
      File "bot.py", line 77, in grabTimeOfDownloadedYoutubeVideo
        hours = int(matches['hours'])
    TypeError: byte indices must be integers or slices, not str
    
  • Tim Pietzcker
    Tim Pietzcker over 8 years
    Isn't that completely backwards? He created that bytes object himself for no obvious reason.
  • Dimitris Fasarakis Hilliard
    Dimitris Fasarakis Hilliard over 8 years
    Sure, I'm just filling this in because the title indicates an error that will always be able to get fixed by following the steps I suggested.
  • Lewis Menelaws
    Lewis Menelaws over 8 years
    Thanks for the reply! I actually converted it to a bytes object reading this answer stackoverflow.com/questions/5184483/python-typeerror-on-rege‌​x It was the answer that somehow got me to get past that error and thought it may be an easier solution to what im asking
  • Lewis Menelaws
    Lewis Menelaws over 8 years
    Whenever I use what you used I get another TypeError TypeError: cannot use a string pattern on a bytes-like object
  • Tim Pietzcker
    Tim Pietzcker over 8 years
    That's probably because you're accessing stdout. You need to .decode() that using the correct encoding (which depends on your platform). If you're lucky, using str(stdout) instead of stdout will already work.
  • Tim Pietzcker
    Tim Pietzcker over 8 years
    Even better, call Popen using the universal_newlines=True option. That way, you get strings instead of bytes objects, already converted using the system encoding.
  • Lewis Menelaws
    Lewis Menelaws over 8 years
    Thank you for the help Tim.