Commit 88564035 authored by liyuanhong's avatar liyuanhong

完成了图像抓拍和视频抓拍功能

parent c3cb585c
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import binascii import binascii
import json import json
import re import re
import sys
import time import time
import traceback import traceback
...@@ -35,7 +36,8 @@ class StreamH264Flv(): ...@@ -35,7 +36,8 @@ class StreamH264Flv():
self.videoPath = "../../flv/bbb3.flv" # 要推流的视频路劲 self.videoPath = "../../flv/bbb3.flv" # 要推流的视频路劲
self.getGetPlayUrl = "http://10.100.11.110:9999/video/streamInfo" # 获取推流播放地址的url self.getGetPlayUrl = "http://10.100.11.110:9999/video/streamInfo" # 获取推流播放地址的url
# self.getGetPlayUrl = "http://fb-test.vandyo.com/video/streamInfo" # 获取推流播放地址的url # self.getGetPlayUrl = "http://fb-test.vandyo.com/video/streamInfo" # 获取推流播放地址的url
with open("config/config.yaml", 'r', encoding="utf-8") as fi: curPath = sys.path[0]
with open(curPath + "/config/config.yaml", 'r', encoding="utf-8") as fi:
fi_data = fi.read() fi_data = fi.read()
data = yaml.load(fi_data,Loader=yaml.FullLoader) data = yaml.load(fi_data,Loader=yaml.FullLoader)
self.getGetPlayUrl = data["globalCon"]["getPlayUrl"] self.getGetPlayUrl = data["globalCon"]["getPlayUrl"]
...@@ -45,11 +47,12 @@ class StreamH264Flv(): ...@@ -45,11 +47,12 @@ class StreamH264Flv():
self.logTextCtr = None # 日志输出框,用于输出日志 self.logTextCtr = None # 日志输出框,用于输出日志
self.pushStatusText = None # 状态显示窗 self.pushStatusText = None # 状态显示窗
self.multiPushStatus = 0 # 多次推流标记, 0:该连接第一次推流 1:该连接第一次对流 2: 该连接第二次对流 self.multiPushStatus = 0 # 多次推流标记, 0:该连接第一次推流 1:该连接第一次对流 2: 该连接第二次对流
self.timesStamp = 0
self.timeStampSeek = 0 # 时间搓偏移,推理完成后设置为最后一帧的时间搓值;循环推流的时候需要加上该值 self.timeStampSeek = 0 # 时间搓偏移,推理完成后设置为最后一帧的时间搓值;循环推流的时候需要加上该值
self.isOpenVideoLog = 0 # 是否开启视频日志 0:不开启 1:开启 self.isOpenVideoLog = 0 # 是否开启视频日志 0:不开启 1:开启
self.isOpenAudioLog = 0 # 是否开启音频日志 0:不开启 1:开启 self.isOpenAudioLog = 0 # 是否开启音频日志 0:不开启 1:开启
self.protocal_1078 = Protocal_1078() self.protocal_1078 = Protocal_1078()
self.autoClose = 0 # 视频推流完是否自动关闭连接 0:否 1:是 self.autoClose = 0 # 视频推流完是否自动关闭连接 0:否 1:是t
def setMobile(self,data): def setMobile(self,data):
...@@ -85,6 +88,10 @@ class StreamH264Flv(): ...@@ -85,6 +88,10 @@ class StreamH264Flv():
def setAutoClose(self,data): def setAutoClose(self,data):
self.autoClose = data self.autoClose = data
def getTimeStamp(self):
times = self.timesStamp - self.timeStampSeek
return times
#################################################### ####################################################
...@@ -114,6 +121,7 @@ class StreamH264Flv(): ...@@ -114,6 +121,7 @@ class StreamH264Flv():
self.isEndPush = 0 self.isEndPush = 0
self.isFileHead = 0 self.isFileHead = 0
timeStamp = 0 timeStamp = 0
self.timesStamp = timeStamp
with open(self.videoPath, 'rb') as fi: with open(self.videoPath, 'rb') as fi:
con = fi.read(self.readSize) con = fi.read(self.readSize)
data = con.hex() data = con.hex()
...@@ -142,9 +150,11 @@ class StreamH264Flv(): ...@@ -142,9 +150,11 @@ class StreamH264Flv():
if self.multiPushStatus < 1: if self.multiPushStatus < 1:
avTimeStamp = self.getAVTimeStamp(tag) #获取时间戳 avTimeStamp = self.getAVTimeStamp(tag) #获取时间戳
timeStamp = avTimeStamp timeStamp = avTimeStamp
self.timesStamp = timeStamp
else: else:
avTimeStamp = self.getAVTimeStamp(tag) + self.timeStampSeek # 获取时间戳 avTimeStamp = self.getAVTimeStamp(tag) + self.timeStampSeek # 获取时间戳
timeStamp = avTimeStamp timeStamp = avTimeStamp
self.timesStamp = timeStamp
if avTimeStamp > 100: if avTimeStamp > 100:
if self.isGetPlayUrl == 0: if self.isGetPlayUrl == 0:
self.getPlayUrl(self.mobile,self.channel) self.getPlayUrl(self.mobile,self.channel)
......
#coding: utf-8 #coding: utf-8
import json import json
import os import os
import re
import sys import sys
import threading import threading
import time import time
...@@ -29,7 +30,8 @@ class CameraArea(): ...@@ -29,7 +30,8 @@ class CameraArea():
self.host="10.100.11.125" self.host="10.100.11.125"
self.port="1078" self.port="1078"
with open("config/config.yaml", 'r', encoding="utf-8") as fi: curPath = sys.path[0]
with open(curPath + "/config/config.yaml", 'r', encoding="utf-8") as fi:
fi_data = fi.read() fi_data = fi.read()
data = yaml.load(fi_data,Loader=yaml.FullLoader) data = yaml.load(fi_data,Loader=yaml.FullLoader)
self.getGetPlayUrl = data["globalCon"]["getPlayUrl"] self.getGetPlayUrl = data["globalCon"]["getPlayUrl"]
...@@ -308,6 +310,16 @@ class CameraArea(): ...@@ -308,6 +310,16 @@ class CameraArea():
timeCur = "[" + timeCur + "] " timeCur = "[" + timeCur + "] "
return timeCur return timeCur
####################################################
# 获取当前时间(不加括号)
####################################################
def getCurTimeO(self):
timeCur = int(time.time() * 1000)
timeArray = time.localtime(timeCur / 1000)
timeCur = time.strftime("%Y年%m月%d日--%H时%M分%S秒", timeArray)
timeCur = timeCur
return timeCur
#################################################### ####################################################
# 断网 # 断网
#################################################### ####################################################
...@@ -531,4 +543,110 @@ class CameraArea(): ...@@ -531,4 +543,110 @@ class CameraArea():
def setLogRedirect(self): def setLogRedirect(self):
if globalParams.isLogRedirect == 1: if globalParams.isLogRedirect == 1:
sys.stdout = self.logTextCtr sys.stdout = self.logTextCtr
sys.stderr = self.logTextCtr sys.stderr = self.logTextCtr
\ No newline at end of file
####################################################
# 获取视频时长
####################################################
def getVideoDur(self,theFile):
cmd = 'ffprobe.exe -show_format ' + theFile
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True
)
p.wait()
out = p.stdout.read()
dur = re.findall('duration=(.*)\r', out.decode("utf-8"))[0]
dur = int(float(dur))
return dur
####################################################
# 秒数转换为时间格式
####################################################
def timeConvert(self,second):
seconds = second
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
timeC = ("%02d:%02d:%02d" % (h, m, s))
return timeC
####################################################
# 剪切视频
####################################################
def splitVideo(self,startTime,dur,inFi,outFi):
startTime = self.timeConvert(startTime)
dur = self.timeConvert(dur)
m_command = ["ffmpeg.exe", "-ss", startTime, "-t", dur, "-i", inFi, "-vcodec", "copy",
"-acodec", "copy", outFi]
subprocess.run(m_command)
####################################################
# 上传文件
####################################################
def uploadFile(self,cam,filePath,iscapture,time):
params = {}
imei = globalParams.homeArea.getDevCodeText().GetValue()
lat = globalParams.eventArea.getLatTextCtr().GetValue()
lng = globalParams.eventArea.getLngTextCtr().GetValue()
with open(filePath,"rb") as fi:
files = {'file': fi}
params["fileaddress"] = "/aaa"
params["cam"] = cam
params["imei"] = imei
params["iscapture"] = iscapture
params["lat"] = lat
params["lng"] = lng
params["time"] = time
res = requests.post("http://api-test.vandyo.com/mirror/upload/file",files=files, params=params)
####################################################
# 视频抓拍
####################################################
def videoCapture(self,cam,replyMsg,ws):
threadObj = threading.Thread(target=self.doVideoCapture,args=(cam,replyMsg,ws,))
threadObj.start()
def doVideoCapture(self,cam,replyMsg,ws):
cutTime = self.getCurTime()
if self.pushObj == None:
wx.CallAfter(pub.sendMessage, "showLog" + str(self.channel), msg=cutTime + "未推流,不可进行视频抓拍!")
else:
capTime = self.pushObj.getTimeStamp()
capTime = int(capTime / 1000)
capdur = 5
inFi = self.videoPathText.GetValue()
videoLen = self.getVideoDur(inFi)
curtimeO = self.getCurTimeO()
curPath = sys.path[0]
outFi = curPath + "/SDCard/video/" + curtimeO + "_" + str(videoLen) + "__" + str(capTime) + ".mp4"
self.splitVideo(capTime, capdur,inFi, outFi)
timeCur = int(time.time())
self.uploadFile(cam, outFi, 2, timeCur)
ws.sendMsg(replyMsg)
####################################################
# 图片抓拍
####################################################
def picCapture(self,cam,replyMsg,ws):
threadObj = threading.Thread(target=self.doPicCapture,args=(cam,replyMsg,ws,))
threadObj.start()
#"ffmpeg -i bbb.mp4 -frames:v 1 -ss 40 -f image2 bbb.jpg"
def doPicCapture(self,cam,replyMsg,ws):
cutTime = self.getCurTime()
if self.pushObj == None:
wx.CallAfter(pub.sendMessage, "showLog" + str(self.channel), msg=cutTime + "未推流,不可进行图片抓拍!")
else:
capTime = str(int(self.pushObj.getTimeStamp() / 1000))
inFi = self.videoPathText.GetValue()
curPath = sys.path[0]
videoLen = self.getVideoDur(inFi)
curtimeO = self.getCurTimeO()
outFi = curPath + "/SDCard/picture/" + curtimeO + "_" + str(videoLen) + "__" + str(capTime) + ".jpg"
m_command = ["ffmpeg.exe", "-i", inFi, "-frames:v", "1", "-ss", capTime, "-f", "image2", outFi]
subprocess.run(m_command)
timeCur = int(time.time())
self.uploadFile(cam,outFi,1,timeCur)
ws.sendMsg(replyMsg)
...@@ -32,6 +32,12 @@ class EventAndOtherArea(): ...@@ -32,6 +32,12 @@ class EventAndOtherArea():
self.logTextCtr = None # 日志输出框 self.logTextCtr = None # 日志输出框
def getLatTextCtr(self):
return self.latTextCtr
def getLngTextCtr(self):
return self.lngTextCtr
################################################# #################################################
# 创建一个顶级pannel # 创建一个顶级pannel
################################################# #################################################
...@@ -281,3 +287,5 @@ class EventAndOtherArea(): ...@@ -281,3 +287,5 @@ class EventAndOtherArea():
return data return data
...@@ -237,9 +237,9 @@ class HomeArea(): ...@@ -237,9 +237,9 @@ class HomeArea():
if msgType == "1": # 请求直播 if msgType == "1": # 请求直播
self.processStream(msgJson, replyMsg) self.processStream(msgJson, replyMsg)
elif msgType == "3": # 视频抓拍 elif msgType == "3": # 视频抓拍
pass self.processVideoCap(msgJson, replyMsg)
elif msgType == "4": # 图片抓拍 elif msgType == "4": # 图片抓拍
pass self.processPicCap(msgJson, replyMsg)
elif msgType == "5": # 视频回看 elif msgType == "5": # 视频回看
pass pass
elif msgType == "7": # 紧急救援 elif msgType == "7": # 紧急救援
...@@ -301,6 +301,41 @@ class HomeArea(): ...@@ -301,6 +301,41 @@ class HomeArea():
curTime = self.getCurTime() curTime = self.getCurTime()
self.logTextCtr.WriteText(curTime + "回复消息:" + replyMsg + "\n") self.logTextCtr.WriteText(curTime + "回复消息:" + replyMsg + "\n")
####################################################
# 处理视频抓拍
####################################################
def processVideoCap(self,msgJson,replyMsg):
cam = msgJson["data"]["cam"]
if cam == 1:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_1.videoCapture(cam,replyMsg,self.ws)
elif cam == 2:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_2.videoCapture(cam,replyMsg,self.ws)
elif cam == 3:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_3.videoCapture(cam,replyMsg,self.ws)
####################################################
# 处理图片抓拍
####################################################
def processPicCap(self,msgJson,replyMsg):
cam = msgJson["data"]["cam"]
if cam == 1:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_1.picCapture(cam,replyMsg,self.ws)
elif cam == 2:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_2.picCapture(cam,replyMsg,self.ws)
elif cam == 3:
replyMsg["type"] = "0"
replyMsg = json.dumps(replyMsg)
globalParams.camera_3.picCapture(cam,replyMsg,self.ws)
#################################################### ####################################################
# 日志重定向到日志框 # 日志重定向到日志框
......
...@@ -66,6 +66,7 @@ class MainWindow(): ...@@ -66,6 +66,7 @@ class MainWindow():
page4 = codecArea.create() page4 = codecArea.create()
nodeBook.AddPage(page4, "转码工具") nodeBook.AddPage(page4, "转码工具")
eventAndOtherArea = EventAndOtherArea(nodeBook) eventAndOtherArea = EventAndOtherArea(nodeBook)
globalParams.eventArea = eventAndOtherArea
page5 = eventAndOtherArea.create() page5 = eventAndOtherArea.create()
nodeBook.AddPage(page5, "告警与其他功能") nodeBook.AddPage(page5, "告警与其他功能")
boxSizer.Add(nodeBook, 1, flag=wx.EXPAND | wx.ALL) boxSizer.Add(nodeBook, 1, flag=wx.EXPAND | wx.ALL)
......
...@@ -4,5 +4,6 @@ homeArea = None # 首页对象 ...@@ -4,5 +4,6 @@ homeArea = None # 首页对象
camera_1 = None # 相机1 camera_1 = None # 相机1
camera_2 = None # 相机2 camera_2 = None # 相机2
camera_3 = None # 相机3 camera_3 = None # 相机3
eventArea = None # 事件发送对象
isLogRedirect = 1 # 日志是否重定向到日志文本框 0: 不重定向 (用于调试) 1:重定向 (用于给别人用) isLogRedirect = 0 # 日志是否重定向到日志文本框 0: 不重定向 (用于调试) 1:重定向 (用于给别人用)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment