Windows环境下python+Opencv2控制双摄像头录像-格式转换-上传指定服务器。

我一个C#搬砖狗,被分配这种苦逼活,然后我就恶补了一堆python知识,学习使我快乐,终于做出来辣,又学习到很多知识。

以下是我参考网上各种代码以后,半原创的代码,自己做一个记录,也供大家参考。

转换器用的FFmpeg,把FFmpeg.exe放到server.py同级目录里

server.py 文件

from flask import Flask,Response,request
from flask_cors import CORS
import threading
import interface
import uuid
from py_linq import Enumerable
import base
import json
import os
import requests
import time
from ffmpy import FFmpeg
#以上是引用的一堆东西 挨个安装的时候真是痛苦

app = Flask(__name__)
serverUlr = 'http://xxx.xxxx.cn'#上传地址
@app.route('/testget', methods=['Get'])#get测试用的
def get():
    return Response("get成功")
@app.route('/testpost', methods=['Post'])#post测试
def post():
    return Response("post成功")

#开始录像
@app.route('/startVideotape', methods=['Get'])
def startVideotape():
    name = ''
    nameTwo=''
    if ('file' in request.values and 'fileTwo' in request.values ):
        name = request.values['file']#你传来的文件名
        nameTwo = request.values['fileTwo']#你传来的文件名2 当然  你也可以自己生成
    else:
        fileText = base.Util.readFile('config.txt', encoding='UTF-8-sig')
        if (not fileText.Succeed):
            return base.Response(base.Util.ObjToJson(base.BaseReturn(False, '读取配置文件失败')))
        savePath = json.loads(fileText.Data)
        if ('VideoSavePath' not in savePath):
            return base.Response(base.Util.ObjToJson(base.BaseReturn(False, '未能找到配置数据')))
        
        name = os.path.join(savePath['VideoSavePath'], str(uuid.uuid1()))
        nameTwo = os.path.join(savePath['VideoSavePath'], str(uuid.uuid1()))
    videotape = Enumerable(threading.enumerate()).where(lambda e: e.name == 'videotape').first_or_default()
    if (videotape != None):
        return base.Response(base.Util.ObjToJson(base.BaseReturn(False, '当期线程正在运行')))
    t = threading.Thread(target=interface.videotape, args=(name,nameTwo,640,480), name='videotape')
    t.start()#线程启动
    return base.Response(base.Util.ObjToJson(base.BaseReturn(True, '开始录制')))


#结束录像
@app.route('/endVideotape', methods=['Get'])
def endVideotape():
    interface.isStop = True
    
    time.sleep(0.5)
    fileName = ''
    fileTwoName = ''
    
    if ('file' in request.values):
        fileName = request.values['file']#get过来的文件名
    if ('fileTwo' in request.values):
        fileTwoName = request.values['fileTwo']#get过来的文件名
    #转换文件为mp4  录制了两个文件 这里转第一个
    savePath = os.path.join(os.getcwd(), 'tmp')
    file = os.path.splitext(fileName)[0]
    avi = os.path.join(savePath, ('%s.avi' % file))
    mp4 = os.path.join(savePath, ('%s.mp4' % file))
    ff = FFmpeg(executable='ffmpeg.exe', inputs={avi: None}, outputs={mp4: None})
    succeed = ff.run()
    os.remove(avi)#删掉avi文件
    filepath = os.path.join(os.getcwd(), 'tmp', fileName)
    file = open(filepath, 'rb')
    file_payload = {'file': file}
    res = requests.post(('%s/api/file/upload' % (serverUlr)), files=file_payload)#把他上传了
    file.close()
    rtn = json.loads(res.text)
    if (len(rtn) == 1 and
        rtn[0]['FileGuid'] == os.path.splitext(fileName)[0]):
        os.remove(filepath)
    
    #转换2文件为mp4 这里转第二个
    fileTwo = os.path.splitext(fileTwoName)[0]
    aviTwo = os.path.join(savePath, ('%s.avi' % fileTwo))
    mp4Two = os.path.join(savePath, ('%s.mp4' % fileTwo))
    ffTwo = FFmpeg(executable='ffmpeg.exe', inputs={aviTwo: None}, outputs={mp4Two: None})
    succeed = ffTwo.run()
    os.remove(aviTwo)#删掉avi文件
    filepath = os.path.join(os.getcwd(), 'tmp', fileTwoName)
    fileTwo = open(filepath, 'rb')
    file_payload = {'file': fileTwo}
    res = requests.post(('%s/api/file/upload' % (serverUlr)), files=file_payload)#上传
    fileTwo.close()
    rtn = json.loads(res.text)
    if (len(rtn) == 1 and
        rtn[0]['FileGuid'] == os.path.splitext(fileTwoName)[0]):
        os.remove(filepath)
    return base.Response(base.Util.ObjToJson(base.BaseReturn(True, '结束录制')))


