Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

Day123: Mofang: front and back end implementation of live room list information & front and back end implementation of creating room

iR-Poke 2021-01-14 16:33:31 阅读数:6 评论数:0 点赞数:0 收藏数:0

Catalog

1. The server provides the list information of all live broadcast rooms

2. Front end display room list

3. Create a room

1. The server provides the list information of all live broadcast rooms

1.marshmallow.py

from marshmallow_sqlalchemy import SQLAlchemyAutoSchema,auto_field
from .models import LiveStream,db
from application.apps.users.models import User
from marshmallow import post_dump
class StreamInfoSchema(SQLAlchemyAutoSchema):
id = auto_field()
name = auto_field()
room_name = auto_field()
user = auto_field()
class Meta:
model = LiveStream
include_fk = True
include_relationships = True
fields = ["id","name","room_name","user"]
sql_session = db.session
@post_dump()
def user_format(self, data, **kwargs):
user = User.query.get(data["user"])
if user is None:
return data
data["user"] = {
"id":user.id,
"nickname": user.nickname if user.nickname else "",
"ip": user.ip_address if user.ip_address else "",
"avatar": user.avatar if user.avatar else ""
}
return data
marshmallow.py

2.views.py

from .marshmallow import StreamInfoSchema
from flask import current_app
@jsonrpc.method("Live.stream.list")
@jwt_required # verification jwt
def list_stream():
# Verify login user information 
current_user_id = get_jwt_identity() # get_jwt_identity It is used to obtain the data in the load 
user = User.query.get(current_user_id)
if user is None:
return {
"errno": status.CODE_NO_USER,
"errmsg": message.user_not_exists,
"data": {
}
}
# Query all live streams in the database 
stream_list = LiveStream.query.filter(LiveStream.status==True, LiveStream.is_deleted==False).all()
sis = StreamInfoSchema()
data_list = sis.dump(stream_list,many=True)
# Use requests send out get request , Read the current srs All live streams and client lists in 
import requests,re,json
stream_response = requests.get(current_app.config["SRS_HTTP_API"]+"streams/")
client_response = requests.get(current_app.config["SRS_HTTP_API"]+"clients/")
stream_text = re.sub(r'[^\{\}\/\,0-9a-zA-Z\"\'\:\[\]\._]', "", stream_response.text)
client_text = re.sub(r'[^\{\}\/\,0-9a-zA-Z\"\:\[\]\._]', "", client_response.text)
stream_dict = json.loads(stream_text)
client_dict = json.loads(client_text)
# Match the total number of clients and the number of current streaming users in the loop IP Address 
for data in data_list:
data["status"] = False
for stream in stream_dict["streams"]:
if data["name"] == stream["name"]:
data["status"] = stream["publish"]["active"]
break
data["clients_number"] = 0
for client in client_dict["clients"]:
if data["name"] == client["url"].split("/")[-1]:
data["clients_number"]+=1
if client["publish"] and "/live/"+data["name"]==client["url"]:
data["user"]["ip"] = client["ip"]
return {
"errno": status.CODE_OK,
"errmsg": message.ok,
"stream_list": data_list
}
views.py

2. Front end display room list

1. Room list page initialization :live_list.html

Put the client above live_list.html, Modified into live.html, And new live_list.html, Code :

<!DOCTYPE html>
<html>
<head>
<title> The friends list </title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta charset="utf-8">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app setting" id="app">
<div class="bg">
<img src="../static/images/rooms_bg.png">
</div>
<img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
<div class="add_friend_btn" @click="add_room">
<img src="../static/images/add_room.png" alt="">
</div>
<div class="friends_list room_list">
<div class="item" v-for="room in rooms">
<div class="avatar">
<img class="user_avatar" :src="room.avatar" alt="">
</div>
<div class="info">
<p class="username">{{room.name}}</p>
<p class="fruit"> The number of :{{room.num}}</p>
</div>
<div class="behavior pick"> live broadcast </div>
<div class="goto"><img src="../static/images/arrow1.png" alt=""></div>
</div>
</div>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
rooms:[{"avatar":"../static/images/avatar.png",name:" Room name ",num:5}],
prev:{name:"",url:"",params:{}},
current:{name:"live",url:"live_list.html",params:{}},
}
},
created(){
},
methods:{
add_room(){
},
goto_home(){
// Exit the current page 
this.game.outFrame("live","live_list.html", this.current);
},
}
});
}
</script>
</body>
</html>
Room list page initialization :live_list.html

2. Room list page CSS style

