实现Http发送Json数据利用ffmpeg实现MobaXterm终端每隔一定时间段提取视频和图片
1.使用到的软件
- VS Code:python编程软件
- Postman:用于发送
Http 请求 - MobaXterm终端:用于连接
RK3399 板子
2.代码
from ast import And
import socket
import json
import os
from time import sleep
import numpy as np
import subprocess
def get_video_duration(video_path: str):
ext = os.path.splitext(video_path)[-1]
if ext != '.mp4' and ext != '.avi' and ext != '.flv' and ext != '.ts':
raise Exception('format not support')
ffprobe_cmd = 'ffprobe -i {} -show_entries format=duration -v quiet -of csv="p=0"'
p = subprocess.Popen(
ffprobe_cmd.format(video_path),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
out, err = p.communicate()
duration_info = float(str(out, 'utf-8').strip())
return int(duration_info)
'''
调用方式:
1.先启动服务器
2.打开postman
3.选择传方式为post,输入网址:http://127.0.0.1:8000
4.输入发送内容(案例):
{"time":"20220405-173000","video_save_path":"C:/Users/pc/Desktop/20220922erro_photo_get/test_vedio/vedio","save_path":"C:/Users/pc/Desktop/20220922erro_photo_get/test_vedio/save/","time_interval":2,"img_number":7}
5.点击发送即可
'''
file_name_list=[]
video_path=""
def get_dict_value(in_dict, target_key, results=[], not_d=True):
for key in in_dict.keys():
data = in_dict[key]
if isinstance(data, dict):
get_dict_value(data, target_key, results=results, not_d=not_d)
if key == target_key and isinstance(data, dict) != not_d:
results.append(in_dict[key])
return results
host='0.0.0.0'
port=8000
addr=(host,port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(addr)
s.listen(3)
while True:
con, addr = s.accept()
request = con.recv(2048)
str_1=str(request,encoding='utf-8')
for i in range(len(str_1)):
if str_1[i]=='{':
flag_1=i
elif str_1[i]=='}':
flag_2=i
str_2="{"+str_1[flag_1+1:-1]+"}"
print(str_2,"type=",type(str_2))
json_str_data=json.loads(str_2)
img_path_data = get_dict_value(json_str_data,'time',results=[])
video_save_path_data =get_dict_value(json_str_data,'video_save_path',results=[])
save_path_data=get_dict_value(json_str_data,'save_path',results=[])
time_interval_data=get_dict_value(json_str_data,'time_interval',results=[])
img_number_data=get_dict_value(json_str_data,'img_number',results=[])
gain_video_time=img_path_data[0]
video_save_path=video_save_path_data[0]
save_path=save_path_data[0]
time_interval=time_interval_data[0]
img_number=img_number_data[0]
for root, dirs, files in os.walk(video_save_path):
file_name_list=files
for video_file_name in file_name_list:
filename=video_file_name.split('.')
if filename[0]==gain_video_time :
video_path=video_save_path+"/"+video_file_name
if video_path=="":
print("文件不存在,未找到!!!")
else:
print("文件存在,已找到!!!")
'''
cap=cv2.VideoCapture(video_path)
if cap!=0:
print("打开视频成功")
else:
print("打开视频失败")
n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) ##视频的帧数
fps = cap.get(cv2.CAP_PROP_FPS) ##视频的帧率
#输入时间根据时间计算所要跳转的帧数,单位ms
frameRate = int(fps) * time_interval * 60
time = n_frames / fps
'''
time=get_video_duration(video_path)
print("time=",time)
frame_time=0
currentFrame = 0
str_system_2="mkdir "+save_path+gain_video_time
os.system(str_system_2)
while True:
if frame_time < time and currentFrame<img_number:
print("正在截取第",frame_time,"秒的图片")
if frame_time<10:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:00:0'+str(frame_time)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
elif frame_time<60:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:00:'+str(frame_time)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
elif frame_time<3600:
min_data=frame_time//60
sec_data=frame_time%60
if min_data<10 and sec_data<10:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:0'+str(min_data)+':0'+str(sec_data)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
elif min_data<10 and sec_data>10:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:0'+str(min_data)+':'+str(sec_data)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
elif min_data>10 and sec_data<10:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:'+str(min_data)+':0'+str(sec_data)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
else:
str_system='ffmpeg -i'+' '+video_path+' '+'-ss 00:'+str(min_data)+':'+str(sec_data)+' '+'-t 2'+' '+'-c copy'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'+' && ffmpeg -i '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts -y -f image2 -ss 00:00:00 -vframes 1'+' '+save_path+gain_video_time+'/'+str(currentFrame)+'.jpg'+' '+'&& rm -f '+save_path+gain_video_time+'/'+str(currentFrame)+'.ts'
os.system(str_system)
frame_time=frame_time+time_interval
currentFrame=currentFrame+1
else:
print("该视频已经截取完\n")
break
con.close()
3.代码简单讲解
get_dict_value 函数:用于传来的Json数据的键值对(key-value)0.0.0.0 :为网络地址,使得HTTP发送方与HTTP接收方能够建立起通讯port=8000 :为指定端口号- 在
while 循环中,使用了ffmpeg 系统命令,通过Python 的os 库中的system 接口来实现
4. 细节
- 本代码实现了对于每隔固定时长提取
2s 视频的操作,同时通过提取这2s 视频的第一帧实现每隔固定时长提取视频中的一帧图片 - 提取从视频的
00:00:00 开始,每隔一定时间(单位:秒)提取图片,为了防止时间累加后导致读取图片为NULL 增加了opencv 中读取视频时长的操作,以防溢出
5.知识学习与软件应用
- postman软件
- 利用socket实现http通信
|