使用runcmd

问题描述

我正在尝试获取此代码,以从提及我的Twitter句柄的任何推文中提取媒体,通过子流程模块使用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,tweetId)

但我总是最终会收到此错误:

Exception has occurred: TypeError
runcmd() takes 1 positional argument but 3 were given
   tweet_photo = runcmd('ffmpeg -i','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','output.jpg')

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...