<!-- Copyright Epic Games, Inc. All Rights Reserved. -->
<!DOCTYPE HTML>
<html>
<head>
<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">
<link rel="icon" type="image/png" sizes="96x96" href="/images/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png">
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css"
integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
<!-- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css"
integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous"> -->
<link type="text/css" rel="stylesheet" href="/player.css">
<script type="text/javascript" src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script type="text/javascript" src="/scripts/webRtcPlayer.js"></script>
<script type="text/javascript" src="/scripts/app.js"></script>
<script type="text/javascript" src="PixelDemo.js"></script>
<link type="text/css" rel="stylesheet" href="player.css">
<link type="text/css" rel="stylesheet" href="PixelDemo.css">
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- For iPhone X the following makes it use the entire screen space for the webpage https://webkit.org/blog/7929/designing-websites-for-iphone-x/ -->
<meta name='viewport' content='initial-scale=1, viewport-fit=cover'>
</head>
<body onl oad="load(); onParagonLoad();">
<div class="wrapper">
<div id="content" class="container">
<div class="row">
<div class="col">
<div id="player" class="fixed-size">
<!-- <div id="configuration">
<div id="ck-fullscreen">
<img src="images/MaximiseToFullscreen.png" alt="Maximise to Fullscreen"
id="fullscreen-img" class="fullscreen-btn">
</div>
</div> -->
<div class="canvasbox">
<div class="opencamera">
开启摄像头
</div>
<div class="camerabox">
<video id="video" class="cameraboxbvideo" width="200" height="113"></video>
<canvas id="canvas" class="cameraboxbvideo" width="200" height="113"
style="transform: rotateY(180deg);"></canvas>
<div class="closecamera" onclick="closeMedia()">
退出使用
</div>
</div>
</div>
</div>
</div>
</div>
<div class="text"></div>
<div id="overlay" class="overlay text-light bg-dark">
<div id="overlayHeader">
<div id="qualityStatus" class="greyStatus">●</div>
<div id="overlayButton">+</div>
</div>
<div id="overlaySettings">
<div id="showFPS" class="setting">
<div class="settings-text">Show FPS</div>
<label class="btn-overlay">
<input type="button" id="show-fps-button" class="overlay-button btn-flat" value="Toggle">
</label>
</div>
<div id="fillWindow" class="setting">
<div class="settings-text">Enlarge display to fill window</div>
<label class="tgl-switch">
<input type="checkbox" id="enlarge-display-to-fill-window-tgl" class="tgl tgl-flat" checked>
<div class="tgl-slider"></div>
</label>
</div>
<div id="qualityControlOwnership" class="setting">
<div class="settings-text">Is quality controller?</div>
<label class="tgl-switch">
<input type="checkbox" id="quality-control-ownership-tgl" class="tgl tgl-flat">
<div class="tgl-slider"></div>
</label>
</div>
<div id="matchViewportResolution" class="setting">
<div class="settings-text">Match viewport resolution</div>
<label class="tgl-switch">
<input type="checkbox" id="match-viewport-res-tgl" class="tgl tgl-flat">
<div class="tgl-slider"></div>
</label>
</div>
<div id="preferSFU" class="setting">
<div class="settings-text">Prefer SFU</div>
<label class="tgl-switch">
<input type="checkbox" id="prefer-sfu-tgl" class="tgl tgl-flat">
<div class="tgl-slider"></div>
</label>
</div>
<div id="useMic" class="setting">
<div class="settings-text">Use microphone</div>
<label class="tgl-switch">
<input type="checkbox" id="use-mic-tgl" class="tgl tgl-flat">
<div class="tgl-slider"></div>
</label>
</div>
<div id="forceTURN" class="setting">
<div class="settings-text">Force TURN</div>
<label class="tgl-switch">
<input type="checkbox" id="force-turn-tgl" class="tgl tgl-flat">
<div class="tgl-slider"></div>
</label>
</div>
<section id="encoderSettings">
<div id="encoderSettingsHeader" class="settings-text">
<div>Encoder Settings</div>
</div>
<div id="encoderParamsContainer" class="collapse">
<div class="form-group">
<label for="encoder-min-qp-text">Min QP</label>
<input type="number" class="form-control" id="encoder-min-qp-text" value="0" min="0"
max="51" />
<label for="encoder-max-qp-text">Max QP</label>
<input type="number" class="form-control" id="encoder-max-qp-text" value="51" min="0"
max="51" />
<br>
<input id="encoder-params-submit" class="overlay-button btn-flat" type="button"
value="Apply">
</div>
</div>
</section>
<section id="webRTCSettings">
<div id="webRTCSettingsHeader" class="settings-text">
<div>WebRTC Settings</div>
</div>
<div id="webrtcParamsContainer" class="collapse">
<div class="form-group">
<label for="webrtc-fps-text">FPS</label>
<input type="number" class="form-control" id="webrtc-fps-text" value="60" min="1"
max="999" />
<label for="webrtc-min-bitrate-text">Min bitrate (kbps)</label>
<input type="number" class="form-control" id="webrtc-min-bitrate-text" value="0" min="0"
max="100000" />
<label for="webrtc-max-bitrate-text">Max bitrate (kbps)</label>
<input type="number" class="form-control" id="webrtc-max-bitrate-text" value="0" min="0"
max="100000" />
<br>
<input id="webrtc-params-submit" class="overlay-button btn-flat" type="button"
value="Apply">
</div>
</div>
</section>
<section id="streamSettings">
<div id="streamSettingsHeader" class="settings-text">
<div>Stream Settings</div>
</div>
<div id="streamSettingsContainer" class="collapse">
<div class="form-group">
<div class="settings-text">Player stream</div>
<select class="form-control" id="stream-select"></select>
<div class="settings-text">Player track</div>
<select class="form-control" id="track-select"></select>
</div>
</div>
</section>
<br>
<section id="statsPanel">
<div class="setting settings-text">
<div>Show Stats</div>
<label class="tgl-switch">
<input type="checkbox" id="show-stats-tgl" class="tgl tgl-flat" checked>
<div class="tgl-slider"></div>
</label>
</div>
<div id="statsContainer" class="statsContainer">
<div id="stats" class="stats"></div>
</div>
</section>
<section id="latencyTest">
<div class="setting settings-text">
<div>Latency Report</div>
<label class="btn-overlay">
<input type="button" id="test-latency-button" class="overlay-button btn-flat"
value="Get Report">
</label>
</div>
<div id="latencyStatsContainer" class="statsContainer">
<div id=LatencyStats class="stats">No report yet...</div>
</div>
</section>
</div>
</div>
<div class=""></div>
</div>
<div class="right">
<div class="title">虚拟形象</div>
<div class="imglist">
<div class="imgbox activeimgbox" onclick="onConfigButton(0,0),onClick('0')" id="new_one">
<img src="./images/man.jpg" class="imgclass" />
</div>
<div class="imgbox" onclick="onConfigButton(0,1),onClick('1')" id="new_two">
<img src="./images/girl.jpg" class="imgclass" />
</div>
<div class="imgbox" onclick="onConfigButton(0,2),onClick('2')" id="new_three">
<img src="./images/cat.jpg" class="imgclass" />
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"
integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em"
crossorigin="anonymous"></script>
</body>
</html>
<script>
function GetQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
var get_ip_id = GetQueryString("ip_id")
var get_websocket = GetQueryString("websocket")
var get_env = GetQueryString("env")
var get_token = GetQueryString("token")
var ajaxurl = ''
console.log(get_ip_id, get_websocket, get_env)
if (get_env === 'test') {
ajaxurl = ''
} else {
ajaxurl = ''
}
function ipStatus(status) {
let data = {
ip_id: get_ip_id,
status: status //状态(1空闲、2占用)
}
let xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', ajaxurl + '/api/task/change_ip_status', true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("Authorization", 'Bearer ' + get_token);
xmlhttp.send(JSON.stringify(data));
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
let response = JSON.parse(xmlhttp.response);
if (response.status == 200) {
console.log(response)
}
} else if (xmlhttp.readyState == 4 && xmlhttp.status != 200) {
alert("网络错误,请稍后重试");
}
}
}
ipStatus(2)
function onClick(obj) {
sessionStorage.setItem('objfaceitem', obj)
if (obj === '0') {
$("#new_one").addClass("activeimgbox");
$("#new_two").removeClass("activeimgbox");
$("#new_three").removeClass("activeimgbox");
}
if (obj === '1') {
$("#new_one").removeClass("activeimgbox");
$("#new_two").addClass("activeimgbox");
$("#new_three").removeClass("activeimgbox");
}
if (obj === '2') {
$("#new_one").removeClass("activeimgbox");
$("#new_two").removeClass("activeimgbox");
$("#new_three").addClass("activeimgbox");
}
}
var session_objfaceitem = sessionStorage.getItem('objfaceitem')
console.log('session_objfaceitem', session_objfaceitem)
if (session_objfaceitem !== null) {
onClick(session_objfaceitem)
}
$('.opencamera').click(function () {
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
getUserMedia({
video: {
width: 200,
height: 113
},
audio: false
}, success, error)
ipStatus(2)
} else {
alert("不支持");
}
});
//用来匹配不同的浏览器
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
console.log(1);
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
console.log(2);
navigator.webkitGetUserMedia(constraints, success, error);
} else if (navigator.mozGetUserMedia) {
console.log(3);
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
console.log(4);
navigator.getUserMedia(constraints, success, error)
}
}
let video = document.getElementById('video');
let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');
var filterimagedata = '';
var type = 'jpg';
var takepicturetimes = null;
var firstlock = true;
// var wsUri = "ws://10.147.100.104:10424/mocap/face_capture/104233";
// var wsUri = "ws://10.147.100.112:10723/mocap/face_capture/104233";
var wsUri = get_websocket + 'mocap/face_capture/104233';
// widnow.locta.href
var output;
var websocket;
var mediaStreamTrack;
//成功回调
function success(stream) {
$(".opencamera").hide();
$(".camerabox").show();
saveFile()
video.srcObject = stream;
mediaStreamTrack = stream
video.play();
// let mediaRecorder = new MediaRecorder(stream); //blob 二进制流文件方法
// mediaRecorder.ondataavailable = function (blob) {
// console.log(blob.data)
// }
// mediaRecorder.start(1000)
}
//失败回调
function error(error) {
console.log("访问用户媒体失败");
}
//开启摄像头
var saveFile = function (filename) {
//获取canvas标签里的图片内容
// context.scale(-1, 1); //左右镜像翻转
context.drawImage(video, 0, 0, 200, 113);
var imgData = document.getElementById('canvas').toDataURL(type);
imgData = canvas.toDataURL('image/jpeg');
filterimagedata = imgData.split('data:image/jpeg;base64,')[1]
// console.log(imgData)
if (firstlock) {
testWebSocket()
settimes40()
} else {
if (filterimagedata != '') {
doSend(filterimagedata);
}
}
};
function settimes40() {
firstlock = false
takepicturetimes = setInterval(() => {
saveFile()
}, 40)
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function (evt) {
onOpen(evt)
doSend(filterimagedata);
};
websocket.onclose = function (evt) {
onClose(evt)
};
websocket.onmessage = function (evt) {
onMessage(evt)
};
websocket.onerror = function (evt) {
one rror(evt)
};
}
function onOpen(evt) {
writeToScreen("连接成功", evt);
}
function onClose(evt) {
console.log('我关闭了WebSocket')
clearInterval(takepicturetimes)
let data = {
ip_id: get_ip_id,
status: 1 //状态(1空闲、2占用)
}
let xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', ajaxurl + '/api/task/change_ip_status', true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("Authorization", 'Bearer ' + get_token);
xmlhttp.send(JSON.stringify(data));
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
sessionStorage.setItem('objfaceitem', 0)
onConfigButton(0, 0)
onClick(0)
let response = JSON.parse(xmlhttp.response);
if (get_env === 'test') {
parent.postMessage("退出使用", "https://test-ai.moviebook.com/faceCapture");
} else {
parent.postMessage("退出使用", "https://ai.moviebook.com/faceCapture");
}
} else if (xmlhttp.readyState == 4 && xmlhttp.status != 200) {
alert("网络错误,请稍后重试");
}
}
writeToScreen("关闭", evt);
}
function onMessage(evt) {
console.log('返回消息' + evt.data)
writeToScreen('返回消息' + evt.data);
}
function one rror(evt) {
let data = {
ip_id: get_ip_id,
status: 1 //状态(1空闲、2占用)
}
let xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', ajaxurl + '/api/task/change_ip_status', true);
xmlhttp.setRequestHeader("Content-type", "application/json");
xmlhttp.setRequestHeader("Authorization", 'Bearer ' + get_token);
xmlhttp.send(JSON.stringify(data));
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
sessionStorage.setItem('objfaceitem', 0)
onConfigButton(0, 0)
onClick(0)
let response = JSON.parse(xmlhttp.response);
if (get_env === 'test') {
parent.postMessage("退出使用", "https://test-ai.moviebook.com/faceCapture");
} else {
parent.postMessage("退出使用", "https://ai.moviebook.com/faceCapture");
}
} else if (xmlhttp.readyState == 4 && xmlhttp.status != 200) {
alert("网络错误,请稍后重试");
}
}
writeToScreen('错误' + evt.data);
//tanchuang
}
function doSend(message) {
writeToScreen("发送:" + message);
websocket.send(message);
}
function writeToScreen(message, evt) {
// console.log(message, evt)
}
//关闭浏览器摄像头
function closeMedia() {
if (mediaStreamTrack) {
this.mediaStreamTrack.getTracks()[0].stop();
onClose()
firstlock = true;
$(".opencamera").show();
$(".camerabox").hide();
}
}
</script>
<style>
.wrapper {
display: inline-flex;
transform-origin: top left;
width: 1070px;
overflow: hidden;
background: #FFFFFF;
}
#player {
position: relative;
margin-top: 0px;
width: 750px;
height: 422px;
z-index: 10;
padding-bottom: 0;
}
#player .canvasbox {
position: absolute;
top: 0;
left: 0;
z-index: 9999;
width: 200px;
height: 113px;
background: #000;
color: #ffffff;
font-size: 14px;
text-align: center;
line-height: 113px;
cursor: pointer;
}
#player .canvasbox .opencamera {
display: block;
}
#player .canvasbox .closecamera {}
#player .canvasbox .camerabox {
width: 200px;
height: 113px;
position: relative;
display: none;
}
#player .canvasbox .camerabox .closecamera {
position: absolute;
top: 0;
right: 0;
visibility: hidden;
transition: 0.2s ease-in-out;
width: 100%;
height: 100%;
color: #fff;
background: rgba(0, 0, 0, 0.6);
}
#player .canvasbox .camerabox .cameraboxbvideo {
position: absolute;
top: 0;
left: 0;
}
#player .canvasbox .camerabox:hover .closecamera {
visibility: visible;
transition-delay: 0.2s;
}
.row {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: 0px;
margin-left: 0px;
width: 750px;
}
.col {
position: relative;
width: 750px;
min-height: 1px;
padding-right: 0px;
padding-left: 0px;
}
.col {
max-width: 750px;
}
.container {
max-width: 750px
}
.container {
width: 750px;
padding-right: 0px;
padding-left: 0px;
margin-right: auto;
margin-left: auto;
}
#sidebar {
width: 300px;
margin-left: 10px;
height: 524px !important;
background-color: rgb(237, 241, 242);
min-width: 300px;
max-width: 300px;
min-height: 524px;
}
#sidebarContent {
max-height: 100%;
position: static;
overflow-y: auto;
}
.right {
min-width: 300px !important;
height: 422px !important;
margin-left: 10px;
background-color: rgb(237, 241, 242);
}
.title {
font-family: SourceHanSansSC;
font-weight: 400;
font-size: 16px;
color: rgb(16, 16, 16);
font-style: normal;
letter-spacing: 0px;
text-align: center;
margin: 20px 0;
}
.imglist {
display: flex;
flex-wrap: wrap;
}
.imgbox {
margin-bottom: 20px;
width: 124px;
height: 94px;
margin-left: 20px;
border: 2px solid transparent;
cursor: pointer;
}
.imgclass {
width: 120px;
height: 90px;
object-fit: cover;
}
.activeimgbox {
width: 124px;
height: 94px;
margin-left: 20px;
margin-bottom: 20px;
border: 2px solid #ff7d00;
}
</style>