类型错误:__init__() 缺少 2 个必需的位置参数:'stdout' 和 'stderr'

问题描述 投票:0回答:1

我在运行程序

extract_frame_and_wav_multiprocess.py
时遇到以下错误,该程序旨在从数据集
MSRVTT
中的视频中提取音频和帧。 这是程序的错误消息:

(valor) xxx:/VALOR/utils$ python extract_frame_and_wav_multiprocess.py                                                                                                                                                                           
0%|                                       | 0/10005 [00:00<?, ?it/s]
Exception in thread Thread-3:                                                                                                                                                      
Traceback (most recent call last):                                                                                                                                                   
File "/anaconda3/envs/valor/lib/python3.9/threading.py", line 973, in _bootstrap_inner                                                    
self.run()                                                                                                                                                                       
File "/anaconda3/envs/valor/lib/python3.9/threading.py", line 910, in run                                                                                          
self._target(*self._args, **self._kwargs)                                                                                                                                        
File "/anaconda3/envs/valor/lib/python3.9/multiprocessing/pool.py", line 576, in _handle_results                                                                   
task = get()                                                                                                                                                                     
File "/anaconda3/envs/valor/lib/python3.9/multiprocessing/connection.py", line 256, in recv                                                                        
return _ForkingPickler.loads(buf.getbuffer())                                                                                                                                  
TypeError: __init__() missing 2 required positional arguments: 'stdout' and 'stderr'   

这是错误消息指示的位置(在文件

/anaconda3/envs/valor/lib/python3.9/multiprocessing/connection.py
中):

    def recv(self):
        """Receive a (picklable) object"""
        self._check_closed()
        self._check_readable()
        buf = self._recv_bytes()
        return _ForkingPickler.loads(buf.getbuffer())

以下程序是正在执行的python程序

extract_frame_and_wav_multiprocess.py

import os
import os.path as P
import ffmpeg
import json
import tqdm
import numpy as np
import threading
import time
import multiprocessing
from multiprocessing import Pool
import subprocess



### change diffenrent datasets
input_path = '../datasets/msrvtt/raw_videos'
output_path = '../datasets/msrvtt/testt'
data_list = os.listdir(input_path)

def execCmd(cmd):
    r = os.popen(cmd)
    text = r.read()
    r.close()
    return text

def pipline(video_path, video_probe, output_dir, fps, sr, duration_target):
    video_name = os.path.basename(video_path)
    audio_name = video_name.replace(".mp4", ".wav")
    video_name = video_name.replace(".mp4", "")


    #extract video frames fps
    fps_frame_dir = P.join(output_dir, f"frames_fps{fps}", video_name)
    os.makedirs(fps_frame_dir, exist_ok=True)
    cmd = "ffmpeg -loglevel error -i {} -vsync 0 -f image2 -vf fps=fps={:.02f} -qscale:v 2 {}/frame_%04d.jpg".format(
              video_path, fps, fps_frame_dir)
    subprocess.call(cmd, shell=True)

    # Extract Audio
    sr_audio_dir = P.join(output_dir,f"audio_{sr}hz")
    os.makedirs(sr_audio_dir, exist_ok=True)
    audio_file_path = P.join(sr_audio_dir, audio_name)
    cmd = "ffmpeg -i {} -loglevel error -f wav -vn -ac 1 -ab 16k -ar {} -y {}".format(
            video_path, sr, audio_file_path)
    subprocess.call(cmd, shell=True)


def extract_thread(video_id):
    
    video_name = os.path.join(input_path, video_id)
    if not os.path.exists(video_name):
        return
    probe = ffmpeg.probe(video_name)
    pipline(video_name, probe, output_path, fps=4, sr=22050, duration_target=10)


def extract_all(video_ids, thread_num, start):
    length = len(video_ids)
    print(length)
    with Pool(thread_num) as p:
        list(tqdm.tqdm(p.imap(extract_thread, video_ids), total=length))

if __name__=='__main__':
    thread_num = 50
    start = 0

    print(len(data_list))
    extract_all(data_list, thread_num, start)

奇怪的是,在处理

DiDeMo
视频数据集时没有出现类似的错误,但在处理
MSRVTT
数据集时却遇到了。 (这与
DiDeMo
数据集没有音频有关吗?)

python python-3.x video ffmpeg typeerror
1个回答
0
投票

由于Python等依赖的版本兼容性问题,在

subprocess.Popen
模块内调用
ffmpeg.probe
时,即使我们输入了stdout、stderr等参数,仍然会抛出stdout缺失等错误。因此,我们省略了使用
ffmpeg.probe
命令记录信息的步骤。
我们可以更改原来的代码:

    probe = ffmpeg.probe(video_name)
    pipline(video_name, probe, output_path, fps=1, sr=22050, duration_target=10)

进入以下代码:

    # probe = ffmpeg.probe(video_name)
    pipline(video_name, None, output_path, fps=1, sr=22050, duration_target=10)
© www.soinside.com 2019 - 2024. All rights reserved.