I am working on a project where I can stream audio live to a HTML file from a server, I am using flask_socketio and Socket io for my client side. I am not sure why it is working, here is my code.
server.py
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecret'
socketio = SocketIO(app, cors_allowed_origins='*')
with open("bensound-spinningcollins.wav", "rb") as fwav:
data = fwav.read(8)
while data:
data = fwav.read(8)
#socketio.on('message')
def handleMessage(msg):
print('User has connected')
while True:
send(data)
if __name__ == '__main__':
socketio.run(app)
this is my client code
<html>
<head>
<title>Chat Room</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Quicksand&display=swap" rel="stylesheet">
<script src="https://cdn.socket.io/3.1.1/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script type="text/javascript">
var socket = io.connect('http://127.0.0.1:5000');
socket.on('connect', function() {
socket.send('connect');
});
socket.on('message', function(msg) {
audioObj = new Audio(msg);
audioObj.play();
});
</script>
</body>
</html>
Not enough rep to comment, so sorry for the reply.
I think the thing you are actually looking for is WebRTC.
Socket.io is great for sending messages back and forth but not so great at streaming something continuously.
If you try to just play a sound on a message, why not access the audio from JS directly?
Related
I began learning sockets today and I have some questions about how it works. I'm using flask_socketIO and this is the code I found in a tutorial
Main.py
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
app.config["SECRET_KEY"] = "secret"
socketio = SocketIO(app, cors_allowed_origins="*")
#socketio.on("message")
def handleMessage(msg):
print("Message: " + msg)
send(msg, broadcast=True)
if __name__ == "__main__":
socketio.run(app)
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chat room</title>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.0/socket.io.js"
integrity="sha512-/xb5+PNOA079FJkngKI2jvID5lyiqdHXaUUcfmzE0X0BdpkgzIWHC59LOG90a2jDcOyRsd1luOr24UCCAG8NNw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(() => {
var socket = io.connect("http://127.0.0.1:5000");
socket.on("connect", () => {
socket.send("User has connected!");
});
socket.once("disconnect", () => {
socket.send("User has disconnected!");
console.log("User Disconnected");
});
socket.on("message", (msg) => {
$("#messages").append("<li>" + msg + "</li>");
console.log("Message recieved");
});
$("#sendButton").on("click", () => {
socket.send($("#myMessage").val());
$("#myMessage").val("");
});
});
</script>
<ul id="messages"></ul>
<input type="text" id="myMessage" />
<button id="sendButton">Send</button>
</body>
</html>
I understand how message works but I don't understand how the connect and disconnect events work. When a new user goes on the page, it logs out both in terminal and on website"User has connected". Why does it do that even though I don't have print() for my terminal or a function similar to
$("#sendButton").on("click", () => {
socket.send($("#myMessage").val());
$("#myMessage").val("");
});
for the website. Also disconnect doesn't work at all, it doesn't console.log when a user disconnects. Does anyone know why?
When a new user goes on the page, it logs out both in terminal and on website"User has connected". Why does it do that even though I don't have print() for my terminal or a function similar to
The browser sends it to the the server. The server prints it (in the server's terminal) and also sends it to all the connected browsers, which log it in #messages.
Also disconnect doesn't work at all, it doesn't console.log when a user disconnects. Does anyone know why?
After the browser disconnects the browser tries to send the message to the server. The server never gets it because the browser already disconnected. Possibly the browser throws an exception when you try to send to a disconnected socket and so it never gets to the next line of code which calls console.log.
I have a flask application that I am trying to send some json to the browser and render it. But the line with $.getJSON() is not running. The jist of which is below:
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index_html():
data = {"this":"is", "just":"a test"}
return render_template('index.html', data=data)
if __name__ == '__main__':
app.run(debug=True)
index.html
<html>
<head>
<script src="{{url_for('static', filename='jquery-3.5.1.min.js')}}"></script>
<script src="{{url_for('static', filename='leaflet/leaflet.js')}}"></script>
<link rel="stylesheet" href="{{url_for('static', filename='leaflet/leaflet.css')}}">
<link rel="stylesheet" href="{{url_for('static', filename='app.css')}}">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<h1>My test that doesn't work</h1>
<div id="llmap"></div>
<script src="{{url_for('static', filename='app.js')}}"></script>
</body>
app.js
console.log("before")
$.getJSON("/", function(data){
console.log("during")
console.log(JSON.stringify(data));
});
console.log('after')
Console OUTPUT
before
after
Even if my data were somehow messed up, i'd expect at least to see
before
during
after
What am I not understanding here, why isn't getJSON() firing?
You are using
return render_template('index.html', data=data)
You need to return ONLY data when you call the .getJSON function. simple
return data
should work. Because getJSON doesn't allow POST request you'll have to add one more route
#app.route('/')
def index_html():
return render_template('index.html')
#app.route("/getjson")
def json():
data = {"this":"is", "just":"a test"}
return data
and change your getJSON request to
$.getJSON("/getjson", function(data){
console.log("during")
console.log(JSON.stringify(data));
});
I'm trying to make a chat application with flask and socketio but I get an Uncaught ReferenceError: io is not defined error in my web browsers inspector. Googling this error didn't give me much.
Here is my python code:
import requests
from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit
# Configure Flask-socketio
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
#socketio.on('message')
def handleMessage(message):
print('Message: ' + message)
send(message, broadcast=True;)
if __name__ == '__main__':
socketio.run(app)
And here is my html code:
<html>
<head>
<title>Test flask-socketio</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
</head>
<body>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
//When connected, configure submit button to emit message event
socket.on('connect', () => {
socket.send('User has connected!');
});
});
</script>
<ul id="messages"></ul>
<input type="test" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>
Does anybody know why I get this error?
Problem is that you are not getting the socket.io here. Below is correct HTML File code for you
<html>
<head>
<title>Test flask-socketio</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
//When connected, configure submit button to emit message event
socket.on('connect', () => {
socket.send('User has connected!');
});
});
</script>
<ul id="messages"></ul>
<input type="test" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>
I have updated the Address of Scripts here.
You will be getting cors error next, Goodluck.
I have a python script and apache web server running in a raspberry pi. I want to change the value of a variable in my python script from a web page using javascript. It is possible?
We can use socket. for easily using socket, we can use socket.io
Start.html
<!doctype html>
<html>
<head>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
</head>
<body>
<h1>Socket.IO GPIO control</h1>
<button id="btnGpio">Change GPIO</button>
<script>
var socket = io.connect('http://localhost:5000');
var index = 0;
socket.on('connect', function () {
console.log('connected')
document.getElementById('btnGpio').addEventListener('click', () => {
index = index + 1;
console.log('index', index)
socket.emit('change_gpio', { status: (index % 2 == 0) })
})
});
</script>
</body>
</html>
socket_server.py
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
#app.route("/")
def home():
return render_template("Start.html")
socketio = SocketIO(app)
pin = True
#socketio.on('change_gpio')
def handle_my_custom_event(json):
pin = json['status']
print('pin = ' , pin)
#socketio.on('connect', namespace='/')
def test_connect():
print('Connected')
if __name__ == '__main__':
socketio.run(app)
Install library with pip
pip install flask
pip install flask-socketio
Document:
https://flask-socketio.readthedocs.io/en/latest/
basically I looked everywhere for answers (google), I can't seem to find the solution. Basically what I'm doing is that I have a python server who scrapes sites and returns them to a page (depending on the url) in json. And the server gets the url's from a site where you enter where you want to search and what do you want to search. What I want to do is add cookies to the whole thing, because you can login to some sites for discount. What I can't figure out is how am i supposed to send my site cookies to my server. I'm using simplified code to test/find out how it works first.
Site URL:
http://localhost/looking/test.html
Server URL:
http://localhost:8082
Server request example:
http://localhost:8082/?search=dell&shop=rlyniceshop
HTML CODE
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" 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.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
<meta charset="UTF-8">
</head>
<body>
<button type="button" class="btn btn-outline-success" data-where="ASWO">Prisijungti</button>
<script>
if (Cookies.get('user') == null) {
var user = Date.now();
Cookies.set('user', user);
console.log(Cookies.get('user'));
}
$('.btn-outline-success').on('click', function(){
var url = 'http://localhost:8082/?search=dell&shop=pls';
$.ajax({
url: url,
method: "POST",
cookie: "TestCookie2=AAA"
});
});
</script>
</body>
PYTHON CODE
from http.server import BaseHTTPRequestHandler, HTTPServer
from bs4 import BeautifulSoup
from urllib.parse import urlparse, parse_qs
import urllib.request
import json
import os
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
crm_path="PATH TO CHROME DRIVER"
class Object:
def toJSON(self):
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True)
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/html; charset=utf-8')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
parsed = urlparse(self.path)
wow = urllib.parse.parse_qs(parsed.query)
luk = ''.join(wow['search'])
wer = ''.join(wow['parde'])
print(luk+wer);
message = "COMPLEX JSON"
self.wfile.write(bytes(message, "utf8"))
return
def run():
print('starting server...')
server_address = ('127.0.0.1', 8082)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
run()
If you think I'm unclear on something, please ask.
Right, so I figured it out on my own. It was easy to do as well tbh. Guess not sleeping well caught up with me. What i did was make a new var, where the cookies would be stored and send it as data. Like so:
var dat = Cookies.get()
$('.btn-outline-success').on('click', function(){
var url = 'http://localhost:8082/?search=dell&parde=pls';
$.ajax({
url: url,
method: "POST",
data: dat
});
});
And then get them from my site with get_POST, like so:
def do_POST(self):
self.send_response(200)
self.send_header('Content-type','text/html; charset=utf-8')
self.send_header('Access-Control-Allow-Origin', 'http://localhost')
self.end_headers()
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
parsed_q = urlparse(self.path)
parsed_b = urlparse(body.decode("utf-8"))
search_info = urllib.parse.parse_qs(parsed_q.query)
user_info = urllib.parse.parse_qs(parsed_b.path)
#print(''.join(wow['search']));
print(search_info);
print(user_info);
message = "Json code"
self.wfile.write(bytes(message, "utf8"))
return
This way i could keep my headers and send some additional data (content_length). I kept my do_GET in python code, just for the sake of if i need it in the future.
My current code looks like this now:
PYTHON:
from http.server import BaseHTTPRequestHandler, HTTPServer
from bs4 import BeautifulSoup
from urllib.parse import urlparse, parse_qs
import urllib.request
import json
import os
import re
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
crm_path="C:\\Users\\Duma\\Desktop\\site\\BrowersDriver\\chromedriver.exe"
class Object:
def toJSON(self):
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True)
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.send_header('Content-type','text/html; charset=utf-8')
self.send_header('Access-Control-Allow-Origin', 'http://localhost')
self.end_headers()
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
parsed_q = urlparse(self.path)
parsed_b = urlparse(body.decode("utf-8"))
search_info = urllib.parse.parse_qs(parsed_q.query)
user_info = urllib.parse.parse_qs(parsed_b.path)
#print(''.join(wow['search']));
print(search_info);
print(user_info);
message = "Json code"
self.wfile.write(bytes(message, "utf8"))
return
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/html; charset=utf-8')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
message = "Nothing to see here."
self.wfile.write(bytes(message, "utf8"))
return
def run():
print('starting server...')
server_address = ('127.0.0.1', 8082)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
run()
HTML:
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" 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.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
<meta charset="UTF-8">
</head>
<body>
<button type="button" class="btn btn-outline-success" data-where="ASWO">Prisijungti</button>
<script>
if (Cookies.get('user') == null) {
var user = Date.now();
Cookies.set('user', user);
console.log(Cookies.get('user'));
}
var dat = Cookies.get()
$('.btn-outline-success').on('click', function(){
var url = 'http://localhost:8082/?search=dell&parde=pls';
$.ajax({
url: url,
method: "POST",
data: dat
});
});
</script>
</body>
</html>
I hope this will help someone in the future who is looking for something similar :)