鱼C论坛

 找回密码
 立即注册
查看: 2071|回复: 14

[已解决]python打包exe问题

[复制链接]
发表于 2022-1-3 01:58:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
使用pydub库写了一个音频转换的小程序,因为要调用ffmpeg,加了环境变量,直接IDLE跑没有问题,但是打包成exe之后就无法调用ffmpeg进行转换了。
不知道有没有人遇到了类似的情况,求帮助。  谢谢了!
最佳答案
2022-1-3 16:46:11
本帖最后由 isdkz 于 2022-1-3 17:04 编辑
泛舟海上 发表于 2022-1-3 16:18
谢了,这样也不行,后面研究下pydub的代码了,调用是它做的,感觉得指定它的调用路径


我拿你的代码试过了,是可以的

不过有一个问题,如果你是目录打包的话可以用os.getcwd()来拼接绝对路径,因为你的可执行文件就是跟bin在一个目录下。

但是你是文件打包就不可以了,因为你的可执行文件没有跟bin在一个目录,文件打包的方式其实运行的时候它也会解压一个临时目录出来的,你可以在资源管理器导航栏输%temp%进去查看

python因为要导包的原因,它会自动把这个路径加入sys.path的

所以,总的来说,你要用-F打包的话,你可以先import sys,然后添加环境变量改成   os.environ['PATH']=sys.path[-1]+'\\bin'+os.pathsep+os.environ['PATH']   这样打包后问题就可以解决了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-1-3 01:58:46 | 显示全部楼层
打包用的pyinstaller,环境是同一台电脑测试的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 02:31:00 From FishC Mobile | 显示全部楼层
调用ffmpeg的时候写相对路径,ffmpeg放主脚本同一目录下,在主脚本中用ffexec = os.getcwd() + "ffmpeg.exe"获取ffmpeg路径,如果有子脚本,在子脚本中调用ffmpeg,那子脚本要通过从主脚本取得ffexec变量的值的方式取得ffmpeg的路径。打包后,ffmpeg放在exe同目录下就可以了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 11:13:37 | 显示全部楼层
hrpzcf 发表于 2022-1-3 02:31
调用ffmpeg的时候写相对路径,ffmpeg放主脚本同一目录下,在主脚本中用ffexec = os.getcwd() + "ffmpeg.exe ...

我想过这种方式,但是它是pydub这个库里调用的exe,我路径要去改库函数写进去,然后再import进来用?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 11:56:18 From FishC Mobile | 显示全部楼层
本帖最后由 hrpzcf 于 2022-1-3 12:15 编辑

我看了一下pydub的源码,他是通过系统环境变量找到ffmpeg的,你可以在你自己的脚本中调用pydub功能之前修改临时环境变量就可以了:
  1. os.environ["PATH"] = "你的ffmpeg所在的目录路径" + os.pathsep + os.environ["PATH"]
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 12:15:02 | 显示全部楼层
hrpzcf 发表于 2022-1-3 11:56
我不了解pydub,它是通过什么方式找到ffmpeg的?它集成了的ffmpeg还是通过系统环境变量找到本机的ffmpeg?

是通过环境变量找的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 12:15:30 | 显示全部楼层
泛舟海上 发表于 2022-1-3 12:15
是通过环境变量找的

楼上修改了,你看下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 12:17:40 | 显示全部楼层
hrpzcf 发表于 2022-1-3 12:15
楼上修改了,你看下

