未验证 提交 997c3882 编写于 作者: D dp 提交者: GitHub

Mask detection (#373)

* Add mask detection demo
上级 b8730bce
# 百度PaddlePaddle实现口罩检测应用
## 0 项目介绍
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/BB6BC87A45D146CEBA7BF237B5383835?ynotemdtimestamp=1582271320612)
### [>点击查看视频链接<](https://www.bilibili.com/video/av88962128)
##### 背景
本项目可以部署在大型场馆出入口,学校,医院,交通通道出入口,人脸识别闸机,机器人上,支持的方案有:安卓方案(如RK3399的人脸识别机,机器人),ubuntu 边缘计算,windowsPC+摄像头,识别率80%~90%,如果立项使用场景可以达到 99% (如:人脸识别机场景)。但是限于清晰度和遮挡关系,对应用场景有一些要求。
##### 效果分析
可以看到识别率在80~90%之前,稍小的人脸有误识别的情况,有些挡住嘴的场景也被误识别成了戴口罩,一个人带着口罩,鼻子漏出来识别成没有戴口罩,这个是合理的因为的鼻子漏出来是佩戴不规范。初步判断,这个模型应用在门口,狭长通道,人脸识别机所在位置都是可以的。
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/7E12DBD91D1D4AB5B33C84786D519065?ynotemdtimestamp=1582271320612)![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/2BD974FB990C4C448B30B04194545054?ynotemdtimestamp=1582271320612)![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/E49E34A071F8484D948511430FAB0360?ynotemdtimestamp=1582271320612)
## 1 部署环境
参考: https://www.paddlepaddle.org.cn/install/quick
### 安装paddlehub
`pip install paddlehub`
## 2 开发识别服务
### 加载预训练模型
```python
import paddlehub as hub
module = hub.Module(name="pyramidbox_lite_mobile_mask") #口罩检测模型
```
>以上语句paddlehub会自动下载口罩检测模型 "pyramidbox_lite_mobile_mask" 不需要提前下载模型
### OpenCV打开摄像头或视频文件
```python
import cv2
capture = cv2.VideoCapture(0) # 打开摄像头
# capture = cv2.VideoCapture('./2.mp4') # 打开视频文件
while(1):
ret, frame = capture.read() # frame即视频的一帧数据
if ret == False:
break
cv2.imshow('Mask Detection', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
```
### 口罩检测
```python
# frame为一帧数据
input_dict = {"data": [frame]}
results = module.face_detection(data=input_dict)
print(results)
```
输出结果:
```json
[
{
"data": {
"label": "MASK",
"left": 258.37087631225586,
"right": 374.7980499267578,
"top": 122.76758193969727,
"bottom": 254.20085906982422,
"confidence": 0.5630852
},
"id": 1
}
]
```
>"label":是否戴口罩,"confidence":置信度,其余字段为脸框的位置大小
### 将结果显示到原视频帧中
```python
# results为口罩检测结果
for result in results:
# print(result)
label = result['data']['label']
confidence = result['data']['confidence']
top, right, bottom, left = int(result['data']['top']), int(result['data']['right']), int(result['data']['bottom']), int(result['data']['left'])
color = (0, 255, 0)
if label == 'NO MASK':
color = (0, 0, 255)
cv2.rectangle(frame, (left, top), (right, bottom), color, 3)
cv2.putText(frame, label + ":" + str(confidence), (left, top-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
```
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/F85FCBCA17994C8691024381CBDAFCA7?ynotemdtimestamp=1582271320612)
>原DEMO中是英文+置信度显示在框的上面,尝试改为中文,遇到字体问题,以下是解决办法
### 图片写入中文
需要事先准备ttf/otf等格式的字体文件
```python
def paint_chinese_opencv(im,chinese,position,fontsize,color_bgr):#opencv输出中文
img_PIL = Image.fromarray(cv2.cvtColor(im,cv2.COLOR_BGR2RGB))# 图像从OpenCV格式转换成PIL格式
font = ImageFont.truetype('思源黑体SC-Heavy.otf',fontsize,encoding="utf-8") # 加载字体文件
#color = (255,0,0) # 字体颜色
#position = (100,100)# 文字输出位置
color = color_bgr[::-1]
draw = ImageDraw.Draw(img_PIL)
draw.text(position,chinese,font=font,fill=color)# PIL图片上打印汉字 # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
img = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)# PIL图片转cv2 图片
return img
```
```python
for result in results:
# print(result)
label = result['data']['label']
confidence = result['data']['confidence']
top, right, bottom, left = int(result['data']['top']), int(result['data']['right']), int(result['data']['bottom']), int(result['data']['left'])
color = (0, 255, 0)
label_cn = "有口罩"
if label == 'NO MASK':
color = (0, 0, 255)
label_cn = "无口罩"
cv2.rectangle(frame, (left, top), (right, bottom), color, 3)
# cv2.putText(frame, label + ":" + str(confidence), (left, top-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
frame = paint_chinese_opencv(frame, label_cn + ":" + str(confidence), (left, top-36), 24, color)
```
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/4F75E5C6F42F4C3CBE1341742D032847?ynotemdtimestamp=1582271320612)
### 提取头像文件
```python
img_name = "avatar_%d.png" % (maskIndex)
path = "./result/" + img_name
image = frame[top - 10: bottom + 10, left - 10: right + 10]
cv2.imwrite(path, image,[int(cv2.IMWRITE_PNG_COMPRESSION), 9])
```
### 结果写入JSON
```python
with open("./result/2-mask_detection.json","w") as f:
json.dump(data, f)
```
>此处可以按照自己的应用需要改为输出到mysql,Redis,kafka ,MQ 供应用消化数据
### 完整代码如下
```python
import paddlehub as hub
import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import json
import os
module = hub.Module(name="pyramidbox_lite_mobile_mask")
def paint_chinese_opencv(im,chinese,position,fontsize,color_bgr):#opencv输出中文
img_PIL = Image.fromarray(cv2.cvtColor(im,cv2.COLOR_BGR2RGB))# 图像从OpenCV格式转换成PIL格式
font = ImageFont.truetype('思源黑体SC-Heavy.otf',fontsize,encoding="utf-8") # 加载字体文件
#color = (255,0,0) # 字体颜色
#position = (100,100)# 文字输出位置
color = color_bgr[::-1]
draw = ImageDraw.Draw(img_PIL)
draw.text(position,chinese,font=font,fill=color)# PIL图片上打印汉字 # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
img = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)# PIL图片转cv2 图片
return img
result_path = './result'
if not os.path.exists(result_path):
os.mkdir(result_path)
name = "./result/1-mask_detection.mp4"
width = 1920
height = 1080
fps = 30
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter(name, fourcc, fps, (width, height))
maskIndex = 0
index = 0
data = []
# capture = cv2.VideoCapture(0) # 打开摄像头
capture = cv2.VideoCapture('./2.mp4') # 打开视频文件
while(1):
frameData = {}
ret, frame = capture.read() # frame即视频的一帧数据
if ret == False:
break
frame_copy = frame.copy()
input_dict = {"data": [frame]}
results = module.face_detection(data=input_dict)
# print(results)
maskFrameDatas = []
for result in results:
# print(result)
label = result['data']['label']
confidence_origin = result['data']['confidence']
confidence = round(confidence_origin, 2)
confidence_desc = str(confidence)
top, right, bottom, left = int(result['data']['top']), int(result['data']['right']), int(result['data']['bottom']), int(result['data']['left'])
#将当前帧保存为图片
img_name = "avatar_%d.png" % (maskIndex)
path = "./result/" + img_name
image = frame[top - 10: bottom + 10, left - 10: right + 10]
cv2.imwrite(path, image,[int(cv2.IMWRITE_PNG_COMPRESSION), 9])
maskFrameData = {}
maskFrameData['top'] = top
maskFrameData['right'] = right
maskFrameData['bottom'] = bottom
maskFrameData['left'] = left
maskFrameData['confidence'] = float(confidence_origin)
maskFrameData['label'] = label
maskFrameData['img'] = img_name
maskFrameDatas.append(maskFrameData)
maskIndex += 1
color = (0, 255, 0)
label_cn = "有口罩"
if label == 'NO MASK':
color = (0, 0, 255)
label_cn = "无口罩"
cv2.rectangle(frame_copy, (left, top), (right, bottom), color, 3)
# cv2.putText(frame, label, (left, top-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
frame_copy = paint_chinese_opencv(frame_copy, label_cn, (left, top-36), 24, color)
writer.write(frame_copy)
cv2.imshow('Mask Detection', frame_copy)
frameData['frame'] = index
# frameData['seconds'] = int(index/fps)
frameData['data'] = maskFrameDatas
data.append(frameData)
print(json.dumps(frameData))
index += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
with open("./result/2-mask_detection.json","w") as f:
json.dump(data, f)
writer.release()
cv2.destroyAllWindows()
```
## 3 制作网页呈现效果
此DEMO是显示一个固定视频,分析导出的 json 渲染到网页里面,如需实时显示需要再次开发
### python 导出的数据
使用上面的 python 文件完整执行后会有3个种类的数据输出,放到`web/video/result`目录下
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/329AC9C2D89447EABE6B8C45D620441E?ynotemdtimestamp=1582271320612)
### json数据结构
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/5D46F32061B047D4AB0AC016FE2A63A5?ynotemdtimestamp=1582271320612)
### 使用数据渲染网页
- 网页中左侧 "视频播放视频区",播放同时实时回调当前播放的时间点
- 根据时间点换算为帧(1秒30帧),遍历 json 数据中的数据
- 把数据中对应的数据输出到网页右侧 "信息区"
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/6329B326216A4950BF35E0CB37CDC58F?ynotemdtimestamp=1582271320612)
## 4 欢迎交流
**百度飞桨合作伙伴:**
![image](https://note.youdao.com/yws/public/resource/b0a4695bc7d58aed3b1ff797409aee1e/DC72DE1CF51747138871BB0E3D54E20D?ynotemdtimestamp=1582271320612)
北京奇想天外科技有限公司
import paddlehub as hub
import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import json
import os
module = hub.Module(name="pyramidbox_lite_mobile_mask")
#opencv输出中文
def paint_chinese(im, chinese, position, fontsize, color_bgr):
img_PIL = Image.fromarray(cv2.cvtColor(
im, cv2.COLOR_BGR2RGB)) # 图像从OpenCV格式转换成PIL格式
font = ImageFont.truetype('思源黑体SC-Heavy.otf', fontsize, encoding="utf-8")
#color = (255,0,0) # 字体颜色
#position = (100,100)# 文字输出位置
color = color_bgr[::-1]
draw = ImageDraw.Draw(img_PIL)
# PIL图片上打印汉字 # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
draw.text(position, chinese, font=font, fill=color)
img = cv2.cvtColor(np.asarray(img_PIL), cv2.COLOR_RGB2BGR) # PIL图片转cv2 图片
return img
result_path = './result'
if not os.path.exists(result_path):
os.mkdir(result_path)
name = "./result/1-mask_detection.mp4"
width = 1920
height = 1080
fps = 30
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter(name, fourcc, fps, (width, height))
maskIndex = 0
index = 0
data = []
# capture = cv2.VideoCapture(0) # 打开摄像头
capture = cv2.VideoCapture('./2.mp4') # 打开视频文件
while (1):
frameData = {}
ret, frame = capture.read() # frame即视频的一帧数据
if ret == False:
break
frame_copy = frame.copy()
input_dict = {"data": [frame]}
results = module.face_detection(data=input_dict)
# print(results)
maskFrameDatas = []
for result in results:
# print(result)
label = result['data']['label']
confidence_origin = result['data']['confidence']
confidence = round(confidence_origin, 2)
confidence_desc = str(confidence)
top, right, bottom, left = int(result['data']['top']), int(
result['data']['right']), int(result['data']['bottom']), int(
result['data']['left'])
#将当前帧保存为图片
img_name = "avatar_%d.png" % (maskIndex)
path = "./result/" + img_name
image = frame[top - 10:bottom + 10, left - 10:right + 10]
cv2.imwrite(path, image, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])
maskFrameData = {}
maskFrameData['top'] = top
maskFrameData['right'] = right
maskFrameData['bottom'] = bottom
maskFrameData['left'] = left
maskFrameData['confidence'] = float(confidence_origin)
maskFrameData['label'] = label
maskFrameData['img'] = img_name
maskFrameDatas.append(maskFrameData)
maskIndex += 1
color = (0, 255, 0)
label_cn = "有口罩"
if label == 'NO MASK':
color = (0, 0, 255)
label_cn = "无口罩"
cv2.rectangle(frame_copy, (left, top), (right, bottom), color, 3)
# cv2.putText(frame, label, (left, top-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2)
origin_point = (left, top - 36)
frame_copy = paint_chinese(frame_copy, label_cn, origin_point, 24,
color)
writer.write(frame_copy)
cv2.imshow('Mask Detection', frame_copy)
frameData['frame'] = index
# frameData['seconds'] = int(index/fps)
frameData['data'] = maskFrameDatas
data.append(frameData)
print(json.dumps(frameData))
index += 1
if cv2.waitKey(1) & 0xFF == ord('q'):
break
with open("./result/2-mask_detection.json", "w") as f:
json.dump(data, f)
writer.release()
cv2.destroyAllWindows()
/*reset*/
*{ margin: 0; padding: 0; box-sizing: border-box; }
body{ font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Noto Sans CJK SC,WenQuanYi Micro Hei,Arial,sans-serif; font-size: 14px; line-height: 1.4; color: #fff; -webkit-font-smoothing: antialiased; background: #2f3242;}
ul,ol{ list-style-type: none; }
a{ text-decoration: none; transition: all .2s ease; -webkit-transition: all .2s ease;}
img{border: none; }
table{ border-collapse:collapse; border-spacing:0; }
p{ line-height: 1.4 }
a {color: #333;}
a:hover {color: #666;}
input{ outline: none; }
button {background: none;border:none}
.clear:after{ content: " "; clear: both; display: block; }
h1,h2,h3,h4,h5,h6{font-style: normal;margin:0;padding:0;font-weight: normal;}
.clear:after{ content: " "; clear: both; display: block; }
.header {height:95px;padding-left:95px;padding-right:25px;}
.header .logo{padding-left:0px;padding-top:25px;}
.header .right-bar {float: right;padding-top:20px;}
.header .search {width: 313px;
height: 48px;
border: 2px solid #fff; /* stroke */
-moz-border-radius: 26px;
-webkit-border-radius: 26px;
border-radius: 26px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background: url(../image/search.png) 10px center no-repeat;
padding-left:50px;
color: #fff;
font-size: 16px;
}
.header .icon {display: inline-block;margin-left:40px;width:31px;height: 31px;vertical-align: middle;position: relative;}
.icon1 {background: url(../image/icon1.png) no-repeat center center;}
.icon2 {background: url(../image/icon2.png) no-repeat center center;}
.header .avatar {width:56px;height: 56px;border-radius: 100%;overflow: hidden;display: inline-block;margin-left:40px;vertical-align: middle;}
.header .right-bar .news-dot {
width: 15px;
height: 15px;
border: 3px solid #2f3141; /* stroke */
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
border-radius: 9px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #2195f3; /* layer fill content */
position: absolute;
right:0px;
top:0px;
}
.header .arrow {display: inline-block;background: url(../image/arrow.png) no-repeat 0 0;width:12px;height: 8px;margin-left:10px;}
.bd {padding-left:95px;position: relative;background: #2f3242;}
.bd .side {width:95px;position: absolute;left:0;top:0;}
.bd .con {background: #2b2d3c;}
.bd .con .hd {background: #6d7499;color: #fff;font-size: 18px;padding:0 25px 0 60px;line-height: 60px;height: 60px;}
.bd.chart {padding:0;}
.bd .con .hd .right-bar {float:right;}
.select-wrap {min-width: 150px;margin-top:10px;line-height: 38px;
height: 38px;
border-radius: 19px;
position: relative;
border:1px solid #9da3bd;
display: inline-block;
color: #fff;
margin-left:20px;
}
.select-wrap select {border: none;
outline: none;
width: 100%;
height: 40px;
line-height: 40px;
background: transparent;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
font-size: 16px;
color: #fff;
padding-left: 20px;}
.select-wrap:after{
content: "";
width: 14px;
height: 8px;
background: url(../image/arrow.png) no-repeat center;
position: absolute;
right: 20px;
top: 45%;
pointer-events: none;
}
.con-bd {position: relative;min-height: 960px;}
.maper {padding-left:380px;}
.con-left {left:0;top:0;position: absolute;width:380px;min-height: 960px;}
.con-left .map {padding:20px;}
.con-left .ctr-pan {position:absolute;bottom:20px;left:0;width:380px;color: #fff;}
.con-left .ctr-pan ul{padding-left:20px;}
.con-left .ctr-pan li {padding:5px 0;}
.con-left .ctr-pan .icon {width:23px;height: 23px;display: inline-block;vertical-align: middle;margin-right:10px;}
.con-left .ctr-pan .icon3 {background: url(../image/icon3.png) no-repeat center center;}
.icon4 {background: url(../image/icon4.png) no-repeat center center;}
.con-left .ctr-pan .icon5 {background: url(../image/icon5.png) no-repeat center center;}
.con-left .ctr-pan .switch {border:2px solid #aaaaaa;border-radius:8px;height:15px;width:30px;display: inline-block;line-height: 15px;position: relative;vertical-align: middle;margin-left:10px;}
.con-left .ctr-pan .switch em {width: 7px;
height: 7px;
-moz-border-radius: 4px / 3px;
-webkit-border-radius: 4px / 3px;
border-radius: 4px / 3px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #aaa; /* layer fill content */
display: inline-block;
vertical-align: middle;
position: absolute;
top:2px;
}
.con-left .ctr-pan .switch.on em{left:16px;}
.con-left .ctr-pan .switch.off em{left:2px;}
.map-wrap {padding:20px 0 0 0;}
.map-wrap img {}
.zoom-bar {
width: 49px;
height: 231px;
border: 3px solid #757da3; /* stroke */
-moz-border-radius: 27px;
-webkit-border-radius: 27px;
border-radius: 27px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #2f3141; /* layer fill content */
position: absolute;
right:50px;
top:30%;
text-align: center;
}
.zoom-bar .icon {width:30px;height: 30px;display: inline-block;}
.zoom-bar .zoom {background: url(../image/zoom.png) no-repeat center center;margin-top:5px;}
.zoom-bar .narrow {background: url(../image/narrow.png) no-repeat center center;margin-top:55px;}
.zoom-bar .mouse {background: url(../image/mu.png) no-repeat center center;margin-top:58px;}
.side .nav {padding-top:118px;}
.side .nav a{display: block;width:95px;height: 95px;margin:100px 0 0 0;position: relative;}
.side .nav a:hover {background-color: #2c2e3d;}
.side .nav .nav1 {background-image: url(../image/nav1.png);background-repeat: no-repeat;background-position: center center;}
.side .nav .nav2 {background-image: url(../image/nav2.png);background-repeat: no-repeat;background-position: center center;}
.side .nav .nav3 {background-image: url(../image/nav3.png);background-repeat: no-repeat;background-position: center center;}
.side .news-dot {
width: 15px;
height: 15px;
border: 3px solid #2f3141; /* stroke */
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
border-radius: 9px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #2195f3; /* layer fill content */
position: absolute;
left:55px;
top:30px;
}
.side .nav a.current {background-color: #2c2e3d;}
.person-list {font-size: 16px;padding-left:60px;}
.person-list table {width:100%;}
.person-list thead td{color: #9ea3b4;height:70px;line-height: 70px;text-align: center;background: none;}
.person-list td {color: #fff;text-align: center;padding:10px 0;}
.person-list .pro .item {display: inline-block;}
.person-list .pro .item span {display:block;width:33px;height: 33px;margin:0 10px;margin-bottom:5px;}
.t1 {background: url(../image/t1.png) no-repeat center center;}
.t2 {background: url(../image/t2.png) no-repeat center center;}
.t3 {background: url(../image/t3.png) no-repeat center center;}
.t4 {background: url(../image/t4.png) no-repeat center center;}
.t5 {background: url(../image/t5.png) no-repeat center center;}
.t6 {background: url(../image/t6.png) no-repeat center center;}
.t7 {background: url(../image/t7.png) no-repeat center center;}
.person-list .dot {background: url(../image/dot.png) no-repeat 0 0;width:4px;height: 16px;display: inline-block;}
.person-list .time {font-size: 14px;color: #9ea3b4;}
.person-list tr:nth-child(odd) td {background: #3a3e52;}
.person-list thead tr:nth-child(odd) td {background: none;}
.person-list tr:nth-child(even) td {height:20px;}
.person-list tr td:last-child {padding:10px 10px;}
.line-female {border-left:4px solid #ed70bc;}
.line-male {border-left:4px solid #2196f3;}
.line-child {border-left:4px solid #e2e3e8;}
.mask {background: rgba(0,0,0,.90);position: absolute;width: 100%;height: 100%;left: 0;top:0;z-index: 99;}
.mask .cp {background: url(../image/cp.png) no-repeat 0 0 ;width:154px;height: 59px;margin:10% auto 0 auto;}
.drop-area {
width: 247px;
height: 247px;
border:4px dotted #fff;
border-radius: 30px;
background: url(../image/icon6.png) no-repeat center 50px;
margin:10% auto 50px auto;
}
.drop-area .text {font-size: 20px;text-align: center;color: #fff;margin-top:170px;}
.match-box {text-align: center;width:470px;margin: auto;color: #fff;font-size: 20px;}
.match-box .match-bar {width: 316px;
height: 8px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #252734; /* layer fill content */
-moz-box-shadow: 0 0 48px rgba(0,0,0,.14); /* outer glow */
-webkit-box-shadow: 0 0 48px rgba(0,0,0,.14); /* outer glow */
box-shadow: 0 0 48px rgba(0,0,0,.14); /* outer glow */
position: relative;
display: inline-block;
margin:0 10px;
vertical-align: middle;
}
.match-box .match-bar span {
height: 8px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #71799f; /* layer fill content */
position: absolute;
left: 0;
top:0;
}
.match-box .match-bar span em {
width: 25px;
height: 25px;
-moz-border-radius: 12px / 13px;
-webkit-border-radius: 12px / 13px;
border-radius: 12px / 13px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #fff; /* layer fill content */
-moz-box-shadow: 0 5px 5px rgba(0,0,0,.13); /* drop shadow */
-webkit-box-shadow: 0 5px 5px rgba(0,0,0,.13); /* drop shadow */
box-shadow: 0 5px 5px rgba(0,0,0,.13); /* drop shadow */
position: absolute;
right:0;
top:-8px;
}
.match-res-box {text-align: center;margin:60px auto 80px auto;width:320px;counter-reset: #fff;font-size: 17px;}
.match-avatar {
width: 98px;
height: 98px;
-moz-border-radius: 49px;
-webkit-border-radius: 49px;
border-radius: 49px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #6b7397; /* layer fill content */
overflow: hidden;
background: #6c7398;
margin: auto;
}
.match-res-box .text {text-align: center;margin-top:15px;}
.match-res-box .text span {font-weight: bold;}
.avatar-s {width: 56px;
height: 56px;
-moz-border-radius: 28px;
-webkit-border-radius: 28px;
border-radius: 28px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #ed6fbb; /* layer fill content */
display: inline-block;
overflow: hidden;
vertical-align: middle;
margin-right:20px;
}
.camera-list {padding:75px 0 0 90px;}
.camera-list li {float: left;width:400px;padding:0 40px 40px 40px;text-align: center;}
.camera-list .video-box {
width: 315px;
height: 236px;
-moz-border-radius: 24px;
-webkit-border-radius: 24px;
border-radius: 24px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #37394b; /* layer fill content */
overflow: hidden;
}
.camera-list li p {height: 44px;line-height: 44px;font-size: 18px;}
.camera-list li .icon {width:23px;height: 23px;display: inline-block;vertical-align: middle;margin-right:10px;}
.camera-con {padding-right:350px;position: relative;margin-top:40px;padding-left:40px;}
.camera-con .list {width:240px;position: absolute;right:50px;top:0;text-align: center;}
.camera-con .list li {margin-bottom:30px;}
.camera-con .list li .ca {width:240px;height: 178px;overflow: hidden;border-radius: 20px;}
.video-box {width:100%;}
.camera-con .list li p {padding:10px 0 0 0;}
.camera-con .list li .icon {width: 23px;
height: 23px;
display: inline-block;
vertical-align: middle;
margin-right: 10px;}
.tab li {float: left;}
.tab a {font-size: 18px;display: block;width: 180px;height: 58px;list-style: 58px;text-align: center;color: #fff;}
.tab a:hover,
.tab a.current {background: #8088ad;}
.chart .con .hd {padding-left:130px;}
.chart-bd {padding:20px;}
.chart-panel {padding-bottom:20px;}
.left-panel {width:790px;height:380px;float: left;background: #2f3242;padding:10px 20px;}
.right-panel {width:1040px;height: 380px;float: left;margin-left:20px;}
.panel-hd .right-bar {float:right;color: #9ea3b4;font-size: 16px;}
.panel-hd {font-size: 25px;color:#fff;height:70px;}
.panel-hd .select-wrap select{color: #9ea3b4;font-size: 16px;}
.right-panel .panel-hd {background: #3a3e52;height:96px;line-height: 96px;font-size: 25px;color: #fff;text-align: center;}
.right-panel .list {height:65px;padding:30px 0;}
.right-panel .list li {padding:30px 100px 30px 85px;position: relative;border-bottom:1px solid #505464;}
.right-panel .list li .avatar {
width: 42px;
height: 42px;
-moz-border-radius: 21px;
-webkit-border-radius: 21px;
border-radius: 21px; /* border radius */
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box; /* prevents bg color from leaking outside the border */
background-color: #9ba1b1; /* layer fill content */
display: block;
position: absolute;
left:25px;
}
.right-panel .list li .time {font-size: 16px;color: #fff;}
.right-panel .list li .text {color: #9ea3b4;}
.right-panel .list li .dot {position: absolute;right:25px;background: url(../image/dot.png) no-repeat center center;width:4px;height: 16px;top:40px;}
<?php
$json_string = file_get_contents(".\\video\\result\\2-mask_detection.json");
// 用参数true把JSON字符串强制转成PHP数组
$data_o = json_decode($json_string, true);
?>
<script language="javascript">
var pic_data = new Array();
<?php
for($i=0;$i<count($data_o);$i++){
$frame=$data_o[$i]["frame"];
$data_1=$data_o[$i]["data"];
for($j=0;$j<count($data_1);$j++){
?>
pic_data[<?php echo $frame;?>] = <?php echo json_encode($data_1);?>;
// pic_data[<?php echo $frame;?>] = 1;
<?php
}
}
?>
</script>
<?php
//摄像机位置,及视野宽高
$cams = array();
//雷达区图片
$area_w=250;
$area_h=500;
//cam图片大小
$cam_w=21;
$cam_h=23;
//vide宽高
$vide_w=1280;
$vide_h=720;
$cams[0]["cam_x"]=645;
$cams[0]["cam_y"]=243;
$cams[0]["cam_area_rotate"]=270;
$cams[0]["cam_area_w"]=0.4; //比例
$cams[0]["cam_area_h"]=0.8;
$cams[1]["cam_x"]=888;
$cams[1]["cam_y"]=167;
$cams[1]["cam_area_rotate"]=180;
$cams[1]["cam_area_w"]=0.6; //比例
$cams[1]["cam_area_h"]=1;
$cams[2]["cam_x"]=1051;
$cams[2]["cam_y"]=163;
$cams[2]["cam_area_rotate"]=270;
$cams[2]["cam_area_w"]=0.3; //比例
$cams[2]["cam_area_h"]=1;
$cams[3]["cam_x"]=893;
$cams[3]["cam_y"]=257;
$cams[3]["cam_area_rotate"]=275;
$cams[3]["cam_area_w"]=1; //比例
$cams[3]["cam_area_h"]=1;
$cams[4]["cam_x"]=714;
$cams[4]["cam_y"]=304;
$cams[4]["cam_area_rotate"]=90;
$cams[4]["cam_area_w"]=0.2; //比例
$cams[4]["cam_area_h"]=0.5;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<meta name="viewport" content="width=device-width" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />
<link rel="stylesheet" type="text/css" href="css/css.css">
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/echarts.js"></script>
<style type="text/css">
body {
margin: 0;
padding: 0px;
font-family: "Microsoft YaHei", YaHei, "微软雅黑", SimHei, "黑体";
font-size: 14px;
}
.box {
}
.cam {
position: absolute;
border: none;
}
.area {
cursor: pointer;
z-index: 999;
}
</style>
</head>
<body>
<div class="header">
<div class="right-bar">
<input type="text" class="search">
<span class="icon icon1"></span> <span class="icon icon2"></span>
<div class="avatar"><img src="image/ava.png" alt=""></div>
<span class="arrow"></span> </div>
<div class="logo"><img src="image/logo.png" alt="" style="font-size:120px;"></div>
</div>
<div class="bd">
<div class="side">
<div class="nav">
<ul>
<li><a href="#" class="nav1 current"></a></li>
<li><a href="#" class="nav2"></a></li>
<li><a href="#" class="nav3"></a></li>
</ul>
</div>
</div>
<div class="con">
<div class="hd clear">
<div class="right-bar">摄像头分组显示 <span class="select-wrap">
<select name="">
<option value="A区摄像头">A区摄像头</option>
<option value="A区摄像头">A区摄像头</option>
</select>
</span> </div>
<span class="tit">摄像头_1</span> </div>
<div class="con-bd">
<div class="map-wrap">
<div class="zoom-bar"> <span class="icon zoom "></span> <span class="icon mouse"></span> <span class="icon narrow"></span> </div>
<div class="box">
<table width="1870" border="0" cellspacing="10">
<tr>
<td width="44%" valign="top"><p></p>
<!-- (拖拽在回来可能会有问题 TODO) -->
<div id="video" style="width: 1000px; height:560px;"></div>
<script type="text/javascript" src="js/ckplayer/ckplayer.js" charset="UTF-8"></script>
<script type="text/javascript">
var videoObject = {
container: '#video', //容器的ID或className
variable: 'player', //播放函数名称
loop: true, //播放结束是否循环播放
loaded: "loadedHandler",
autoplay: true,//是否自动播放
drag: 'start', //拖动的属性
video: [
['video/result/222.mp4', 'video/mp4', '中文标清', 0],
]
};
var player = new ckplayer(videoObject);
function timeHandler(time) {
$(".no_pmask").html("");
$(".pmask").html("");
var rtime = parseInt(time*1000);
frame=parseInt(time*30); //每秒30帧 第多少帧
for (i = 0; i < pic_data[frame].length; i++) {
if(pic_data[frame][i].label=="NO MASK"){
$(".no_pmask").append("<img src='video/result/"+pic_data[frame][i].img+"' height=100>");
} else {
$(".pmask").append("<img src='video/result/"+pic_data[frame][i].img+"' height=100>");
}
}
}
function seekTimeHandler(time) {
var rtime = parseInt(time*1000);
$(".seekstate").html(rtime);
}
function loadedHandler() {
player.addListener('time', timeHandler); //监听播放时间
player.addListener('seekTime', seekTimeHandler); //监听跳转播放完
/*
player.addListener('error', errorHandler); //监听视频加载出错
player.addListener('loadedmetadata', loadedMetaDataHandler); //监听元数据
player.addListener('duration', durationHandler); //监听播放时间
player.addListener('play', playHandler); //监听暂停播放
player.addListener('pause', pauseHandler); //监听暂停播放
player.addListener('buffer', bufferHandler); //监听缓冲状态
player.addListener('seek', seekHandler); //监听跳转播放完成
player.addListener('volume', volumeChangeHandler); //监听音量改变
player.addListener('full', fullHandler); //监听全屏/非全屏切换
player.addListener('ended', endedHandler); //监听播放结束
player.addListener('screenshot', screenshotHandler); //监听截图功能
player.addListener('mouse', mouseHandler); //监听鼠标坐标
player.addListener('frontAd', frontAdHandler); //监听前置广告的动作
player.addListener('wheel', wheelHandler); //监听视频放大缩小
player.addListener('controlBar', controlBarHandler); //监听控制栏显示隐藏事件
player.addListener('clickEvent', clickEventHandler); //监听点击事件
player.addListener('definitionChange', definitionChangeHandler); //监听清晰度切换事件
player.addListener('speed', speedHandler); //监听加载速度*/
}
</script>
<br>
</td>
<td width="56%" valign="top">
<p style="padding:0 0 0 40px; font-size:30px; color:red; backgroud-color:#b3b6c7">无口罩</p>
<p class="no_pmask" style="padding:40px;"></p><br><br><br><br>
<p style="padding:0 0 0 40px; font-size:30px; color:#08d814; backgroud-color:#b3b6c7">有口罩</p>
<p class="pmask" style="padding:40px; ;"></p>
</td>
</tr>
<tr>
<td colspan="2" valign="top"><div style="position:relative;"><img src="image/b2f2.png" width="1250"/>
<?php for($i=0;$i<count($cams);$i++){
$r = get_mast_postion($cams[$i]["cam_x"],$cams[$i]["cam_y"],$cams[$i]["cam_area_w"],$cams[$i]["cam_area_h"],$area_w,$area_h,$cam_w,$cam_h);
?>
<div>
<div style="border: 2px #fff solid; border: none; position: absolute; left: <?php echo $r['left'];?>px; top: <?php echo $r['top'];?>px; transform: rotate(<?php echo $cams[$i]["cam_area_rotate"];?>deg);"> <img src="image/mask.png" width="<?php echo $area_w*$cams[$i]["cam_area_w"];?>" height="<?php echo $area_h*$cams[$i]["cam_area_h"];?>" />
</div>
<div id="cam<?php echo $i?>" class="cam area" style="left: <?php echo $cams[$i]["cam_x"];?>px;top: <?php echo $cams[$i]["cam_y"];?>px;"> <img src="image/cam.png" width="<?php echo $cam_w;?>" height="<?php echo $cam_h;?>"/> </div>
</div>
<?php }?>
</div></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<?php
function get_mast_postion($cam_x,$cam_y,$cam_area_w,$cam_area_h,$area_w,$area_h,$cam_w,$cam_h){
$left=$cam_x-$cam_area_w*$area_w/2;
$top=$cam_y-$cam_area_h*$area_h/2;
$r['left'] = $left+$cam_w/2;
$r['top'] = $top+$cam_h/2;
return $r;
}
?>
此差异已折叠。
此差异已折叠。
<?xml version="1.0" encoding="utf-8"?>
<ckplayer>
<!--基本配置-->
<config>
<fullInteractive>true</fullInteractive><!--是否开启交互功能-->
<delay>30</delay><!--延迟加载视频,单位:毫秒-->
<timeFrequency>100</timeFrequency><!--计算当前播放时间和加载量的时间频率,单位:毫秒-->
<autoLoad>true</autoLoad><!--视频是否自动加载-->
<loadNext>0</loadNext><!--多段视频预加载的段数,设置成0则全部加载-->
<definition>true</definition><!--是否使用清晰度组件-->
<smartRemove>true</smartRemove><!--是否使用智能清理,使用该功能则在多段时当前播放段之前的段都会被清除出内存,减少对内存的使用-->
<bufferTime>200</bufferTime><!--缓存区的长度,单位:毫秒,不要小于100-->
<click>true</click><!--是否支持屏幕单击暂停-->
<doubleClick>true</doubleClick><!--是否支持屏幕双击全屏-->
<doubleClickInterval>200</doubleClickInterval><!--判断双击的标准,即二次单击间隔的时间差之内判断为是双击,单位:毫秒-->
<keyDown>
<space>true</space><!--是否启用空格键切换播放/暂停-->
<left>true</left>
<right>true</right>
<up>true</up>
<down>true</down>
</keyDown>
<timeJump>10</timeJump><!--快进快退时的秒数-->
<volumeJump>0.1</volumeJump><!--音量调整的数量,大于0小于1的小数-->
<timeScheduleAdjust>1</timeScheduleAdjust><!--是否可调节调节栏,0不启用,1是启用,2是只能前进(向右拖动),3是只能后退,4是只能前进但能回到第一次拖动时的位置,5是看过的地方可以随意拖动-->
<previewDefaultLoad>true</previewDefaultLoad><!--预览图片是否默认加载,优点是鼠标第一次经过进度条即可显示预览图片-->
<promptSpotTime>false</promptSpotTime><!--提示点文字是否在前面加上对应时间-->
<buttonMode>
<player>false</player><!--鼠标在播放器上是否显示可点击形态-->
<controlBar>false</controlBar><!--鼠标在控制栏上是否显示可点击形态-->
<timeSchedule>true</timeSchedule><!--鼠标在时间进度条上是否显示可点击形态-->
<volumeSchedule>true</volumeSchedule><!--鼠标在音量调节栏上是否显示可点击形态-->
</buttonMode>
<liveAndVod><!--直播+点播=时移功能-->
<open>false</open><!--是否开启,开启该功能需要设置flashvars里live=true-->
<vodTime>2</vodTime><!--可以回看的整点数-->
<start>start</start><!--回看请求参数-->
</liveAndVod>
<errorNum>1</errorNum><!--错误重连次数-->
<playCorrect>false</playCorrect><!--错误修正-->
<timeCorrect>true</timeCorrect><!--http视频播放时间错误纠正,有些因为视频格式的问题导致视频没有实际播放结束视频文件就返回了stop命令-->
<m3u8Definition><!--m3u8自动清晰度时按关键字来进行判断-->
<!--<tags>110k</tags>
<tags>200k</tags>
<tags>400k</tags>
<tags>600k</tags>
<tags>800k</tags>
<tags>1000k</tags>-->
</m3u8Definition>
<m3u8MaxBufferLength>30</m3u8MaxBufferLength><!--m3u8每次缓冲时间,单位:秒数-->
<split>,</split><!--当视频地址采用字符形式并且需要使用逗号或其它符号来切割数组里定义-->
<timeStamp></timeStamp><!--一个地址,用来请求当前时间戳,用于播放器内部时间效准-->
<addCallback>adPlay,adPause,playOrPause,videoPlay,videoPause,videoMute,videoEscMute,videoClear,changeVolume,fastBack,fastNext,videoSeek,newVideo,getMetaDate,videoRotation,videoBrightness,videoContrast,videoSaturation,videoHue,videoZoom,videoProportion,videoError,addListener,removeListener,addElement,getElement,deleteElement,animate,animateResume,animatePause,deleteAnimate,changeConfig,getConfig,openUrl,fullScreen,quitFullScreen,switchFull,screenshot,custom,changeControlBarShow,getCurrentSrc</addCallback>
</config>
<menu>
<ckkey></ckkey>
<name></name>
<link></link>
<domain></domain>
<version></version>
<more></more>
</menu>
<languagePath></languagePath>
<stylePath></stylePath>
<style>
<loading><!--显示的loading元素-->
<file>data:image/swf;base64,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</file>
<align>center</align><!--水平对齐方式:left,center,right-->
<vAlign>middle</vAlign><!--垂直对齐方式:top,middle,bottom-->
<offsetX>-100</offsetX><!--水平偏移量,单位:像素-->
<offsetY>-40</offsetY><!--垂直偏移量,单位:像素-->
</loading>
<logo>
<file>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAUCAYAAAD4BKGuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAVTSURBVHja1Fl/aJVVGP4cw/mH5tUWi3I53cA0WbeIzMgaq6lQoVawm0S6glHhIKM/TELICotqCxMSGWQRdFfRLEhc9mMxqA0rbdS2wsV0GkZXuaKUWlHvgeeNh7f3u1du3Ft74eGcnXu+c873vD/Pt0nZbDZyZL2gWZAQTBH8IjggeEjgPZASPIB+g/P7EsGT6J/BfHfjHFIv2Jpjj/+dlDskvCm42Jk7X3C7YJOgw/z2oOBGwdEYRW0RVAjOCZ4ugNggqwU3CTLRBJFyQ+xuwVRY14igB78tE9QKpgmeEHwkGKRnq9AeMesHRWwEsYGUxwSdBZ51ecweE4Lct0DsOVjaZvptA8jfC4JfghWpXIJ2jMY+EDShf1pwh6DvX5x1GtpDE43cNFlfhyFWpQ9xd5FgFo3fRi++C+2nCBNBRgU3O6RsEyyEQv4QLMb4CcE9RlFBLqS1WZ6BZ83A35ofVhuvfE5QJrjWebdgCJOx51qM1QgewbMzsO57MDQrB9DeC8ObHd5Xyb2eiNiQQxmtgkZBr+OuZwV7BIcF1RgbF1wTE2MbEccX48VY9sMzBilhTke/m+b1Q9lefpgruI7OsYhIGzPJuAnn3+6EM7vu1YKl5vkrYRSfCGZivCxoMklk7M5j6eFlXyRNRSAvAoFf0Fo/CC7LkbwuQjsZsf0qwbuI9wlYgIqGl6NEzDYibJ/gbmAfxpKoMDRcaSK8xZzjZbK+NMhSYoNSngV5e+ksKXp+JdqZwDDmdpSbsqa9gNAyi5JalSGv3iQ+dtNK9HvI+sNBh2AhvNYVaH+msRtAdsa4ehoKCuQsoP2PY8+kCSkJ5IRWjD2FZ4/BOFSWYv9KhI40eUKQ31CqdnLM1c1OOnHufKSS+iEZvgHNhji8g1yT5VZKdCnHO+ajvrYK/I7GkuSWjwvq8Mzl5M79NF89aCHaBNXmWv0sQVUUZEDwsDnbr2i9s31lKyGuFs7kITEBC+snJaToRYIFrRN0CeYgoSUxJ23WUm85eB41b4IUuIvGtyIMVMY8lzHGMoYworF7J/onKYk10/wVQL6zXYr+Zq9aOEhuXZPDel8Q3If+HMzTeHPKlForEK+mws3SMfH2UMxNLIJbasKsoIQZwVLbKFkN4T1C3HxUMM+EkCAfgjwNV40Y304KriOP+jIHqa+jvYsqnH/kqzKaGCFZxWnoTqooxky8+dHUsOGwr6Jfi9jmlVVTHGLnot9L3qGWqCToWYYRF5fDa96mtb93yI2g8B0IWxlTHWmi/hOG00D4mEJfJ5WhQX7ySCsDUaNkJeud6+sgXCgs3OLEG2/xdZSh10JBeiB1zQU0HuQdSib60rOdm9kFToIL8hmFiRHzm1YM0ylet5k579OFpcUk4I0oD0/QuJ7tcBy5ERY6ixdrh5uNwN3bUV7pd4E+J958HmPxbRRydqK/in6vxj5aH9din/udEPKtuU1GqBL24xJwBInQWiHLcbQVKBXTzkVpHP0tWHsIpZUqPeWcrScXuX2ImRkqlufBhdQl15ig3WLKH0/SeAmtD+uprBqGx1ThhlWN5LKG4lcNKbDblFDjVDU0wWK7yLLqnPNk6cKzKsfXt1GQmQQXSuwymhd3tr9lkvPJMUV152kc2PsmUEMxtzdPRk2SNX2DQ3Vhr02Is18LXjHVAz/bG0NEK8johus3UBiwyfkYlDkQUyLaWrwZBrbHMaB8Z3PJLaYk8IIVKKPSJdxbv3ecynNzLNr33GKLV1YVW4IyfycXfq0UxP4X5HJdXCqX4Wv0AKqYkkipw4LG6WxMNi+GhAtH+M/K8wVe7wuWvwQYAFT+UsGCXmX3AAAAAElFTkSuQmCC</file>
<align>right</align><!--水平对齐方式:left,center,right-->
<vAlign>top</vAlign><!--垂直对齐方式:top,middle,bottom-->
<offsetX>-100</offsetX><!--水平偏移量,单位:像素-->
<offsetY>10</offsetY><!--垂直偏移量,单位:像素-->
</logo>
<advertisement><!--广告相关的配置-->
<time>5</time><!--广告默认播放时长以及多个广告时每个广告默认播放时间,单位:秒-->
<method>get</method><!--广告监测地址默认请求方式,get/post-->
<videoForce>false</videoForce><!--视频广告是否强制播放结束-->
<videoVolume>0.8</videoVolume><!--视频音量-->
<skipButtonShow>true</skipButtonShow><!--是否显示跳过广告按钮-->
<linkButtonShow>true</linkButtonShow><!--是否显示广告链接按钮,如果选择显示,只有在提供了广告链接地址时才会显示-->
<muteButtonShow>true</muteButtonShow><!--是否显示跳过广告按钮-->
<closeButtonShow>true</closeButtonShow><!--暂停时是否显示关闭广告按钮-->
<closeOtherButtonShow>true</closeOtherButtonShow><!--其它广告是否需要关闭广告按钮-->
<frontSkipButtonDelay>0</frontSkipButtonDelay><!--前置广告跳过广告按钮延时显示的时间,秒-->
<insertSkipButtonDelay>0</insertSkipButtonDelay><!--插入广告跳过广告按钮延时显示的时间,秒-->
<endSkipButtonDelay>0</endSkipButtonDelay><!--后置广告跳过广告按钮延时显示的时间,秒-->
<!--广告拉伸方式,0=原始大小,1=自动缩放,2=只有当广告的宽或高大于播放器宽高时才进行缩放,3=参考播放器宽高,4=宽度参考播放器宽、高度自动,5=高度参考播放器高、宽度自动-->
<frontStretched>1</frontStretched>
<insertStretched>2</insertStretched>
<pauseStretched>2</pauseStretched>
<endStretched>2</endStretched>
</advertisement>
<video><!--视频的默认比例-->
<defaultWidth>4</defaultWidth>
<defaultHeight>3</defaultHeight>
</video>
</style>
<!--做为前端flashvars的补充-->
<flashvars></flashvars>
</ckplayer>
\ No newline at end of file
Copyright (c) 2017 Dailymotion (http://www.dailymotion.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
src/remux/mp4-generator.js and src/demux/exp-golomb.js implementation in this project
are derived from the HLS library for video.js (https://github.com/videojs/videojs-contrib-hls)
That work is also covered by the Apache 2 License, following copyright:
Copyright (c) 2013-2015 Brightcove
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<?xml version="1.0" encoding="utf-8"?>
<language>
<adCountdown>[$second]</adCountdown><!--广告播放结束倒计时-->
<skipDelay>[$second]</skipDelay>
<buttonOver>
<play>点击播放</play>
<pause>暂停播放</pause>
<mute>静音</mute>
<escMute>恢复音量</escMute>
<full>全屏</full>
<escFull>退出全屏</escFull>
<previousPage>上一集</previousPage>
<nextPage>下一集</nextPage>
<definition>点击选择清晰度</definition>
</buttonOver>
<volumeSliderOver>
音量:[$volume]%
</volumeSliderOver>
<buffer>[$percentage]%</buffer>
<timeSliderOver><!--鼠标经过进度条显示的时间格式-->
[$timeh]:[$timei]:[$times]
</timeSliderOver>
<liveAndVod>
[$timeh]:[$timei]:[$times]
</liveAndVod>
<live>
直播中 [$liveTimeY]-[$liveTimem]-[$liveTimed] [$liveTimeh]:[$liveTimei]:[$liveTimes]
</live>
<m3u8Definition>
<name>流畅</name>
<name>低清</name>
<name>标清</name>
<name>高清</name>
<name>超清</name>
<name>蓝光</name>
<name>未知</name>
</m3u8Definition>
<error>
<cannotFindUrl>视频地址不存在</cannotFindUrl>
<streamNotFound>加载失败</streamNotFound>
<formatError>视频格式错误</formatError>
</error>
<definition>自动</definition>
</language>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
......@@ -135,15 +135,18 @@ def runnable(func):
class Module(object):
_record = {}
def __new__(cls, name=None, directory=None, module_dir=None, version=None):
def __new__(cls,
name=None,
directory=None,
module_dir=None,
version=None,
**kwargs):
if cls.__name__ == "Module":
if name:
module = cls.init_with_name(name=name, version=version)
module = cls.init_with_name(
name=name, version=version, **kwargs)
elif directory:
module = cls.init_with_directory(directory=directory)
module = cls.init_with_directory(directory=directory, **kwargs)
elif module_dir:
logger.warning(
"Parameter module_dir is deprecated, please use directory to specify the path"
......@@ -154,19 +157,28 @@ class Module(object):
version = module_dir[1]
else:
directory = module_dir
module = cls.init_with_directory(directory=directory)
module = cls.init_with_directory(directory=directory, **kwargs)
CacheUpdater("update_cache", module.name, module.version).start()
else:
module = object.__new__(cls)
if not name and not directory:
directory = os.path.dirname(
sys.modules[cls.__module__].__file__)
module = Module.init_with_directory(
directory=directory, **kwargs)
else:
module = object.__new__(cls)
return module
def __init__(self, name=None, directory=None, module_dir=None,
version=None):
def __init__(self,
name=None,
directory=None,
module_dir=None,
version=None,
**kwargs):
# Avoid module being initialized multiple times
if not directory or id(self) in Module._record:
if "_is_initialize" in self.__dict__ and self._is_initialize:
return
Module._record[id(self)] = True
mod = self.__class__.__module__ + "." + self.__class__.__name__
if mod in _module_runnable_func:
......@@ -195,10 +207,11 @@ class Module(object):
self._summary = utils.from_module_attr_to_pyobj(
module_info.map.data['summary'])
self._initialize()
self._initialize(**kwargs)
self._is_initialize = True
@classmethod
def init_with_name(cls, name, version=None):
def init_with_name(cls, name, version=None, **kwargs):
fp_lock = open(os.path.join(CACHE_HOME, name), "a")
lock.flock(fp_lock, lock.LOCK_EX)
log_msg = "Installing %s module" % name
......@@ -214,22 +227,29 @@ class Module(object):
logger.info(tips)
lock.flock(fp_lock, lock.LOCK_UN)
return cls.init_with_directory(directory=module_dir[0])
return cls.init_with_directory(directory=module_dir[0], **kwargs)
@classmethod
def init_with_directory(cls, directory):
def init_with_directory(cls, directory, **kwargs):
desc_file = os.path.join(directory, MODULE_DESC_PBNAME)
checker = ModuleChecker(directory)
checker.check()
module_code_version = checker.module_code_version
if module_code_version == "v2":
basename = os.path.split(directory)[-1]
dirname = os.path.join(*list(os.path.split(directory)[:-1]))
sys.path.append(dirname)
user_module = importlib.import_module("{}.module".format(basename))
return user_module.HubModule(directory=directory)
return ModuleV1(directory=directory)
sys.path.insert(0, directory)
# clear module cache
if 'module' in sys.modules:
sys.modules.pop('module')
_module = importlib.import_module("module")
for _item, _cls in inspect.getmembers(_module, inspect.isclass):
_item = _module.__dict__[_item]
if issubclass(_item, Module):
user_module = _item(directory=directory, **kwargs)
break
sys.path.pop(0)
return user_module
return ModuleV1(directory=directory, **kwargs)
@property
def run_func(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册