从Python执行子进程
我觉得在我尝试从Python脚本中执行一个子进程时,可能出现了一些微妙的问题。
我想用很多参数来执行vlc这个程序。
结果启动的vlc实例却报错了:
你的输入无法打开:
VLC无法打开这个地址 ' -vvv rtsp://192.168.1.201:554/ch0_multicast_one --sout=#transcode{acodec=none}:duplicate{dst=rtp{sdp=rtsp://:5544/user_hash.sdp},dst=display} :no-sout-rtp-sap :no-sout-standard-sap :ttl=1 :sout-keep'。请查看日志以获取更多细节。
这是我的Python代码:
pid = subprocess.Popen(["vlc "," -vvv rtsp://%s" % target_nvc.ip_address + ":554/ch0_multicast_one --sout=#transcode{acodec=none}:duplicate{dst=rtp{sdp=rtsp://:5544/user_hash.sdp},dst=display} :no-sout-rtp-sap :no-sout-standard-sap :ttl=1 :sout-keep" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
我检查了子进程函数的输出(使用了shell),如果我把那个字符串复制粘贴到命令行窗口,vlc实例就能正常工作……这是不是权限的问题呢?
3 个回答
在编程中,有时候我们需要处理一些数据,这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解这些数据,我们通常需要将它们转换成一种程序能处理的格式。
比如说,如果你从一个网页上获取了一些信息,这些信息可能是以文本的形式存在的。为了让程序能够使用这些信息,我们需要把它们转化为程序能够识别的格式,比如数字、列表或者字典等。
这个过程就叫做“数据解析”。简单来说,就是把复杂的东西变得简单易懂,让程序能够顺利地使用这些数据。
在实际操作中,我们可能会用到一些工具或者库来帮助我们完成这个解析的工作。这样可以节省时间,也能减少出错的机会。
总之,数据解析就是让程序能够理解和使用我们提供的数据的一个重要步骤。
movies_path = glob.glob("D:\\MOVIES\**\*\*\*.mp4", recursive=True) + \
glob.glob("D:\\MOVIES\**\*\*\*.mkv", recursive=True) + \
glob.glob("D:\\MOVIES\**\*\*\*.avi", recursive=True)
# probably the right movie
rightMoviePath = difflib.get_close_matches(which_movie, movies_path, len(movies_path), 0)
movie_name = rightMoviePath[0].split("\\")[-1]
hebrew_subtitle_path = glob.glob(rightMoviePath[0].replace(movie_name, "Hebrew.srt"))[0]
english_subtitle_path = glob.glob(rightMoviePath[0].replace(movie_name, "English.srt"))[0]
process, player = subprocess.Popen(["C:\\Users\\yonat\\Downloads\\VLC\\vlc.exe", "--sub-file", hebrew_subtitle_path, rightMoviePath[0]],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
因为你是把一个列表传给subprocess.Popen
,所以每个参数必须放在它自己的元素里。你应该像这样写:
pid = subprocess.Popen([
"vlc",
"-vvv",
"rtsp://%s:554/ch0_multicast_one" % target_nvc.ip_address,
# etc
], ...)
每个参数(通常是由命令行解析的)必须放在不同的列表元素中。
你也可以传一个完整的命令行字符串,让命令行自己来解析:
pid = subprocess.Popen("vlc -vvv rtsp://...", shell=True, ...)
第一种写法更适合那些有很多参数的命令。
你应该使用这个...
pid = subprocess.Popen(["vlc", "-vvv",
"rtsp://%s" % target_nvc.ip_address + ":554/ch0_multicast_one",
"--sout=#transcode{acodec=none}:duplicate{dst=rtp{sdp=rtsp://:5544/user_hash.sdp},dst=display}",
":no-sout-rtp-sap", ":no-sout-standard-sap",
":ttl=1", ":sout-keep" ], stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE)