python使用pexpect与screen进行交互控制启动ffmpeg

最近在折腾screen内ffmpeg自动启动,但是树莓派不知道为啥运行ffmpeg几乎每次首次运行都会报错Input/output error,然后第二次运行就能正常工作。所以需要对screen的命令运行结果做一个判断,然后根据返回的内容决定是否再次运行命令。

一、准备工作:

开启screen的log参数

编辑/etc/screenrc文件:
sudo nano /etc/screenrc
末尾添加一行(tips:nano跳转到最后一行快捷键是 ctrl+-然后 ctrl+v

logfile /tmp/screenlog_%t.log

二、代码

方法一:

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   start_ff_cron.py
@Time    :   2020/04/09 18:42:04
@Author  :   SimonLiu 
@Version :   1.0
@License :   (C)Copyright @SimonLiu
@Desc    :   None
'''

# here put the import lib
import pexpect,os,re,time

count = 0
result = 1
def execshellCmd(cmd):  
    r = os.popen(cmd)  
    text = r.read()  
    r.close()  
    return text  

def start_ffmpeg():
    #Note: "stuff \\015"代表回车,"stuff \\003" 代表ctrl+c
    session.sendline('screen -x ffmpeg -p0 -X stuff "ffmpeg -thread_queue_size 4096 -f v4l2  -f lavfi -i \
anullsrc=channel_layout=stereo:sample_rate=44100  -input_format yuyv422 -video_size 1280x720 -framerate 30 \
-i /dev/video0 -vf eq=gamma=1.5:saturation=1.3 -c:v h264_omx -b:v 20480K -vsync 1 -g 16  -f flv\
rtmp://dummy.mydomain.com:1935/live/"')
    session.sendline('screen -x ffmpeg -p0 -X eval "stuff \\015"')

def check_log():
    global result
    #读取log文件最后5行
    cmd = "tail -n 10 /tmp/screenlog_ffmpeg.log"
    print("executing cmd:%s"%cmd)
    tailoutput = execshellCmd(cmd)
    print("tailoutput:%s"%tailoutput)
    #在读取结果中匹配字符串'output error'
    pattern1 = "output error"
    match = re.findall(pattern1, tailoutput)
    if match:
        print("match=%s, ffmpeg start failed" %(match[0]))
        return 1
    else:
        print("no error message found in screen log file, ffmpeg start success")
        return 0



#spawn a new bash session
session = pexpect.spawn('/bin/bash')
#导入用户profile
session.sendline('source ~/.bashrc')
#清空旧的log
session.sendline('echo "">/tmp/screenlog_ffmpeg.log')
#dettach模式开启screen(-dmS ffmpeg)并且log文件名参数为ffmpeg(-L -t ffmpeg)
session.sendline('screen -L -t ffmpeg -dmS ffmpeg')



while (True):
    start_ffmpeg()
    #延时等待执行结果
    time.sleep(10)
    if (check_log()):
        count += 1
        print('error message found, restart ffmpeg, count:',count)
        time.sleep(5)
        continue
    else:
        break
    
time.sleep(0.1)

session.close()

方法二:

1.安装pexpect模块

pip install pexpect

2.代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pexpect, time

result = 1
count = 0

def start_ffmpeg():
    #Note: "stuff \\015"代表回车,"stuff \\003" 代表ctrl+c
    session.sendline('screen -x ffmpeg -p0 -X stuff "ffmpeg -thread_queue_size 4096 -f v4l2  -f lavfi -i \
anullsrc=channel_layout=stereo:sample_rate=44100  -input_format yuyv422 -video_size 1280x720 -framerate 30 \
-i /dev/video0 -vf eq=gamma=1.5:saturation=1.3 -c:v h264_omx -b:v 20480K -vsync 1 -g 16  -f flv\
rtmp://dummy.mydomain.com:1935/live/"')
    session.sendline('screen -x ffmpeg -p0 -X eval "stuff \\015"')
    
def check_log():
    global result
    #读取log文件最后5行
    session.sendline('tail -n 5 /tmp/screenlog_ffmpeg.log')

    #在读取结果中匹配字符串'output error'
    try:
        result=session.expect([pexpect.TIMEOUT,'output error'])
        print("result = %d "%result)
        if (result):
            return 1
        else:
            return 0
    except:
        print('--== exception error, set result to 1 ==--')
        return 1


#spawn a new bash session
session = pexpect.spawn('/bin/bash')
#导入用户profile
session.sendline('source ~/.bashrc')
#清空旧的log
session.sendline('echo "">/tmp/screenlog_ffmpeg.log')
#dettach模式开启screen(-dmS ffmpeg)并且log文件名参数为ffmpeg(-L -t ffmpeg)
session.sendline('screen -L -t ffmpeg -dmS ffmpeg')


while (True):
    start_ffmpeg()
    time.sleep(10)
    if (check_log()):
        count += 1
        print('error message found, restart ffmpeg, count:',count)
        time.sleep(5)
        continue
    else:
        print('No error message,ffmpeg running OK')
        break
    
time.sleep(0.1)

session.close()

实际运行可以看到/tmp/cron.log/tmp/screenlog_ffmpeg.log都看到了ffmpeg启动失败的信息然后又再次启动了。
在这里插入图片描述

参考文献:
python获取命令行输出结果
linux - Send command to detached screen and get the output - Unix & Linux Stack Exchange
Linux之screen创建、切换、记录屏幕日志 – JeeInn的技术分享
Linux删除(清空)正在运行的应用日志文件内容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章