记录未知长度的数据时如何修复错误?

Posted

技术标签:

【中文标题】记录未知长度的数据时如何修复错误?【英文标题】:how to fix Error while recording data of unknown length? 【发布时间】:2018-04-26 13:34:11 【问题描述】:

我正在尝试从我的麦克风录制所需持续时间的音频。我想通过接受用户输入来控制文件的持续时间。根据它的决定,我必须停止录制并在该持续时间内保存文件。

import pyaudio
import wave
from multiprocessing import Process

global flag
global frames

def try_recording(stream,RATE, CHUNK):
    while flag != 1:
        #for i in range(0,int(RATE/CHUNK*DURATION): 
        for i in range(0,int(RATE/CHUNK)):
            data = stream.read(CHUNK)
            frames.append(data)

def scan_input():
    num = input('Enter input number: ')
    if int(num) == 1:
       flag = 1
    else:
       scan_input()

if __name__=='__main__':
    FORMAT = pyaudio.paInt16
    CHANNELS = 2
    RATE = 44100
    CHUNK = 1024

    WAVE_OUTPUT_FILENAME = "file.wav"
    flag = 0

    audio = pyaudio.PyAudio()

    # start Recording
    stream = audio.open(format=FORMAT, channels=CHANNELS,
                    rate=RATE, input=True,
                    frames_per_buffer=CHUNK)
    print("recording...")
    frames = []
    #sys.setrecursionlimit(1500)
    p1 = Process(target=try_recording, args = (stream,RATE,CHUNK))
    p1.start()
    p2 = Process(target=scan_input)
    p2.start()

    #frames = try_recording(stream, RATE, CHUNK)
    print('finished recording')
    # stop Recording
    stream.stop_stream()
    stream.close()
    audio.terminate()

    waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    waveFile.setnchannels(CHANNELS)
    waveFile.setsampwidth(audio.get_sample_size(FORMAT))
    waveFile.setframerate(RATE)
    waveFile.writeframes(b''.join(frames))
    waveFile.close()

当我以秒为单位定义时间时,我可以record 文件。现在我想在停止录制时扫描来自用户端的输入。所以我修改了程序,添加了parallel processing,让两个函数同时运行。当我遇到递归错误时,我尝试通过添加sys.setrecursionlimit(1500) 来resolve,但结果并没有改变任何东西。

如何解决此问题,以便我可以录制所需时间的音频。

更新: 错误与回溯

recording...
Traceback (most recent call last):
  File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
  File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
  File "D:/Projects/Trails/try.py", line 14, in try_recording
try_recording(stream,RATE,CHUNK)
  [Previous line repeated 995 more times]
  File "D:/Projects/Trails/try.py", line 9, in try_recording
     if flag == 1:
  RecursionError: maximum recursion depth exceeded in comparison

如果我将限制增加到 44000 sys.setrecursionlimit(44000),代码将运行大约 1 秒并以错误结束

 Process finished with exit code -1073741571 (0xC00000FD)

更新2: @quamrana 建议的更新代码。

这两个进程没有同时工作。循环不会出现在流程 2 功能之外。使用打印语句进行测试我知道在我按下 1 之前它只会在进程 1 中循环,稍后它会移动到第二个进程但无法扫描来自第一个函数的输入以结束录制。

更新 3: 更新进程参数

Traceback (most recent call last):
File "D:/Projects/Trails/try.py", line 42, in <module>
p1.start()
File "C:\Program Files\Python36\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Program Files\Python36\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "C:\Program Files\Python36\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "C:\Program Files\Python36\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _portaudio.Stream objects
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Program Files\Python36\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File "C:\Program Files\Python36\lib\multiprocessing\spawn.py", line 115, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

如何解决多处理泡菜错误?

【问题讨论】:

你能分享你看到的错误和回溯 @akshat:错误和追溯更新 【参考方案1】:

我假设您实际上并不要求 try_recording 是递归的,因此可以这样重写:

def try_recording(stream,RATE, CHUNK):
    while flag != 1:
        for i in range(0,int(RATE/CHUNK)):
            data = stream.read(CHUNK)
            frames.append(data)

您也没有正确启动您的流程。它们应该是:

p1 = Process(target=try_recording, args=(stream,RATE,CHUNK))
p2 = Process(target=scan_input)

你的标志应该是一个共享变量:

# flag = 0
flag = multiprocessing.Value('i', 0)

【讨论】:

更新了代码,但只有一个函数在运行,两个函数没有同时运行。请参阅更新 2 您的代码似乎有p1.start()p2.start() - 哦!但是您对Processtarget 参数是错误的! 我已经更新了目标参数,我想我已经打开了另一个问题。而不是启动,而是输入不足。 我想我没有同步进程。【参考方案2】:

一旦你try_recording 进入else,你如何期待flag 被更新。你已经在这里实现了任何 IPC 机制。导致它进入无限循环

【讨论】:

更新了代码,但是只运行了一个函数,两个函数没有同时运行。

以上是关于记录未知长度的数据时如何修复错误?的主要内容,如果未能解决你的问题,请参考以下文章

尝试将服务推送到 Apollo Engine 时,如何修复“将服务上传到引擎 → 未知指令“密钥””错误?

如何修复 XMLHttpRequest 中的 419 未知状态?

如何修复错误 [Vue 警告]:未知的自定义元素?

如何修复 Vue 3 中的“错误:未知选项:devServer”[关闭]

如何修复 DiscordAPIError:未知成员?

Smarty:如何修复“未知修饰符'rewrite'”异常?