.room_list{
position: absolute;
top: 18rem;
}

3. The front end obtains the live stream list from the back end :get_room_list

Get the live stream list of the server , live_list Code :

<!DOCTYPE html>
<html>
<head>
<title> Room list </title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta charset="utf-8">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app user setting" id="app">
<div class="bg">
<img src="../static/images/rooms_bg.png">
</div>
<img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
<div class="add_friend_btn" @click="add_room">
<img src="../static/images/add_room.png" alt="">
</div>
<div class="friends_list room_list">
<div class="item" v-for="room in rooms">
<div class="avatar">
<img class="user_avatar" :src="room.user && settings.static_url+room.user.avatar" alt="">
</div>
<div class="info">
<p class="username">{{room.room_name}}</p>
<p class="fruit"> The number of :{{room.clients_number}}</p>
</div>
<div class="behavior pick" v-if="room.status"> live broadcast </div>
<div class="goto" @click="goto_live(room.id,room.name)"><img src="../static/images/arrow1.png" alt=""></div>
</div>
</div>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
rooms:[], // Room list 
 prev:{name:"",url:"",params:{}},
current:{name:"live",url:"live_list.html",params:{}},
}
},
created(){
this.get_room_list();
},
methods:{
get_room_list(){
var token = this.game.get("access_token") || this.game.fget("access_token");
this.axios.post("",{
"jsonrpc": "2.0",
"id": this.uuid(),
"method": "Live.stream.list",
"params": {}
},{
headers:{
Authorization: "jwt " + token,
}
}).then(response=>{
if(parseInt(response.data.result.errno)==1000){
this.rooms = response.data.result.stream_list;
}else{
this.game.print(response.data.result.errmsg);
}
}).catch(error=>{
// Network and other anomalies 
this.game.print(error);
});
},
goto_live(room_id,stream_name){
// get into the room 
var pageParam = {
name: this.current.name,
url: this.current.url,
room_id: room_id,
stream_name: stream_name
}
this.game.goFrame("room","live.html",pageParam);
},
add_room(){
},
goto_home(){
// Exit the current page 
this.game.outWin("live");
},
}
});
}
</script>
</body>
</html>
The front end obtains the live stream list from the back end

3. Create a room

1. Create room page initialization :add_room.html

When the user clicks create room , The user will be asked to enter the room name and password

When the user enters, click OK , Send a request to the back end interface , Pass the room name and password entered by the user to the back end

Create a room , add_room.html, Code :

<!DOCTYPE html>
<html>
<head>
<title> Create a room </title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta charset="utf-8">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app frame avatar update_password" id="app">
<div class="box">
<p class="title"> Create a room </p>
<img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
<div class="content">
<input class="password" type="text" v-model="name" placeholder=" Room name ....">
<input class="password password2" type="password" v-model="password" placeholder=" Room code ....">
</div>
<img @click="add_room_submit" class="btn" src="../static/images/yes.png" alt="">
</div>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
name:"",
password:"",
prev:{name:"",url:"",params:{}},
current:{name:"add_room",url:"add_room.html",params:{}},
}
},
methods:{
close_frame(){
this.game.outFrame("add_room");
},
add_room_submit(){
// Submit data 
var token = this.game.get("access_token") || this.game.fget("access_token");
this.axios.post("",{
"jsonrpc": "2.0",
"id": this.uuid(),
"method": "Live.stream",
"params": {
room_name: this.name,
password: this.password
}
},{
headers:{
Authorization: "jwt " + token,
}
}).then(response=>{
if(parseInt(response.data.result.errno)==1000){
this.rooms = response.data.result.stream_list;
}else{
this.game.print(response.data.result.errmsg);
}
}).catch(error=>{
// Network and other anomalies 
this.game.print(error);
});
},
}
});
}
</script>
</body>
</html>
Create room page initialization :add_room.html

2. Add room password field in live stream data table

Add room password field to server interface ,live/models.py , Code :

from application.utils.models import BaseModel,db
class LiveStream(BaseModel):
""" Live stream management """
__tablename__ = "mf_live_stream"
name = db.Column(db.String(255), unique=True, comment=" Stream name ")
room_name = db.Column(db.String(255), default=" unnamed ",comment=" Room name ")
room_password = db.Column(db.String(255), default="", comment=" Room code ")
user = db.Column(db.Integer, comment=" House owner ")
class LiveRoom(BaseModel):
""" studio """
__tablename__ = "mf_live_room"
stream_id = db.Column(db.Integer, comment=" Live streaming ID")
user = db.Column(db.Integer, comment=" user ID")

