使用子进程从python执行ffmpeg命令

2024-09-27 09:32:50 发布

您现在位置:Python中文网/ 问答频道 /正文

以下命令可以从命令行正常工作:

ffmpeg -y -threads 4 -i /dev/video0 -filter_complex "[v:0]scale=-2:720:force_original_aspect_ratio=decrease[vout001]" -c:v libx264 -b:v 2800k -maxrate:v 2996k -bufsize:v 4200k -c:a aac -b:a 128k -ac 2 -ar 48000 -preset veryfast -x264opts keyint=25:min-keyint=25:no-scenecut -sc_threshold 0 -r 25 -pix_fmt yuv420p -segment_list_flags +live -map [vout001] -f tee -var_stream_map 'v:0' "[f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename='segment_%%06d_%Y%m%d%H%M%S.ts']playlist.m3u8|[f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename=\'http://X.X.X.X:pppp/ABCD/segment_%%06d_%Y%m%d%H%M%S.ts\':method=PUT]http://X.X.X.X:pppp/ABCD/playlist.m3u8"

但是,当我使用以下命令通过子进程从python代码执行它时,它会抛出错误:

^{pr2}$

错误如下:

No option found near "//X.X.X.X:pppp/ABCD/segment_%%06d_%Y%m%d%H%M%S.ts":method=PUT]http://X.X.X.X:pppp/ABCD/playlist.m3u8"

从python代码执行时,它将“http”后面的“:”作为选项分隔符(escape不起作用),而直接从shell执行时,escape可以正常工作。在

我如何解决这个问题?在


Tags: 命令httpmaptimetypesegmentplaylistflags
3条回答

谢谢你们的建议和帮助。我尝试了三重引号,但它产生了另一个问题,包括视频片段/播放列表,文件名如下:

"f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename=segment_%%06d_%Y%m%d%H%M%S.ts]playlist.m3u8

"f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename=segment_%%06d_%Y%m0%H%M%S.ts]playlist0.ts

"f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename=segment_%%06d_%Y%m11%H%M%S.ts]playlist11.ts

。。。。在

因此,它将参数列表视为片段/播放列表文件名。此外,它生成一个输出而不是两个输出(一个在本地,另一个到远程服务器)。在

实际上,解决方案是保持相同的命令,只在远程服务器url中的“:”之前添加“\”。因此,从python代码中可以正常工作的最后一个命令是:

^{pr2}$

关于选项/值:'-var_stream_map'和'v:0',我只是错过了它。它可以被忽略,因为我们只有一个输入。在

谢谢。在

您是如何生成cmd\ufmpeg的?手动?它与shlex.split返回的内容不同。例如,cmd_fmpegfilter_complex后面有双引号,而whatshlex.分离返回没有

import shlex
shell_ffmpeg_cmd = r'''ffmpeg -y -threads 4 -i /dev/video0 -filter_complex "[v:0]scale=-2:720:force_original_aspect_ratio=decrease[vout001]" -c:v libx264 -b:v 2800k -maxrate:v 2996k -bufsize:v 4200k -c:a aac -b:a 128k -ac 2 -ar 48000 -preset veryfast -x264opts keyint=25:min-keyint=25:no-scenecut -sc_threshold 0 -r 25 -pix_fmt yuv420p -segment_list_flags +live -map [vout001] -f tee -var_stream_map 'v:0' "[f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename='segment_%%06d_%Y%m%d%H%M%S.ts']playlist.m3u8|[f=hls:hls_time=1:hls_playlist_type=event:strftime=1:hls_flags=independent_segments+program_date_time+second_level_segment_index:hls_segment_filename=\'http://X.X.X.X:pppp/ABCD/segment_%%06d_%Y%m%d%H%M%S.ts\':method=PUT]http://X.X.X.X:pppp/ABCD/playlist.m3u8"'''
popen_args = shlex.split(shell_ffmpeg_cmd)
print(" ".join(popen_args))

另外,与shell调用相比,cmd ffmpeg缺少这两个开关:-var_stream_map和{}。在

然而,你的问题似乎出在列表的最后一个元素上。正如eatmeimadanish建议的那样,试着三次引用它。以下是您的cmd\ufmpeg,最后一个元素被更正并用三个单引号括起来。它打印了ffmpeg的stderr,根据我的经验,它非常有用:

^{pr2}$

ffmpeg看到命令行之前,shell会丢弃长字符串周围的双引号。在Python中,您可以简单地用单引号替换它们。在单引号中包含双引号是抛出ffmpeg选项解析器的原因。在

相关问题 更多 >

    热门问题