V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

如何通过 Python 调用 potplayer 的 exe 来播放某个音频?

  •  
  •   amiwrong123 · 178 天前 · 1869 次点击
    这是一个创建于 178 天前的主题,其中的信息可能已经有所发展或是发生改变。

    环境:window10.

    import subprocess  
    import os  
    main = "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe"
    if os.path.exists(main):  
        rc,out= subprocess.getstatusoutput(main)  
        print (rc)
        print ('*'*10)
        print (out)
    

    通过上面的代码是可以打开 potplayer ,但也就只是打开 空白的 potplayer ,并不会播放某个音频。

    然后我这么改:

    main = "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe 1.wav"
    
    

    1.wav 是和这个 python 脚本同目录的一个音频,但是这么运行就不好使了,potplayer 没有被打开。

    (之所以要写这个脚本,是因为音频有很多个,放在不同的地方,我需要通过 py ,输入一个字符串来找到特定的音频,再用 potplayer 来播放)

    27 条回复    2021-12-29 03:26:56 +08:00
    chengyiqun
        1
    chengyiqun  
       178 天前
    可以通过 bat 脚本理解决.
    我以前写了一个换壁纸的 python 脚本, 用到了批处理.
    python 里:
    https://paste.org.cn/kzILLcm6wI

    bat 里:
    https://paste.org.cn/E1QrRgtbnB

    bat 里的 "%1" 就是 python 脚本里 run(['setWallpaper.bat', file_path]) 这句里的 file_path
    这个数组可以添加更多参数, 依次加 %2 %3 之类的. %0 就是脚本本身了.

    可以参考下.
    minami
        2
    minami  
       178 天前
    PotPlayerMini64.exe 1.wav /same
    chengyiqun
        3
    chengyiqun  
       178 天前
    python 脚本完整版我也贴出来吧
    https://paste.org.cn/J4HcMJD5Dn

    raw_img_url 已经失效. 暂时懒得弄换壁纸了. 提供个新的地址就行了.

    我这个脚本是用 windows 任务计划程序每天中午运行一次的. 现在不用了.
    cccer
        4
    cccer  
       178 天前
    可以用绝对路径试试,PotPlayerMini64 运行的工作目录不一定和 python 脚本的工作目录一致。
    ahhui
        5
    ahhui  
       178 天前
    main = "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe 1.wav"
    这个命令行是不合法的,"是字符串边界,所以等效于你传给系统的命令是:
    C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe 1.wav
    由于空格是进程和参数的分隔符,所以系统会认为你要调用的是 C:\Program 这个程序,给的参数是 Files\DAUM\PotPlayer\PotPlayerMini64.exe 1.wav
    你可以开个 cmd ,直接这样输入一下看看就知道了
    所以正确的做法是

    main = """C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe"" 1.wav"

    我不确定 Python 下双写""是否代表单个的",如果不是,你需要找到一个正确的写法。反正这样的字符串才是正确的命令行:

    "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" 1.wav
    zsedc
        6
    zsedc  
       178 天前
    用 url scheme ?
    ```
    import webbrowser
    webbrowser.open_new('potplayer://路径或 url potplayer://file:///D:/path/to/video.wav')
    ```
    kidonng
        7
    kidonng  
       178 天前
    @ahhui 把空格转移掉就行吧
    kidonng
        8
    kidonng  
       178 天前
    转移 -> 转义
    killva4624
        9
    killva4624  
       178 天前
    搜了一下还有人基于 subprocess.Popen 写了个 potplayer 的 SDK 哈哈哈
    https://github.com/MacHu-GWU/potplayer-project
    amiwrong123
        10
    amiwrong123  
    OP
       178 天前
    @cccer #4
    @ahhui #5
    在 cmd 终端里,运行"C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" "C:\1.wav",是可以的。会调用 potplayer 然后播放 wav 。

    但是我执行 python 代码
    import subprocess
    import os
    main=" \"C:\\Program Files\\DAUM\\PotPlayer\\PotPlayerMini64.exe\" \"C:\\1.wav\" "
    if os.path.exists(main):
    rc,out= subprocess.getstatusoutput(main)
    print (rc)
    print ('*'*10)
    print (out)

    print(main)

    缺不好使,我佛了。这是怎么回事。print(main)打印出来就是"C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" "C:\1.wav"
    28ms
        11
    28ms  
       178 天前 via iPhone
    我不清楚 potplayer 是不是功能里的刚需,如果不是刚需可以替换成 vlc ,后者有全套的 python binding ,可以玩出花来。popen 这种调用连暂停都实现不了。
    cccer
        12
    cccer  
       178 天前   ❤️ 1
    没有显示是因为 if os.path.exists(main) 这个判断,你的 main 里面根本不是一个路径,而是命令,至于空格转义可以参考我这个。
    ```
    main = r'"C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" "D:\Downloads\1.mp4"'

    # if os.path.exists(main):
    rc, out = subprocess.getstatusoutput(main)
    print(rc)
    print('*' * 10)
    print(out)
    ```
    amiwrong123
        13
    amiwrong123  
    OP
       178 天前
    @chengyiqun #1
    所以 python 脚本和 bat 脚本在同一个目录呗。


    然后我试了一下 bat 脚本:
    @echo off
    start "" "C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe" "C:\1.wav"
    发现是可以用,所以我应该把 "C:\1.wav" 替换为 "%1"呗?


    另外,本着不懂就问的原则,为啥 start 要跟个"" 呢,我百度了说是为了打开新窗口,但我试了,加不加都是可以的呢?
    ahhui
        14
    ahhui  
       178 天前
    @kidonng 移掉空格是不行的,因为移掉空格,那么 ProgramFiles 目录名就不存在了,这个目录确实有个空格。
    ahhui
        15
    ahhui  
       178 天前
    @amiwrong123 直接帮你 Google 了下,正确的 python 写法应该是这样的:

    import subprocess
    subprocess.run(["C:\Program Files\DAUM\PotPlayer\PotPlayerMini64.exe", "C:\1.wav"])
    ysc3839
        16
    ysc3839  
       178 天前
    subprocess.run(['C:\\Program Files\\PotPlayer\\PotPlayerMini64.exe', 'test.mkv'])
    这样并没有问题。

    似乎直到 12 楼才有人意识到是 os.path.exists(main) 导致的问题。
    再者,Python 本来就有提供自动帮你处理好命令行参数转义的 subprocess.run() 函数,不知道为什么不用这个,而去用那些更麻烦的函数。
    amiwrong123
        17
    amiwrong123  
    OP
       178 天前
    @cccer #12
    啊,我太笨了,原来如此,见笑了😂
    hpencilb
        18
    hpencilb  
       178 天前 via iPhone
    sunprocess.run 为了防止命令注入默认 shell=False ,一个字符串会被当作一个命令,你要传多个参数进去尽量用元组或者列表,真要字符串传需要增加 shell=True
    ysc3839
        19
    ysc3839  
       178 天前   ❤️ 1
    @hpencilb Windows 和 Unix 不同,进程参数是一个字符串,Unix 则是字符串数组。在 Unix 下需要 shell=True 是因为需要 shell 来把字符串解析成字符串数组,但是 Windows 下不需要。

    subprocess.run('"C:\\Program Files\\PotPlayer\\PotPlayerMini64.exe" test.mkv', shell=False)
    这样也是没问题的。
    mingl0280
        20
    mingl0280  
       178 天前 via Android
    python 程序员连程序与调用参数都分不清了么?你不分开成两个部分当然就视为一个完整的路径,你问 Python 要个叫“PotPlayerMini64.exe 1.wav”的文件凭什么 Python 要告诉你有?
    hpencilb
        21
    hpencilb  
       178 天前 via iPhone
    @ysc3839 试了一下确实,学到了
    mingl0280
        22
    mingl0280  
       178 天前 via Android
    @hpencilb 并不是这样的
    ctro15547
        23
    ctro15547  
       178 天前
    一定要用规定的 exe 来播放音频么,py 本身有开源库能够播音频 ,之前工作中有用到,效果挺不错的
    amiwrong123
        24
    amiwrong123  
    OP
       178 天前
    @ysc3839 #19
    那岂不是说,Windows 下,不需要使用到 shell=True 了呗
    amiwrong123
        25
    amiwrong123  
    OP
       178 天前
    @ctro15547 #23
    也不是一定要用 potplayer ,只是电脑刚好有这个软件
    CallMeReznov
        26
    CallMeReznov  
       178 天前
    把这个贴子看完,发现 process 就该把 args 关键字删掉,根本没用.
    ysc3839
        27
    ysc3839  
       178 天前 via Android
    @amiwrong123 具体看需求,一般来说我建议用 subprocess.run 传数组进去,因为 Python 会自动处理命令行转义。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2395 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:35 · PVG 13:35 · LAX 22:35 · JFK 01:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.