3. Back end modification creates room interface , New password verification function

The server creates a room interface , Add a password field and verify the password to enter the room

After the user enters the room name and password , The front end makes a request to the back end , Submit the input to the back end

After the back end receives the room name and password , Do the following :

1. Create a live stream :,mysql In the store : user id/ Room name / Room code / Live stream number

2. Create a room :mysql In the store : user id/ Live stream number

live/views.py, Code :

from application import jsonrpc,db
from message import ErrorMessage as message
from status import APIStatus as status
from flask_jwt_extended import jwt_required,get_jwt_identity
from application.apps.users.models import User
from .models import LiveStream,LiveRoom
from datetime import datetime
import random
@jsonrpc.method("Live.stream")
@jwt_required # verification jwt
def live_stream(room_name,password):
""" Create a live stream """
current_user_id = get_jwt_identity() # get_jwt_identity It is used to obtain the data in the load 
user = User.query.get(current_user_id)
if user is None:
return {
"errno": status.CODE_NO_USER,
"errmsg": message.user_not_exists,
}
# Apply to create a live stream 
stream = LiveStream.query.filter(LiveStream.user==user.id).first()
if stream is None:
stream_name = "room_%06d%s%06d" % (
user.id, datetime.now().strftime("%Y%m%d%H%M%S"), random.randint(100, 999999))
stream = LiveStream(
name=stream_name,
user=user.id,
room_name=room_name,
room_password=password
)
db.session.add(stream)
db.session.commit()
else:
stream.room_name = room_name
stream.room_password = password
db.session.commit()
# get into the room 
room = LiveRoom.query.filter(LiveRoom.user==user.id,LiveRoom.stream_id==stream.id).first()
if room is None:
room = LiveRoom(
stream_id=stream.id,
user=user.id
)
db.session.add(room)
db.session.commit()
return {
"errno": status.CODE_OK,
"errmsg": message.ok,
"data":{
"stream_name": stream.name,
"room_name": room_name,
"room_owner": user.id,
"room_id": "%04d" % stream.id,
}
}
from .marshmallow import StreamInfoSchema
from flask import current_app
@jsonrpc.method("Live.stream.list")
@jwt_required # verification jwt
def list_stream():
""" Room list """
current_user_id = get_jwt_identity() # get_jwt_identity It is used to obtain the data in the load 
user = User.query.get(current_user_id)
if user is None:
return {
"errno": status.CODE_NO_USER,
"errmsg": message.user_not_exists,
"data": {
}
}
stream_list = LiveStream.query.filter(LiveStream.status==True, LiveStream.is_deleted==False).all()
sis = StreamInfoSchema()
data_list = sis.dump(stream_list,many=True)
# Use requests send out get request 
import requests
stream_response = requests.get(current_app.config["SRS_HTTP_API"]+"streams/")
client_response = requests.get(current_app.config["SRS_HTTP_API"]+"clients/")
import re,json
stream_text = re.sub(r'[^\{\}\/\,0-9a-zA-Z\"\'\:\[\]\._]', "", stream_response.text)
client_text = re.sub(r'[^\{\}\/\,0-9a-zA-Z\"\:\[\]\._]', "", client_response.text)
stream_dict = json.loads(stream_text)
client_dict = json.loads(client_text)
for data in data_list:
data["status"] = False
for stream in stream_dict["streams"]:
if data["name"] == stream["name"]:
data["status"] = stream["publish"]["active"]
break
data["clients_number"] = 0
for client in client_dict["clients"]:
if data["name"] == client["url"].split("/")[-1]:
data["clients_number"]+=1
if client["publish"] and "/live/"+data["name"]==client["url"]:
data["user"]["ip"] = client["ip"]
return {
"errno": status.CODE_OK,
"errmsg": message.ok,
"stream_list": data_list
}
The server provides an interface for creating rooms

4. The front end judges whether there is a password in the room , If there is a password, you must input it correctly to enter the room

It is determined in the client that when the password exists in the room , The user must enter the password successfully before entering the room , live_list.html Code :

