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刪除(清空)正在運行的應用日誌文件內容

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