当前位置: 首页 > 知识库问答 >
问题:

python3.x - python subprocess启动多个ffmpeg shell?

子车新立
2024-06-14

我需要依次调用三次subprocess. 发现最后一个没有执行? 在流媒体服务器的控制台上只能看到: aac和mp4的rtmp信息, 看不到live的rtmp连接
参考代码:

if __name__ == "__main__":    device: str = "cuda:0" if torch.cuda.is_available() else "cpu"    model, tokenizer = loadModel(device=device)    #    # 音频(aac)    #    audioProcess = sp.Popen(["ffmpeg",                              "-f", "s16le",                              '-y', '-vn',                             "-ac", "1",                             "-ar", "16000",                             "-channel_layout", "mono",                             '-acodec','pcm_s16le',                             "-i", "pipe:",                             "-ar", "44100",                             "-f", "flv",                             rtmpAURL], stdin=sp.PIPE)        #    # 视频(mp4)    #    vedioProcess = sp.Popen(["ffmpeg",                             "-re",                             '-y', '-an',                             '-rtbufsize', '1024M',                             "-f", "dshow",                             "-i", "video=Q8 HD Webcam",                             "-pix_fmt", "yuvj420p",                             "-framerate", "25",                             '-vcodec', 'libx264',                              '-preset', 'fast',                              '-crf', '25',                             "-vf", "scale=640:480",                             "-f", "flv", rtmpVURL], shell=True)        #    #https://stackoverflow.com/questions/18618191/ffmpeg-merge-multiple-rtmp-stream-inputs-to-a-single-rtmp-output    #ffmpeg -i rtmp://ip:1935/live/micMyStream7 -i rtmp://ip:1935/live/MyStream7 -filter_complex "[0:a][1:a]amix[a]" -map 0:v -map "[a]" -c:v copy -f flv rtmp://ip:1935/live/bcove7    #    # 合并(live)    #     mergeVAP = sp.Popen(["ffmpeg",                                 "-i", rtmpAURL,                                "-i", rtmpVURL,                                "-c:v", "copy",                                "-c:a", "aac",                                "-preset", "veryfast",                                "-f", "flv",                                "-flvflags", "no_duration_filesize",                                rtmpURL], shell=True, stderr=True)        writeAudioThead = Thread(target=soundRecorder, args=(model, device, tokenizer, audioProcess))    writeAudioThead.start()    writeAudioThead.join()    audioProcess.wait()    vedioProcess.wait()    mergeVAP.wait()

问题1:这三个是串行执行的. 如何让他们异步执行
问题2: 上面的示例串行执行, 为什么 mergeVAP没有执行.在命令行上执行是可以执行的

共有1个答案

彭涵衍
2024-06-14

捕获了一下合并流的subprocess发现它启动时音频流不可用,所以才无法正常通行. 在音频流可用的第一时间调用封装了合并流的函数都可以正常运行了. 示例代码:

if __name__ == "__main__":    device: str = "cuda:0" if torch.cuda.is_available() else "cpu"    model, tokenizer = loadModel(device=device)    #    # 音频    #    audioProcess = sp.Popen(["ffmpeg",                              "-f", "s16le",                              "-y", "-vn",                             "-ac", "1",                             "-ar", "16000",                             "-channel_layout", "mono",                             "-acodec","pcm_s16le",                             "-i", "pipe:",                             "-ar", "44100",                             "-f", "flv",                             rtmpAURL], stdin=sp.PIPE)    writeAudioThead = Thread(target=soundRecorder, args=(model, device, tokenizer, audioProcess))    writeAudioThead.start()    #writeAudioThead.join()    #    # 视频    #    vedioProcess = sp.Popen(["ffmpeg",                             "-re",                             "-y", "-an",                             "-f", "dshow",                             "-i", "video=Q8 HD Webcam",                             "-pix_fmt", "yuvj420p",                             "-framerate", "25",                             "-vcodec", "libx264",                              "-x264-params", "nal-hrd=cbr",                             "-minrate", "1M",                             "-maxrate", "1M",                             "-bufsize", "2M",                             "-preset", "fast",                              "-crf", "25",                             "-vf", "scale=640:480",                             "-f", "flv", rtmpVURL], shell=True)        #    #https://stackoverflow.com/questions/18618191/ffmpeg-merge-multiple-rtmp-stream-inputs-to-a-single-rtmp-output    #ffmpeg -i rtmp://ip:1935/live/micMyStream7 -i rtmp://ip:1935/live/MyStream7 -filter_complex "[0:a][1:a]amix[a]" -map 0:v -map "[a]" -c:v copy -f flv rtmp://ip:1935/live/bcove7    #    # 合并    #     isFirst = False    while True:        if isFirst:            mergeVA()            break    #     #    audioProcess.wait()    vedioProcess.wait()    #mergeVAP.wait(60)    #

