0

I am trying to remove absolute path info from my playlist.m3u file(s) and convert this file(s) to a relative path, using Python. I can do this with an Excel script that concatenates and it works great, but I would think the Python route would be easier.

Here is a script I have been trying to get to work, without success.

import sys
import os

infile = sys.argv[1]
basepath = os.path.dirname(os.path.abspath(infile))

outlines = []
fp = open(infile)
for line in fp.readlines():
    if line.startswith('#'):  # m3u comments start with #
        outlines.append(line)
    else:
        outlines.append(os.path.relpath(line, basepath))
fp.close()

fp = open(infile, "w")
for line in outlines:
    fp.write(line)
fp.close()

Here is an example of the absolute path playlist file contents:

J:\NTFS_1\MP3_D\Dan Fogelberg - River of Souls - 08 - A Love Like This.mp3 J:\NTFS_1\MP3_H\Harry Chapin - Verities & Balderdash - 04 - 30,000 Pounds Of Bananas.mp3

Here is the relative path playlist contents from Excel:

\Dan Fogelberg - River of Souls - 08 - A Love Like This.mp3 \Harry Chapin - Verities & Balderdash - 04 - 30,000 Pounds Of Bananas.mp3

I execute the python code with the command line:

c:\temp>playlist.py playlist.m3u > playlistout.m3u

The program does generate an output file playlistout.m3u but it is blank or empty. I have really looked around and posted elsewhere about a solution, without success. I'm exhausted at this point. Anyone? Thanks.

sahasrara62
  • 10,069
  • 3
  • 29
  • 44
playhard
  • 1
  • 3

3 Answers3

1

You are calling this with

c:\temp>playlist.py playlist.m3u > playlistout.m3u

which redirects the stdout printed output of playlist.py to playlistout.m3u. However, in your program you aren't printing anything. Your program actually writes back into the original input file in these lines

fp = open(infile, "w")
for line in outlines:
    fp.write(line)
fp.close()

The way you're calling this program you would actually want to replace those lines with

for line in outlines:
    print(line)

You don't actually need to store the outlines and could rewrite the program to exclude that part but we'll save that for later.

If you want to make sure that you are producing anything in outlines at all you can do:

import sys
print("Number of lines to print: {}".format(len(outlines)), file=sys.stderr)
for line in outlines:
    print(line)
Nick Chapman
  • 4,402
  • 1
  • 27
  • 41
  • Nick C, more and more floundering on my part. I could list all the useless iterations of things I've done, with no success. Still hoping that you or anyone could help make what little I've furnished work. I accept spoon feeding. – playhard Dec 22 '18 at 22:30
  • I suspect that there are earlier problems in the script. I tried testing the line: else: outlines.append(os.path.relpath(line, basepath)).. As written, even that code seems faulty. I apologize for post here. Not familiar with the editing commands of the site. – playhard Dec 23 '18 at 14:20
  • @playhard edited with a tiny bit more instructions. After you think you've followed these instructions please post your updated code as an edit in your original question so I can see what you're doing. – Nick Chapman Dec 23 '18 at 18:56
  • Nick, I thought I added a comment responding to your reply. I solved my issue. See the below Answer I provided. I did leave open 1 additional question. I needed a little help in creating and/or pointing to a output file, in the body of the python script. Bill M. – playhard Dec 23 '18 at 23:35
0

This answer talks about the script code required to extract the relative path information from the absolute path information that is generally found in a playlist created by a stand alone media center file and database manager. Playlists can then be generated and exported, along with media files, to portable tablets and cellphones within a household.

I am answering my own question, as the originating poster. I have put in a lot of personal effort researching the question in the original post. Just seems like a lot of things came together, here recently. So, I furnished 2 answers on the same general question. Thanks. Bill M.

The below script is a very compact way to convert a playlist with full absolute path information to a playlist with minimal relative path information. I use a popular Android music player, except. It cannot decipher a standard .m3u playlist, when that playlist is created externally And when the playlist includes the full Drive and Folder path information that is generated by my home media center application. Note, other Android mp3 players apps didn't suffer this shortcoming, but they failed to impress me for other reasons. So, I needed a means to remove the absolute path information. Here are the initial conditions and the solution.

I have a file named playlist.m3u. It is plain text. The file contents are:

J:\NTFS_1\MP3_D\Dan Fogelberg - River of Souls - 08 - A Love Like This.mp3 
J:\NTFS_1\MP3_H\Harry Chapin - Verities & Balderdash - 04 - 30,000 Pounds Of Bananas.mp3