#结束录像
@app.route('/uploadFile', methods=['Get'])
def uploadFile():
    fileName = ''
    fileTwoName = ''
    if ('file' in request.values):
        fileName = request.values['file']
    if ('fileTwo' in request.values):
        fileTwoName = request.values['fileTwo']
    filePath = os.path.join(os.getcwd(), 'tmp', fileName)
    filePathTwo = os.path.join(os.getcwd(), 'tmp', fileTwoName)
    file_payload = {'file': open(filePath, 'rb')}
    file_payloadTwo = {'file': open(filePathTwo, 'rb')}
    res = requests.post(('%s/api/file/upload' % (serverUlr)), files=file_payload)
    resTwo = requests.post(('%s/api/file/upload' % (serverUlr)), files=file_payloadTwo)
    interface.isStop = True
    while interface.isFinish:
        time.sleep(1)
        continue
    return base.Response(base.Util.ObjToJson(base.BaseReturn(True, '结束上传')))
CORS(app, supports_credentials=True)
if __name__ == '__main__':
    app.debug = False
    app.run(host='0.0.0.0', port=80)

然后是interface.py文件

import cv2
from ffmpy import FFmpeg
import os
import logging

isStop = False
isFinish = False
#录像
def videotape(file,fileTwo, width=640, height=480, maxTime=''):#上一个文件传来的file fileTwo
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH,width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT,height)

    capTwo = cv2.VideoCapture(1)#摄像头2
    capTwo.set(cv2.CAP_PROP_FRAME_WIDTH,width)#摄像头2
    capTwo.set(cv2.CAP_PROP_FRAME_HEIGHT,height)#摄像头2
    
    savePath = os.path.join(os.getcwd(), 'tmp')
    if (not os.path.exists(savePath)):
        os.mkdir(savePath)
    file = os.path.splitext(file)[0]
    avi = os.path.join(savePath, ('%s.avi' % file))
    mp4 = os.path.join(savePath, ('%s.mp4' % file))

    fileTwo = os.path.splitext(fileTwo)[0]#摄像头2
    aviTwo = os.path.join(savePath, ('%s.avi' % fileTwo))#摄像头2
    mp4Two = os.path.join(savePath, ('%s.mp4' % fileTwo))#摄像头2
    #cap.set(1, 10.0)
    global isStop
    isStop = False
    isFinish = False
    try:
        #此处fourcc的在MAC上有效,如果视频保存为空,那么可以改一下这个参数试试, 也可以是-1
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        #fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 这些都是一样的意思 不需要纠结
        #fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', 'V') 我也不知道为什么录制出来是AVI 
        #fourcc = cv2.VideoWriter_fourcc(*'MP4V')虽然我定义的mp4  定别的格式可以去搜一下 都有
        #这个参数则是镜头快慢的,10为正常,小于10为慢镜头 
        fps = 20 #别人都说10是正常速度 我写20才是正常速度 不知道为什么
        out = cv2.VideoWriter(avi, fourcc, fps, (width, height))# 文件名 格式 帧率 宽高
        outTwo = cv2.VideoWriter(aviTwo, fourcc, fps, (width, height))
        while True:
            ret,frame = cap.read()
            retTwo,frameTwo = capTwo.read()#摄像头2
            if (isStop):
                break
            if ret == True:
                a = out.write(frame)
                aTwo = outTwo.write(frameTwo)
            else:
                break
    except Exception as e:
        pass
    finally:
        cap.release()
        capTwo.release()
        out.release()
        outTwo.release()
        cv2.destroyAllWindows()
        isFinish = True
        pass

以上就这些啦!稍微有些编程基础就能够看懂的,一定要注意python的缩进非常严格,给跪了
 

转载请注明出处。如有问题可留言或者Q4396765,感谢您的查阅,如有错误希望各位大佬能够指正,感激不尽!

你可能感兴趣的:(硬件控制)