在soundRecorder方法中将全局的状态(isFirst)切换为true以触发合并流的调用. 本来想用signal发现windows中不支持,会报错:AttributeError: module 'signal' has no attribute 'alarm'

def soundRecorder(model, device, tokenizer, audioPipProcesss):    global isFirst    #    filepath = 'oldmansea.txt'    for content in read_file(filepath):        print(content)        audioPipWriter(generte(prompt=content, device=device, model=model, tokenizer=tokenizer), audioPipProcesss=audioPipProcesss)        if not isFirst:            isFirst = True        time.sleep(2)    audioPipProcesss.stdin.close() 

mergeVA的方法代码如下:

def mergeVA():    print('------------->start vedio and autio')    #time.sleep(30)    try:        mergeVAP = sp.Popen(["ffmpeg",                                 "-rw_timeout", "5000000",                                "-rtbufsize", "1024M",                                "-i", rtmpAURL,                                "-i", rtmpVURL,                                "-c:v", "copy",                                "-c:a", "aac",                                "-preset", "veryfast",                                "-f", "flv",                                "-flvflags", "no_duration_filesize",                                rtmpURL], stderr=sp.PIPE, shell=True)        out, err = mergeVAP.communicate()        print('merge vedio&audio has error:%s' % err)        print(out)    except sp.CalledProcessError as error:        print('ffmpeg exited with return code ' + str(error.returncode))        print(f'**ERROR** An error occurred while converting the file')    mergeVAP.wait()

当前方案的采集和推流方法实时性欠缺. 希望还有提升的空间

 类似资料:
  • 我一直在尝试写一些java应用程序。这个应用程序想要运行的是处理一个文本文件。 但是,输入文本文件很大(超过200MB),我尝试将200MB拆分为四个拆分文件(每个50MB) 所以,每一个都只需要0.5秒,但是用这种线性运行,每一个也需要2秒。(worker1+0.5s,worker2+0.5s,worker3+0.5s,worker4)如果我可以同时运行4个线程,我预计这个应用程序只需要0.5秒

  • 我自己写了一个多进程下载网络大文件的程序:基本思路是多进程分块下载完后,再拼接文件。 这个url的大文件被分割成20个部分,开启了4个进程下载。 测试运行: python3 mpdown.py #速度比单进程快50%以上。 现在我有点不满意这个多进程下载,拼接文件(merge)是在全部下载完成后,再拼接,我想这个拼接动作也修改成多进程并行的,边下载边拼接。 由于下载是多进程的,各进程存在一定的竞争

  • 主要内容:1 配置Tomcat服务器的多个实例很多时候,我们遇到需要修改服务器配置以使其适应应用程序的情况。如果我们有多个应用程序,并且希望每个应用程序都有自己定义的配置选项,那么需要怎么配置呢?在本教程中,我将讨论为每个应用程序使用不同的Tomcat实例。 1 配置Tomcat服务器的多个实例 我正在使用Windows机器,您将使用Windows格式的路径。但是创建多个实例的过程在所有其他操作系统中都是相同的。另外,我假设您要创建2个新的t

  • 我能够在我的windows机器上运行单个zooKeer实例。但在单个windows机器上成功设置多个zooKeer实例。 根据指南,我执行了以下步骤: > 在conf文件夹中创建多个zoo.conf文件。结构如下 zookeeper\u主页--|形态--|动物园。cfg zoo\u 2。cfg zoo\u 3。cfg公司 zoo.cfg C:/opt/zooeger/data C:/opt/zoo

  • 我正试图使用INFOQ提供的本教程设置一个包含多个数据源的Springboot(v2.0.0.BUILD-SNAPSHOT)项目 https://www.infoq.com/articles/Multiple-Databases-with-Spring-Boot 但是我需要使用多个EntityManager来代替JdbcTemplate 这是我目前掌握的情况 应用属性 一个pplication.j

  • 我正在尝试在我的容器中启动一些服务。 这是我entry_point剧本: 我想做的是取消评论这一行: 但在启动时,容器就挂在这里。 有什么解决办法吗?