【问题标题】:Trying to Convert an Absolute .m3u Path to a Relative .m3u Path尝试将绝对 .m3u 路径转换为相对 .m3u 路径
【发布时间】:2019-05-22 17:01:44
【问题描述】:

我正在尝试从我的 playlist.m3u 文件中删除绝对路径信息,并使用 Python 将此文件转换为相对路径。我可以使用连接的 Excel 脚本来做到这一点,而且效果很好,但我认为 Python 路线会更容易。

这是我一直试图开始工作的脚本,但没有成功。

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()

这里是绝对路径播放列表文件内容的示例:

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

这是来自 Excel 的相对路径播放列表内容:

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

我用命令行执行python代码:

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

程序确实生成了一个输出文件playlistout.m3u,但它是空白或空的。我确实环顾四周并在其他地方发布了有关解决方案的信息,但没有成功。在这一点上我已经筋疲力尽了。任何人?谢谢。

【问题讨论】:

    标签: python


    【解决方案1】:

    此答案讨论了从绝对路径信息中提取相对路径信息所需的脚本代码,该绝对路径信息通常在由独立媒体中心文件和数据库管理器创建的播放列表中找到。然后可以生成播放列表并将其与媒体文件一起导出到家庭中的便携式平板电脑和手机。

    作为发帖人,我正在回答我自己的问题。我已经付出了很多个人努力来研究原始帖子中的问题。好像很多事情都在一起了,最近在这里。所以,我就同一个一般性问题提供了 2 个答案。谢谢。比尔 M.

    下面的脚本是一种非常紧凑的方法,可以将具有完整绝对路径信息的播放列表转换为具有最少相对路径信息的播放列表。我使用流行的 Android 音乐播放器,但除外。它无法破译标准的 .m3u 播放列表,当该播放列表是在外部创建的并且播放列表包含由我的家庭媒体中心应用程序生成的完整驱动器和文件夹路径信息时。请注意,其他 Android mp3 播放器应用程序没有遇到这个缺点,但由于其他原因它们未能给我留下深刻印象。所以,我需要一种方法来删除绝对路径信息。这是初始条件和解决方案。

    我有一个名为 playlist.m3u 的文件。它是纯文本。文件内容为:

    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
    

    我的Android音乐播放器无法识别上述文件记录,因为每一行或记录都包含绝对路径信息,例如J:\NTFS_1\MP3_D和J:\NTFS_1\MP3_H。以上仅为示例,MP3_A、MP_B等还有额外的绝对路径文件夹。

    如果我手动或使用 Excel 公式转换编辑或以其他方式处理上述行,则这需要是每条记录的开头格式:

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

    这是我在 Stackoverflow 上的链接中找到的逐字代码 sn-p:(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))
    

    这是一个符合我要求的重新设计的版本。我从 DOS 命令行执行此操作,以便可以在命令行将结果定向到输出文件。

    我将此脚本命名为 playlist.py。在命令行我输入:

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

    这里是 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))
    

    我在命令行中测试了上述内容。它会生成一个根据需要填充的输出文件,如上所示。我还在 PyCharm 项目社区中测试了脚本。 PyCharm 将在屏幕上生成打印输出。当然,这与命令行的重定向输出一致 > output.m3u

    我很高兴满足了我的好奇心,并为原始帖子的问题提供了实用的解决方案。

    我仍然可以使用一些帮助。哪些额外的代码允许我在 python 脚本中指定我希望将输出打印到的位置和命名文件?

    【讨论】:

      【解决方案2】:

      此答案主要讨论将输出发送到特定本地计算机硬盘驱动器和文件夹的脚本代码。我在这里发布了 2 个答案。作为发帖人,我正在回答我自己的问题。我已经付出了很多个人努力来研究原始帖子中的问题。好像很多事情都在一起了,最近在这里。所以,我就同一个一般性问题提供了 2 个答案。谢谢。比尔 M.

      我之前的回答保持原样,并达到所描述的目的。在前面的例子中,脚本输出位置是命令行语句变量的函数。我注意到了这个限制。我的偏好是能够在 python 脚本本身中指定输出文件的放置位置。经过进一步的研究,我拼凑了几行代码来满足我的需求。该产品是斯巴达式的。不是很优雅。但它对我有用。如果我能找到一个直接执行此操作的脚本,我会使用它。也许其他人会直接或间接地发现它有用。

      因此,在第二个答案中,对于我自己的问题,我从另一个主题重新编写了一些 Stackoverflow 代码,以允许规定转换后的播放列表输出的放置位置。

      处理如何将 print 的输出重定向到 TXT 文件的原始代码可在链接 How to redirect the output of print to a TXT file 中找到。

      Eli Courtwright 的其中一个回答非常适合这种情况。以下是我提取的相关代码片段:

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

      这是我如何调整它们并(后来)根据我的情况合并它们

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

      我从:log 更改为:outfile。我将之前的打印命令修改为现在指向 outfile,该文件之前与我首选的本地硬盘驱动器位置相关联。请注意使用双后斜线。

      最后,这是读取绝对路径播放列表所需的完整 9 行代码,然后为我的 Android mp3 播放器应用程序转换并生成新的播放列表文件。

      # 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))
      

      这就是我所拥有的。我想我仍然可以编写一个像“convert.bat”这样的批处理文件,我可以在其中删除我原来的 playlist.m3u 文件并让它直接执行 python 脚本,而不是从 PyCharm 或命令行运行它。但那是另一天。圣诞快乐。

      【讨论】:

        【解决方案3】:

        你用

        来调用它
        c:\temp>playlist.py playlist.m3u > playlistout.m3u
        

        playlist.pystdout 打印输出重定向到playlistout.m3u。但是,在您的程序中,您没有打印任何内容。您的程序实际上会在这些行中写回原始输入文件

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

        你调用这个程序的方式你实际上想用这些行替换

        for line in outlines:
            print(line)
        

        您实际上不需要存储轮廓,并且可以重写程序以排除该部分,但我们将保存它以备后用。

        如果您想确保在大纲中生成任何内容,您可以这样做:

        import sys
        print("Number of lines to print: {}".format(len(outlines)), file=sys.stderr)
        for line in outlines:
            print(line)
        

        【讨论】:

        • 尼克 C,我越来越挣扎了。我可以列出我所做的所有无用的迭代,但没有成功。仍然希望您或任何人可以帮助完成我提供的少量工作。我接受勺子喂食。
        • 我怀疑脚本中存在早期问题。我尝试测试该行: else: outlines.append(os.path.relpath(line, basepath)).. 正如所写的那样,即使该代码似乎也有问题。我为在这里发帖道歉。不熟悉网站的编辑命令。
        • @playhard 编辑了更多指令。在您认为您已按照这些说明进行操作后,请将更新后的代码作为编辑发布在您的原始问题中,以便我看到您在做什么。
        • 尼克,我想我添加了一条评论来回应你的回复。我解决了我的问题。请参阅我提供的以下答案。我确实留下了 1 个额外的问题。在 python 脚本的主体中,我需要一些帮助来创建和/或指向输出文件。比尔 M.
        猜你喜欢
        • 2017-08-01
        • 2011-11-07
        • 2011-05-02
        • 2016-12-14
        相关资源
        最近更新 更多