首先讲一下模块的背景,我需要在Linux下面录屏,因为并不知道目标机的屏幕分辨率,所以:
1、自动获取屏幕分辨率
2、自动开始录屏
3、录屏5分钟以后自动保存并结束录制
二、逐个击破首先是怎么获取分辨率,在Linux下面有个命令是 xrandr ,它可以打印出来屏幕分辨率,但是他会打印一大堆出来,所以要精准筛选出****x***这样的文字出来:
xrandr -q --current | grep '*' | awk '{print$1}'
然后把它组装到ffmpeg命令里面作为指定的录屏分辨率:
ffmpeg -f x11grab -s $(xrandr -q --current | grep '*' | awk '{print$1}') -r 2 -i :0.0+0+0 -b:v 150k -vcodec libx264 output.mp4
其中 :
-f x11grab是信号源
-s 是设置分辨率
-r 设定帧率
-i 设定采集位置和偏移量
-b:v 是码率
-vcodec 是编码格式
最后一个难点是如何让他定时录屏5分钟之后自动结束:
经过测试 subprocess里面的wait()命令并不生效,ffmpeg进程无法结束
但是在正常命令运行中按[q]键可以结束录制,因为在按了q之后ffmpeg程序会补齐文件尾,如果因为其他的什么方式结束了ffmpeg,会导致视频缺少文件尾没法播放。
很多教程的思路都是在进程层面上如何让ffmpeg以exit(0)结束,这是一个误区。ffmpeg的录屏命令和其他命令不太一样,不存在一个主动结束的步骤,如果没有外界干涉会一直录下去。
正确的思路其实是如何把q这个按键送进去,让ffmpeg以它希望的方式安全结束。
进程句柄.stdin.write()
这句话是一个关键,它以标准输入的形式模拟按下了q键。
communicate() kill()
也同样重要,前者是为了及时停下子进程,后者是一起杀掉。
三、整体回顾import time
import subprocess
def run_cmd(command):
res = subprocess.Popen(command,shell=True,stdin=subprocess.PIPE,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
time.sleep(300)
res.stdin.write('q'.encode("GBK"))
res.communicate()
res.kill()
filename = str(int(time.time()))
command = "ffmpeg -f x11grab -s $(xrandr -q --current | grep '*' | awk '{print$1}') -r 2 -i :0.0+0+0 -b:v 150k -vcodec libx264 "+filename+".mp4"
run_cmd(command)