<!DOCTYPE html>
<html>
<head>
<title> Room list </title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta charset="utf-8">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app user setting" id="app">
<div class="bg">
<img src="../static/images/rooms_bg.png">
</div>
<img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
<div class="add_friend_btn" @click="add_room">
<img src="../static/images/add_room.png" alt="">
</div>
<div class="friends_list room_list">
<div class="item" v-for="room in rooms" @click="goto_live(room.id,room.name,room.room_password)">
<div class="avatar">
<img class="user_avatar" :src="room.user && settings.static_url+room.user.avatar" alt="">
</div>
<div class="info">
<p class="username">{{room.room_name}}</p>
<p class="fruit"> The number of :{{room.clients_number}}</p>
</div>
<div class="behavior pick" v-if="room.status"> live broadcast </div>
<div class="goto"><img src="../static/images/arrow1.png" alt=""></div>
</div>
</div>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
rooms:[], // Room list 
 prev:{name:"",url:"",params:{}},
current:{name:"live",url:"live_list.html",params:{}},
}
},
created(){
this.get_room_list();
},
methods:{
get_room_list(){
var token = this.game.get("access_token") || this.game.fget("access_token");
this.axios.post("",{
"jsonrpc": "2.0",
"id": this.uuid(),
"method": "Live.stream.list",
"params": {}
},{
headers:{
Authorization: "jwt " + token,
}
}).then(response=>{
if(parseInt(response.data.result.errno)==1000){
this.rooms = response.data.result.stream_list;
}else{
this.game.print(response.data.result.errmsg);
}
}).catch(error=>{
// Network and other anomalies 
this.game.print(error);
});
},
goto_live(room_id,stream_name,room_password){
// Verify password 
if(room_password != null){
api.prompt({
title:" Please enter the room code !",
buttons: [' determine ', ' Cancel '],
}, (ret, err)=>{
if( ret.text == room_password ){
this.goto_room(room_id,stream_name);
}else {
alert(" Wrong password !");
}
});
}else{
this.goto_room(room_id,stream_name);
}
},
goto_room(room_id,stream_name){
// get into the room 
var pageParam = {
name: this.current.name,
url: this.current.url,
room_id: room_id,
stream_name: stream_name
}
this.game.goFrame("room","live.html",pageParam);
},
add_room(){
this.game.goFrame("add_room","add_room.html",this.current,null,{
type:"push",
subType:"from_top",
duration:300
});
api.addEventListener({
name: 'add_room_success'
}, (ret, err)=>{
if( ret ){
this.game.print(" The room was created successfully ");
}
});
},
goto_home(){
// Exit the current page 
this.game.outWin("live");
},
}
});
}
</script>
</body>
</html>
The front end judges whether there is a password in the room , If there is a password , You have to enter the room with the correct password

5. When the user clicks the back button , Turn off streaming

1.live_list.html

Listen to any frame page in the current window and click the return button (keyback) The operation of

When the user clicks the back button , inform (sendEvent) Close the live room and push the stream

<!DOCTYPE html>
<html>
<head>
<title> Room list </title>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta charset="utf-8">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app user setting" id="app">
<div class="bg">
<img src="../static/images/rooms_bg.png">
</div>
<img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
<div class="add_friend_btn" @click="add_room">
<img src="../static/images/add_room.png" alt="">
</div>
<div class="friends_list room_list">
<div class="item" v-for="room in rooms" @click="goto_live(room.id,room.name,room.room_password)">
<div class="avatar">
<img class="user_avatar" :src="room.user && settings.static_url+room.user.avatar" alt="">
</div>
<div class="info">
<p class="username">{{room.room_name}}</p>
<p class="fruit"> The number of :{{room.clients_number}}</p>
</div>
<div class="behavior pick" v-if="room.status"> live broadcast </div>
<div class="goto"><img src="../static/images/arrow1.png" alt=""></div>
</div>
</div>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
rooms:[], // Room list 
 prev:{name:"",url:"",params:{}},