The above file reords are not recognized by my Android music player, because each line or record contains absolute path information, such as J:\NTFS_1\MP3_D and J:\NTFS_1\MP3_H. The above is only an example and there are additional absolute path folders for MP3_A, MP_B, etc., etc.

If I edit, or otherwise process the above lines either manually or with an Excel formula conversion, this needs to be the opening format of each record:

\Dan Fogelberg - River of Souls - 08 - A Love Like This.mp3
\Harry Chapin - Verities & Balderdash - 04 - 30,000 Pounds Of Bananas.mp3 

Here is a verbatim code snippet that I found here on Stackoverflow at the link: (Splitting path strings into drive, path and file name parts):

with open('C:/Users/visc/scratch/scratch_child/test.txt') as f:
    for line in f:
        drive, path = os.path.splitdrive(line)
        path, filename = os.path.split(path)
        print('Drive is %s Path is %s and file is %s' % (drive, path, filename))

Here is a reworked version that meets my requirements. I execute this from the DOS command line, so that I can direct the results to an output file, at the command line.

I named this script playlist.py. On the command line I enter:

C:\temp\playlist.py > output.m3u.

Here is playlist.py:

import sys
import os
with open('C:/temp/playlist.m3u') as f:
for line in f:
    drive, path = os.path.splitdrive(line)
    path, filename = os.path.split(path)
#   print('Drive is %s Path is %s and file is %s' % (drive, path, filename))
#   The original print adds spaces and such.  I removed the not necessary
#   Drive and Path fields.  Note, I Added a "\" 
    print('\%s' % (filename))

I tested the above at the command line. It produces an output file populated as required and shown above. I also tested the script in PyCharm Projects Community. PyCharm will produce the print output on screen. This agrees, of course, with the redirect output for the command line > output.m3u

I'm happy to have satisfied my curiosity and have a functional solution to the issue of the original post.

I could still use some help. What additional code will allow me to specify in the python script, where and to what named file I want the output printed to?

playhard
  • 1
  • 3
0

This answer talks primarily about script code that sends output to a specific local computer hard drive and folder. There are 2 answers that I have posted here. I am answering my own questions, as the originating poster. I have put in a lot of personal effort researching the question in the original post. Just seems like a lot of things came together, here recently. So, I furnished 2 answers on the same general question. Thanks. Bill M.

My previous answer stands as is and serves the purpose described. The script output location, in the earlier case, was a function of a command line statement variable. I noted this constraint. My preference was to be able to specify, within the python script itself, where the output file should be placed. After additional research, I have cobbled together a couple lines of code that make my needs complete. The product is spartan. Not very elegant. But it works for me. If I could have found a script that performed this directly, I would have used it. Maybe others will find it useful directly or indirectly.

So, in this second answer, to my own question, I have reworked some Stackoverflow code from another topic to allow for stipulating where the converted playlist output is placed.

The original code for handling how to redirect the output of print to a TXT file was found at the link How to redirect the output of print to a TXT file.

One of the responses by Eli Courtwright was ideal for this situation. Here are the pertinent code pieces that I extracted:

log = open("c:\\goat.txt", "w")
print >>log, "test"

Here is how I adapted them and (later) incorporated them for my situation

outfile = open("c:\\temp\goat.m3u", "w")
print >> outfile,('\%s' % (filename))

I changed from:log to:outfile. I modified my earlier print command to now point to outfile, which previously was associated with my preferred local hard drive location. Note the use of the double rear facing slashes.

Finally, here is the complete 9 lines of code required to read an absolute path playlist, then convert and generate a new playlist file for my Android mp3 player application.

# Python Script to extract playlist relative folder path and names
# Script removes local storage absolute path info from playlist records.

import sys
import os

outfile = open("c:\\temp\goat.m3u", "w")
f = open('output.txt','w')


with open('C:/temp/playlist.m3u') as f:
    for line in f:
        drive, path = os.path.splitdrive(line)
        path, filename = os.path.split(path)
        # Note the '\' in the print command.  Need this because the
        # previous operation removes any/all path info.  This 1 '\'
        # is required to be restored
        print >> outfile,('\%s' % (filename))

That's all I have. I'm thinking I can still write a batch file like "convert.bat" where I can drop my original playlist.m3u file and have it execute the python script directly, instead of running it from PyCharm or the Command Line. But that's another day. Merry Christmas.

playhard
  • 1
  • 3