My task is to get the video stream from the client's webcam, analyze it and return the result as a string. Reading the documentation on aiortc and looking at their examples on git, I could only do this option:
async def offer(request):
params = await request.json()
offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])
pc = RTCPeerConnection()
pcs.add(pc)
await server(pc, offer)
return web.Response(
content_type="application/json",
text=json.dumps(
{"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
),
)
pcs = set()
async def server(pc, offer):
#pc.on("connectionstatechange")
async def on_connectionstatechange():
print("Connection state is %s" % pc.connectionState)
if pc.connectionState == "failed":
await pc.close()
pcs.discard(pc)
#pc.on("track")
def on_track(track):
print("======= received track: ", track)
if track.kind == "video":
global new_video_track
new_video_track = Sign(track)
pc.addTrack(new_video_track)
#pc.on("datachannel")
def on_datachannel(channel):
global new_video_track
new_video_track.channel = channel
print("mounted channel")
#channel.on("message")
async def on_message(message):
if isinstance(message, str):
data = message.encode("utf-8")
else:
data = message
print("receive data: ", data)
await pc.setRemoteDescription(offer)
answer = await pc.createAnswer()
await pc.setLocalDescription(answer)
async def on_shutdown(app):
# close peer connections
coros = [pc.close() for pc in pcs]
await asyncio.gather(*coros)
pcs.clear()
class Sign(VideoStreamTrack):
kind = "video"
def __init__(self, track):
super().__init__()
self.track = track
self.channel = None
async def recv(self):
frame = await self.track.recv()
# getting the result I need
if self.channel and self.sentence:
self.channel.send(json.dumps({'word': self.sentence}))
return frame
But this result is not satisfactory, because I need to return the frame. How to make it so that only my word is returned.
Here's the client.js
var pc = null;
var localVideo = document.querySelector("video#localVideo");
var serverVideo = document.querySelector("video#serverVideo");
navigator.mediaDevices.getUserMedia({
video: {
height: 1080,
width: 1920,
frameRate: {
max: 10
}
}
}).then(stream => {
localVideo.srcObject = stream;
localVideo.addEventListener('loadedmetadata', () => {
localVideo.play();
});
});
function negotiate () {
return pc.createOffer().then(function (offer) {
return pc.setLocalDescription(offer);
}).then(function () {
// wait for ICE gathering to complete
return new Promise(function (resolve) {
if (pc.iceGatheringState === 'complete') {
resolve();
} else {
function checkState () {
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
pc.addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function () {
var offer = pc.localDescription;
return fetch('/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type,
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
});
}).then(function (response) {
return response.json();
}).then(function (answer) {
return pc.setRemoteDescription(answer);
}).catch(function (e) {
alert(e);
});
}
function start () {
var config = {
sdpSemantics: 'unified-plan',
iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }]
};
pc = new RTCPeerConnection(config);
localVideo.srcObject.getVideoTracks().forEach(track => {
pc.addTrack(track);
});
pc.addEventListener('track', function (evt) {
console.log("receive server video");
if (evt.track.kind == 'video') {
serverVideo.srcObject = evt.streams[0];
}
});
ch = pc.createDataChannel("chat", {
ordered: false,
maxRetransmits: 0,
});
ch.addEventListener("message", function (evt) {
console.log(Date.now() - JSON.parse(evt.data).now);
});
document.getElementById('start').style.display = 'none';
negotiate();
document.getElementById('stop').style.display = 'inline-block';
}
function stop () {
document.getElementById('stop').style.display = 'none';
setTimeout(function () {
pc.close();
}, 500);
}
Thank you in advance and forgive the large chunks of code.
You can use jinja template. You can send only variable values.
This is an example of jinja template https://aiohttp-jinja2.readthedocs.io/en/stable/
Related
I'm trying to retrieve the session data after login but it doesn't seem to be saving the information
.
class getSession(View):
def post(self, request):
print('====================>')
print(request.session.get('usuario'))
sesion = request.session.get('usuario')
return JsonResponse({'nombre': sesion.nombre, 'rut':sesion.rut})
class Login(View):
def post(self, request):
data = json.loads(request.body)
try:
usuario = Usuario.objects.get(rut=data['rut'], password=data['password'])
request.session['usuario'] = {'nombre': usuario.idpersona.name, 'rut': usuario.rut}
request.session.modified = True
#print(self.request.session['usuario'])
return JsonResponse({'usuario':usuario.rut})
except:
return JsonResponse({'usuario':'no existe'})
I'm get this error.
AttributeError: 'NoneType' object has no attribute 'nombre'
I'am using fetch with react.
async login() {
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
rut: this.state.rut,
password: this.state.password,
}),
};
const response = await fetch("http://127.0.0.1:8000/test", requestOptions);
const data = await response.json();
if (data.usuario == "no existe") {
mensajeError("RUT o contraseña inválidos.");
} else {
mensajeExitoso("Usuario validado correctamente.");
setTimeout(() => {
window.location.href = "/Inicio";
}, 2000);
}
console.log(data.usuario);
}
try setting SESSION_SAVE_EVERY_REQUEST = True in settings.py
Code:
const WebSocket = require('ws');
const shaUtil = require('js-sha256');
String.prototype.hashCode = function() {
return shaUtil(String(this));
};
const server = new WebSocket.Server({port:2909}); // Change to another port if you like.
// Hashes of client keys. Generate them using getHash.js and place them here.
const passes = {
'86cec081a5288000ddb804c24ac70de62a5060e5b4f4068b01a01f9f29dddacc': 0, // Receiver's key.
'c01223ad2ba8cdd184ded788cf6d3469111229cbe6cb3939ce24f471e8f257ca': 1, // Buzzer #1's key.
'5476be1700a54be0572b0066b32b5905986641fa163c5eabd52369eb3a2685cf': 2 // Buzzer #2's key...
};
var receiver = null;
var senders = {1: null, 2: null, 3: null, 4: null}; // You can add more/remove buzzers if you want to.
const lockClients = true; // If it is true, a connected client will not be overriden by another client logging in until it disconnects.
if (lockClients) canConnect = function(id) {
if (id == 0) return receiver === null;
return senders[id] === null;
}
else canConnect = function(id) {
return true;
}
function processBuzzer(client) {
if (receiver == null) return;
receiver.send('BUZZER '+client.buzzerId);
//console.log('Buzzer #'+client.buzzerId+' is activated.');
}
function onDisconnect(id) {
if (id === 0) {
receiver = null;
console.log('Receiver has disconnected.');
} else {
senders[id] = null;
console.log('Sender #' + id + ' has disconnected.');
}
}
server.on('connection', function(client) {
client.sendBuzzer = function() {};
client.on('message', function(message) {
if (message.startsWith('PASSWORD: ')) {
let id = passes[message.substring(10).hashCode()];
if (id !== undefined && canConnect(id)) {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
client.buzzerId = id;
if (id === 0) {
receiver = client;
console.log('Receiver has connected.');
} else {
senders[id] = client;
console.log('Sender #' + id + ' has connected.');
client.sendBuzzer = function() { processBuzzer(this) };
client.send('CONNECTED SUCCESSFULLY');
}
}
}
if (message == 'BUZZER') client.sendBuzzer();
});
client.on('close', function() {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
});
});
console.log('Server is running.');
If i started this with nodeJS with "node server.js", it appears Server is running.....no mistakes.....and now, Iwill connect to this server with the receiver.py (Python-File):
serverAddress = 'ws://192.168.1.50:2909' # The server's address.
clientKey = 'receiver' # The client key corresponding to the receiver's hash.
buzzerSoundFile = 'buzzer.wav' # The name/path of the buzzer sound file.
import asyncio
import websockets
from win32com.client import Dispatch
import winsound
from threading import Thread
app = Dispatch('Powerpoint.Application')
def playBuzzerSound():
global buzzerSoundFile
winsound.PlaySound(buzzerSoundFile, winsound.SND_FILENAME+winsound.SND_ASYNC)
async def mainFunction():
global serverAddress, clientKey
async with websockets.connect(serverAddress) as ws:
await ws.send('PASSWORD: ' + clientKey)
while True:
msg = await ws.recv()
if msg.startswith('BUZZER '):
if app.Run('onBuzzerActivated', int(msg[7:])):
Thread(target=playBuzzerSound).start();
asyncio.get_event_loop().run_until_complete(mainFunction())
I got an error 200 like this:
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 200
What's wrong ??
I am doing a Django project in which I have added a live chat feature using Django channels. When I finished the messaging part I worked on other parts of the project (like posting, liking posts, and in general parts that have nothing to do with the messaging). However now when I test the messaging page I get the following error in my browser console:
8_9:58 WebSocket connection to 'ws://127.0.0.1:8000/ws/chat/8_9/' failed:
The error has no further explanation after the colon (which is why I don't even know where to start solving it, I've had similar errors but they always had something else after the colon). I also tried rolling back to an older version of my app using GitHub (I went back to the last version that I was sure was working) and it still didn't work.
Here is my js code:
const roomName = JSON.parse(document.getElementById('room-name').textContent);
var chatSocket = "";
if(document.location.protocol == "https:"){
chatSocket = new WebSocket(
'wss://'
+ window.location.host
+ '/wss/chat/'
+ roomName
+ '/'
);
}
else{
chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/chat/'
+ roomName
+ '/'
);
}
chatSocket.addEventListener('open', function(event) {
$.ajax({
url: '/ajax/get_msg/',
data: {
'room': roomName
},
dataType: 'json',
success: function (data) {
var realData=data[0];
var i=0;
while(i<realData.length){
document.querySelector('#chat-log').value += (realData[i][0] + ': ' + realData[i][1] + '\n');
i++;
}
}
});
})
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
document.querySelector('#chat-log').value += (data.user + ': ' + data.message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message,
}));
messageInputDom.value = '';
};
My routing:
# Django imports
from django.urls import re_path
from . import consumers
# routing to the consumer
websocket_urlpatterns=[
re_path(r'wss/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
]
My consumer:
import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth import get_user_model
from .models import Message
User = get_user_model()
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# get both users
user = self.scope["user"]
get_ids = self.scope["url_route"]["kwargs"]["room_name"]
ids = get_ids.split('_')
my_user = User.objects.get(username=user.username)
my_id = my_user.id
other_id = 0
if str(ids[0]) == str(my_id):
other_id = ids[1]
else:
other_id = ids[0]
other_user = User.objects.get(pk=other_id)
# save the sent message to a database
new_message = Message(sender=my_user, rec=other_user, text=message, room=get_ids)
new_message.save()
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'user': user.username,
}
)
# Receive message from room group
def chat_message(self, event):
message = event['message']
# get the user that sent the message
user = event['user']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message,
'user': user
}))
And my settings:
CACHES = {
"default": {
"BACKEND": "redis_cache.RedisCache",
"LOCATION": REDIS_URI,
}
}
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [REDIS_URI],
},
},
}
Any help would be greatly appreciated
Cannot to sign in, i run localy in docker my container, i can sign-in on my machine and docker no error, but on my remote server i cannot to login, it doesn't write cookie in reponse, have no error, just don't write response. It just redirect me on my page which i setted,and after that i got error, cause i have no my cookie authorization key inside cookie.
video
My SignIn method
#auth_router.post('/signin')
async def sign_in(response: Response, username: str = Form(...), password: str = Form(...), recaptchav3: str = Form(...)) -> dict:
is_human = await verify_recaptcha(recaptchav3)
if is_human['success']:
user = await authenticate_user(username, password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail='Invalid username or password',
)
user_obj = await User_Pydantic.from_tortoise_orm(user)
user_token = await generate_token(user_obj)
response.set_cookie(key="Authorization", value=user_token, httponly=True, secure=True, expires=(8*60*60))
response.headers["Authorization"] = user_token
user.jwt_token = user_token
await user.save()
return {
'access_token': user_token,
'token_type': 'bearer'
}
else:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Invalid captcha',
)
How i submit my form js
const request = (method, url, data = null, redirectPage) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open(method, url, true)
// xhr.setRequestHeader('Content-Type', 'multipart/form-data')
xhr.onerror = function (event) {
alert(event)
console.log(event);
};
xhr.onload = () => {
if (xhr.status === 200) {
return window.location.href = redirectPage;
return resolve(JSON.parse(xhr.responseText || '{}'))
} else {
alert(`Request failed with status ${xhr.status}`)
reject(new Error(`Request failed with status ${xhr.status}`))
return window.location.reload();
}
}
if (data) {
if (typeof data === 'string' || data instanceof String || typeof data.constructor == Object){
xhr.send(JSON.stringify(data))
} else {
xhr.send(data)
}
} else {
xhr.send()
}
})
}
signInForm = getElementById('signinform');
handleEvent(signInForm, 'submit', e => {
e.preventDefault();
if(!isEmpty(signInForm)){
signInUsername = getElement('input[name="username"]', signInForm).value;
signInPassword = getElement('input[name="password"]', signInForm).value;
recaptchaV3 = getElement('[name="g-recaptcha-response"]').value;
if(recaptchaV3){
signInData = new FormData();
signInData.append('username', signInUsername);
signInData.append('password', signInPassword);
signInData.append('recaptchav3', recaptchaV3);
isLogened = request('POST', '/signin', signInData, 'dashboard');
} else{
alert('Перезагрузите страницу');
}
}
})
I cannot understand why using the built-in method in fastapi it does not write on the remote server, it worked on the local one, but I solved the problem by writing. token via js.
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkCookie(cookieValue) {
var user = getCookie("Authorization");
if (user == "") {
if (cookieValue != "" && cookieValue != null) {
setCookie("Authorization", cookieValue, 365);
}
}
}
signInForm = getElementById('signinform');
handleEvent(signInForm, 'submit', e => {
e.preventDefault();
if(!isEmpty(signInForm)){
signInUsername = getElement('input[name="username"]', signInForm).value;
signInPassword = getElement('input[name="password"]', signInForm).value;
recaptchaV3 = getElement('[name="g-recaptcha-response"]').value;
if(recaptchaV3){
signInData = new FormData();
signInData.append('username', signInUsername);
signInData.append('password', signInPassword);
signInData.append('recaptchav3', recaptchaV3);
isLogened = request('POST', '/signin', signInData);//, 'dashboard');
isLogened.then(result => {
checkCookie(result.access_token);
return window.location.href = 'dashboard';
}, result => {
log('Cant get response')
});
} else{
alert('Перезагрузите страницу');
}
}
})
I'm trying to upload a picture to my server with some additional data. My angularJs code is that:
function create_question(question, callback){
var form = new FormData()
var settings = {
"url": "http://127.0.0.1:8000/" + "question/api/create_question/",
"method": "POST",
"headers": {
'Content-Type': undefined
},
"processData": false,
"data": form
}
$cordovaFile.readAsDataURL(cordova.file.dataDirectory, question.name)
.then(function (success) {
form.append("file", success)
form.append("title", question.title)
form.append("options", JSON.stringify(question.options))
form.append("correct_option", question.correct_option)
form.append("question_id", question.question_id)
form.append("project_id", question.project_id)
$http(settings).then(function (response) {
if (response.data.hasOwnProperty("date_str")) {
callback(true, response.data)
console.log("succesFull")
} else {
console.log(JSON.stringify(response.data))
callback(false, response.data)
}
}, function (response) {
console.log(Utf8Decode(response.data))
callback(false, response.data)
});
// success
}, function (error) {
callback(false,error)
// error
});
}
In my server, I have that view:
#parser_classes((MultiPartParser, ))
class CreateQuestion(APIView):
def post(self, request, format=None):
picture = request.data['file']
question_id = request.data['question_id']
project_id = request.data['project_id']
options = request.data['options']
title = request.data['title']
correct_option = request.data['correct_option']
username = request.user.username
project = Project.objects.get(project_id=project_id)
if project.owner_user.username == username:
ext = '.jpg'
aws = AWSClient()
picture_name = question_id + ext
picture_url = aws.put(picture, 'question_pictures', picture_name)
question = Question.objects.create(question_id=question_id, title=title,
picture_url=picture_url, options=options, owner_project=project,
correct_option=correct_option)
project.question_count += 1
project.picture_url = picture_url
project.save()
serializer = QuestionSerializer(question, context={"request": request})
return JsonResponse(serializer.data)
else:
return JsonResponse({"result": "fail"})
After I made the request, question was created and the picture file was uploaded to Amazon S3. However, I could not open the resulting file in my pc. Where am I doing mistake?
After a long search on the internet, I found the answer. First, I read file with
$cordovaFile.readAsArrayBuffer(directory,filename)
After that, I created a Blob object with the file:
var imgBlob = new Blob([success], { type: "image/jpeg" } );
My final angularJS code is:
function create_question(question, callback){
var form = new FormData()
$cordovaFile.readAsArrayBuffer(cordova.file.dataDirectory, question.name)
.then(function (success) {
var imgBlob = new Blob([success], { type: "image/jpeg" } );
form.append("file", imgBlob)
form.append("title", question.title)
form.append("options", JSON.stringify(question.options))
form.append("correct_option", question.correct_option)
form.append("question_id", question.question_id)
form.append("project_id", question.project_id)
var settings = {
"url": "http://127.0.0.1:8000/" + "question/api/create_question/",
"method": "POST",
"headers": {
'Content-Type': undefined
},
"filename": question.id,
"processData": false,
"data": form,
"file": success,
"filename": "file"
}
$http(settings).then(function (response) {
if (response.data.hasOwnProperty("date_str")) {
callback(true, response.data)
console.log("succesFull")
} else {
console.log(JSON.stringify(response.data))
callback(false, response.data)
}
}, function (response) {
console.log(JSON.stringify(response.data))
callback(false, response.data)
});
// success
}, function (error) {
callback(false,error)
// error
});
}