好的,谢谢,我试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 12:39:36 | 显示全部楼层
依旧不行,算了,后面再想办法试试吧,先继续学了,自己用起来直接idle先用着,下边是代码
  1. from pydub import AudioSegment
  2. from tkinter import *
  3. import tkinter.filedialog as tf
  4. from tkinter import ttk
  5. import os




  6. #转换函数
  7. def trans_mp3_to_every(filepath,filepath_n,geshi_o,geshi):
  8.     name='AudioSegment.from_'+geshi_o #参数名
  9.     #print(name)
  10.     #eval转换动态字符串为方法
  11.     song=eval(name)(filepath)
  12.    # print(filepath_n+'.'+geshi)
  13.     song.export(filepath_n+'.'+geshi,format=geshi)



  14. def main():
  15.     #增加临时系统变量
  16.     os.environ['PATH']=os.getcwd()+'\\bin'+os.pathsep+os.environ['PATH']


  17.     root=Tk()

  18.     root.title('转换音频')
  19.     root.geometry('338x200')

  20.     group =LabelFrame(root)
  21.     group.grid(padx=5,pady=5)

  22.     #选择待转换的文件
  23.     Label(group,text='原文件:').grid(row=0,padx=5,pady=5,sticky=E)
  24.     route_old=Entry(group)
  25.     route_old.grid(row=0,column=1,padx=5,pady=5)
  26.    
  27.     def getroute_old():
  28.         route_old.insert(0,tf.askopenfilename())

  29.         
  30.     Button(group,text='选择文件',command=getroute_old)\
  31.     .grid(row=0,column=2,padx=5,pady=5)

  32.     #选择目标保存的文件夹
  33.     Label(group,text='目标文件夹:').grid(row=1,padx=5,pady=5,sticky=E)
  34.     route_new=Entry(group)
  35.     route_new.grid(row=1,column=1,padx=5,pady=5)
  36.     def getroute_new():
  37.         route_new.insert(0,tf.askdirectory())
  38.     Button(group,text='选择文件夹',command=getroute_new)\
  39.     .grid(row=1,column=2,padx=5,pady=5)

  40.     #目标格式,设置下拉列表选择
  41.     Label(group,text='目标格式:').grid(row=2,padx=5,pady=5,sticky='e')
  42.     value=StringVar()
  43.     value.set('ogg')
  44.     values=['mp3','ogg','wav','aiff']
  45.     geshi=ttk.Combobox(group,height=14,width=15,state='readonly'\
  46.                        ,cursor='arrow',textvariable=value,values=values)
  47.     geshi.grid(row=2,column=1,padx=5,pady=5,sticky='w')

  48.     #定义选择列表事件,列表值设置为当前选中值
  49.     def choose(event):
  50.         value.set(value.get())

  51.      #列表绑定选中事件   
  52.     geshi.bind('<<ComboboxSelected>>',choose)



  53.     #转换文件
  54.     def transfile():
  55.         geshi_o=route_old.get().split('.')[-1]
  56.         filename_o=(route_old.get().split('/')[-1]).split('.')[0]
  57.         trans_mp3_to_every(route_old.get(),route_new.get()+'/'+filename_o,\
  58.                            geshi_o,geshi.get())

  59.    

  60.     Button(group,text='开始转换',command=transfile).\
  61.                                                  grid(row=3,columnspan=3,pady=20)

  62.     mainloop()


  63. if __name__=='__main__':
  64.     main()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 14:36:06 | 显示全部楼层
本帖最后由 isdkz 于 2022-1-3 14:37 编辑
泛舟海上 发表于 2022-1-3 12:39
依旧不行,算了,后面再想办法试试吧,先继续学了,自己用起来直接idle先用着,下边是代码


你用pyinstaller打包的话,可以加一个  --add-data=bin;bin  (--add-data=打包前的路径;打包后相对于项目的路径) 将ffmpeg给打包进去,也可以用pyi-makespec test.py文件生成.spec文件后,再修改.spec文件里面的datas选项,然后用pyinstaller test.spec打包。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 16:18:55 | 显示全部楼层
isdkz 发表于 2022-1-3 14:36
你用pyinstaller打包的话,可以加一个  --add-data=bin;bin  (--add-data=打包前的路径;打包后相对于项 ...

谢了,这样也不行,后面研究下pydub的代码了,调用是它做的,感觉得指定它的调用路径
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 16:46:11 | 显示全部楼层    本楼为最佳答案   
本帖最后由 isdkz 于 2022-1-3 17:04 编辑
泛舟海上 发表于 2022-1-3 16:18
谢了,这样也不行,后面研究下pydub的代码了,调用是它做的,感觉得指定它的调用路径


我拿你的代码试过了,是可以的

不过有一个问题,如果你是目录打包的话可以用os.getcwd()来拼接绝对路径,因为你的可执行文件就是跟bin在一个目录下。

但是你是文件打包就不可以了,因为你的可执行文件没有跟bin在一个目录,文件打包的方式其实运行的时候它也会解压一个临时目录出来的,你可以在资源管理器导航栏输%temp%进去查看

python因为要导包的原因,它会自动把这个路径加入sys.path的

所以,总的来说,你要用-F打包的话,你可以先import sys,然后添加环境变量改成   os.environ['PATH']=sys.path[-1]+'\\bin'+os.pathsep+os.environ['PATH']   这样打包后问题就可以解决了

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
ciwmy + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-3 21:44:46 | 显示全部楼层
isdkz 发表于 2022-1-3 16:46
我拿你的代码试过了,是可以的

不过有一个问题,如果你是目录打包的话可以用os.getcwd()来拼接绝对 ...

感谢,用-D打包解决了,-F加了这个环境变量还是有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-3 22:24:08 | 显示全部楼层
本帖最后由 isdkz 于 2022-1-3 22:27 编辑
泛舟海上 发表于 2022-1-3 21:44
感谢,用-D打包解决了,-F加了这个环境变量还是有问题


默认就是-D的,-F我在这边也调试了把os.getcwd()换成 sys.path[-1] 是可以的,它把它解压后的路径加在了sys.path的最后,你可以到 %temp%(windows的临时文件夹下类似_MEI117762这种命名的文件夹里查看一下看看你的bin目录有没有打包进去了)你打包先不要隐藏那个控制台窗口,方便调试,可以print一下sys.path,调试成功后再隐藏控制台窗口打包

                               
登录/注册后可看大图


                               
登录/注册后可看大图


                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-28 12:10:11 | 显示全部楼层
考古
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 23:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表