使用 runcmd 提取推文信息时出现问题

Problem extracting tweet info with runcmd

我正在尝试获取此代码以从任何提及我的推特句柄的推文中提取媒体,通过子进程模块使用 ffmpeg 对其进行转换,然后将转换后的媒体作为回复发送回此人。

import tweepy
from tweepy import Stream
from tweepy.streaming import StreamListener
from datetime import datetime
import time
import subprocess

stdout = subprocess.PIPE
def runcmd(cmd):
    x = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    return x.communicate(stdout)

import json
import random

class StdOutListener(StreamListener):
    def on_data(self, data):
        clean_data = json.loads(data)
        tweetId = clean_data['id']
        tweet_name = clean_data['user']['screen_name']
        tweet_media = clean_data['entities']['media'][0]['media_url']
        print(tweet_media)
        tweet_photo = runcmd('ffmpeg -i', tweet_media, 'output.jpg')
        tweet = 'Here ya go'
        now = datetime.now()
        dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
        print(' Reply sent to @'+tweet_name, 'on', dt_string, '\n' ' Message:', tweet, '\n')
        respondToTweet(tweet_media, tweet, tweetId)

但我总是得到这个错误:

Exception has occurred: TypeError
runcmd() takes 1 positional argument but 3 were given
   tweet_photo = runcmd('ffmpeg -i', tweet_media, 'output.jpg')

很明显,我不能将 tweet_media 放在 ffmpeg -ioutput.jpg 之间,那么我该如何正确转换 tweet_media

基于this answer,如果你想保持通话原样,你需要这样的东西:

def runcmd(*cmd):
    x = subprocess.Popen([*cmd], stdout=subprocess.PIPE)
    return x.communicate(stdout)

另见 the official documentation on Arbitrary Argument Lists

进一步说明:Popen() 将命令 运行 作为单词列表。因此,有两个 Python 特征要使用。

  1. def runcmd(*cmd): 这表示该函数采用任意参数列表,并将它们作为元组存储在 cmd 中,因此调用 runcmd('ffmpeg', '-i', tweet_media, 'output.jpg') 会导致 cmd 等于 ('ffmpeg', '-i', tweet_media, 'output.jpg').

  2. Popen 将表示 运行 命令的字符串列表作为第一个参数。因此,首先 *cmd 将元组展开为元素,然后 [*cmd] 将元素放入列表中,因此我们得到了所需的调用 ['ffmpeg', '-i', tweet_media, 'output.jpg'].

注意:将 'ffmpeg -i' 指定为列表的第一个元素会使 Popen 搜索名为 ffmpeg<SPACE>-i 的可执行文件,这很可能将不存在,因此您应该改用 'ffmpeg', '-i'