current:{name:"live",url:"live_list.html",params:{}},
}
},
created(){
this.get_room_list();
},
methods:{
get_room_list(){
var token = this.game.get("access_token") || this.game.fget("access_token");
this.axios.post("",{
"jsonrpc": "2.0",
"id": this.uuid(),
"method": "Live.stream.list",
"params": {}
},{
headers:{
Authorization: "jwt " + token,
}
}).then(response=>{
if(parseInt(response.data.result.errno)==1000){
this.rooms = response.data.result.stream_list;
}else{
this.game.print(response.data.result.errmsg);
}
}).catch(error=>{
// Network and other anomalies 
this.game.print(error);
});
},
goto_live(room_id,stream_name,room_password){
// Verify password 
if(room_password != null){
api.prompt({
title:" Please enter the room code !",
buttons: [' determine ', ' Cancel '],
}, (ret, err)=>{
if( ret.text == room_password ){
this.goto_room(room_id,stream_name);
}else {
alert(" Wrong password !");
}
});
}else{
this.goto_room(room_id,stream_name);
}
},
goto_room(room_id,stream_name){
// get into the room 
var pageParam = {
name: this.current.name,
url: this.current.url,
room_id: room_id,
stream_name: stream_name
}
// When the user clicks the return button in any frame page under the current window , Initiate global notification 
 api.addEventListener({
name: 'keyback'
}, (ret, err)=>{
// Tell the studio , Turn off live streaming 
 api.sendEvent({
name: 'live_page_out',
extra: {
}
});
});
this.game.goFrame("room","live.html",pageParam);
},
add_room(){
this.game.goFrame("add_room","add_room.html",this.current,null,{
type:"push",
subType:"from_top",
duration:300
});
api.addEventListener({
name: 'add_room_success'
}, (ret, err)=>{
if( ret ){
this.game.print(" The room was created successfully ");
// get into the room 
this.goto_room(ret.value.room_id,ret.value.stream_name);
}
});
},
goto_home(){
// Exit the current page 
this.game.outWin("live");
},
}
});
}
</script>
</body>
</html>
live_list.html Monitor exit action , And tell the studio to close the live streaming

2.live.html

Monitor whether the user returns , If it detects , Turn off the camera capture function and live streaming

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
<link rel="stylesheet" href="../static/css/main.css">
<script src="../static/js/vue.js"></script>
<script src="../static/js/axios.js"></script>
<script src="../static/js/main.js"></script>
<script src="../static/js/uuid.js"></script>
<script src="../static/js/settings.js"></script>
</head>
<body>
<div class="app" id="app">
<br><br><br><br>
<br><br><br><br>
<button @click="start_live"> I'm going to broadcast </button>
<button @click="viewer"> I'm the audience </button>
</div>
<script>
apiready = function(){
init();
new Vue({
el:"#app",
data(){
return {
music_play:true, //
 stream_name:"", // Live stream name 
 prev:{name:"",url:"",params:{}}, //
 current:{name:"live",url:"live_list.html","params":{}}, //
 }
},
created(){
this.stream_name = api.pageParam.stream_name;
},
methods:{
viewer(){
// Watch the live broadcast 
var obj = api.require('playModule');
obj.play({
rect:
{ x: 0,
y : 0,
w : 360,
h: 1080,
},
fixedOn: api.frameName,
title: 'test',
scalingMode:2,
url: this.settings.live_stream_server+this.stream_name,
defaultBtn: false,
enableFull : false,
isTopView : false,
isLive: true,
placeholderText:true,
}, (ret, err)=>{
this.game.print(ret);
});
},
liver(){
var token = this.game.get("access_token") || this.game.fget("access_token");
this.axios.post("",{
"jsonrpc": "2.0",
"id": this.uuid(),
"method": "Live.stream",
"params": {
"room_name": " Love studio "
}
},{
headers:{
Authorization: "jwt " + token,
}
}).then(response=>{
var message = response.data.result;
if(parseInt(message.errno)==1005){
this.game.goWin("user","login.html", this.current);
}
if(parseInt(message.errno)==1000){
this.stream_name = message.data.stream_name;
this.game.print(this.stream_name)
}else{
this.game.print(response.data);
}
}).catch(error=>{
// Network and other anomalies 
this.game.print(error);
});
},
start_live(){
// Live broadcast 
var acLive = api.require('acLive');
// Turn on the camera to collect video information 
 acLive.open({
camera:0, // 1 For the front camera , 0 For the rear camera , Default 1
 rect : { // The position and size of the acquisition screen 
 x : 0,
y : 0,
w : 360,
h : 1080,
}
},(ret, err)=>{
this.game.print(ret);
// Open up beauty 
 acLive.beautyFace();
// Start pushing 
 acLive.start({
url: this.settings.live_stream_server+this.stream_name // t1 That's the name of the stream , It can be understood as the room number of the live broadcast 
 },(ret, err)=>{
this.game.print(ret); // If the state is 2 The connection is successful , Everything else is not successful 
 });
});
// Monitor whether the user clicks the return button , If you click , Then turn off the streaming and camera information collection functions 
 api.addEventListener({
name:'live_page_out'
},()=>{
acLive.close();
acLive.end();
});
}
}
})
}
</script>
</body>
</html>
live.html Monitor whether the user returns , If it detects , Turn off the camera collection function and live streaming

 

Copyright statement
In this paper,the author:[iR-Poke],Reprint please bring the original link, thank you