Split mp3 of album into individual tracks
I'll consider answering your last question (at least at the moment) about subprocess.run(). 

There's a similar method you can use for this kind of situations named subprocess.check_call(). The difference between the two is that call() already gives you the return code —
 not as an attribute, just as the return value of the function. The reason you might want to use check_call() is that it takes care of checking that return code for you, raising a CalledProcessError. 

Anyway, either one will raise an OSError for the program not being found.

So, a first solution to your problem might look like this:

try:
    subprocess.check_call(track.setargs(infile, metadata))
except subprocess.CalledProcessError:
    pass  # handle errors in the called executable
except OSError:
    pass  # executable not found


Now, I don't necessary like this solution because sincerely I don't know about those specific exception cases, or check_call() / run() (which apparently they both block). What I learned from my previous projects is that .run() basically merges all the old functions — call(), check_call(), check_output() — into one friendlier function.



You should know that subprocess will raise an exception, OSError, when a command is not found. So, if you catch OSError you can handle the non-existent command, and if you check the result code you can find out whether the command succeeded or not.

As a personal advice, If you have no good way to handle it, let it raise. If you want to continue the execution even if this fails, log it somewhere:

try:
    subprocess.run(track.setargs(infile, metadata))
except OSError as e:
    logger.WARNING("Error: {}".format(e))


Depending on what track.setargs() raises, you can change the Error type. 

It's worth mentioning that you might want to use except Exception which will cover any runtime exceptions. With except Exception you can remove the OSError except since Exception will cover those as well. This way of exception handling is kind of hand wavey (and it's best avoided) but will keep your program running.



Other aspects:


you're reading the entire file into memory before processing it.  If the file is very large, that will be slow; and if it's very large, it'll fail. Consider reading the file line by line.
I wouldn't bother writing a setEnd method. Calling it is no simpler than just saying tk.endtime = 3.
you can test if a string has '=' with:   if '=' in line:


PEP8


methods are usually snake_cased so if you'll keep your setEnd(self, endtime) it should be renamed to set_end(self, endtime)


Overall, nice job! You did pretty well! Keep going the good work.