mirror of
https://github.com/damp11113/IDRB.git
synced 2025-04-27 22:48:09 +00:00
update 1.6.2
this update is update on server side new Buffer client side fix buffer
This commit is contained in:
parent
d5e6b8e1ea
commit
1e77eae2d8
Binary file not shown.
Binary file not shown.
@ -1,3 +1,20 @@
|
||||
"""
|
||||
This file is part of IDRB Project.
|
||||
|
||||
IDRB Project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
IDRB Project is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with IDRB Project. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import dearpygui.dearpygui as dpg
|
||||
|
||||
from utils import *
|
||||
@ -60,7 +77,7 @@ def window(self):
|
||||
dpg.add_spacer()
|
||||
dpg.add_text("IDRB (Internet Digital Radio Broadcasting System) Client")
|
||||
dpg.add_spacer()
|
||||
dpg.add_text(f"IDRB Client v1.6.1 Beta")
|
||||
dpg.add_text(f"IDRB Client v1.6.2 Beta")
|
||||
dpg.add_spacer()
|
||||
|
||||
desc = "IDRB is a novel internet radio broadcasting alternative that uses HLS/DASH/HTTP streams, transferring over TCP/IP. This system supports images and RDS (Dynamic update) capabilities, enabling the transmission of station information. Additionally, it allows for setting station logos and images. IDRB offers multi-broadcasting functionalities and currently supports the Opus codec, with plans to incorporate PCM, MP2/3, AAC/AAC+, and more in the future, ensuring low delay. If you find this project intriguing, you can support it at damp11113.xyz/support."
|
||||
@ -148,8 +165,10 @@ def window(self):
|
||||
dpg.add_text("Please restart software when configured")
|
||||
with dpg.tab_bar():
|
||||
with dpg.tab(label="Audio"):
|
||||
dpg.add_combo([], label="Output Device", tag="selectaudiooutputdevicecombo",
|
||||
callback=self.changeaudiodevice)
|
||||
dpg.add_combo([], label="Output Device", tag="selectaudiooutputdevicecombo", callback=self.changeaudiodevice)
|
||||
with dpg.tab(label="Network"):
|
||||
dpg.add_input_int(label="Buffer Size", tag="buffersizeintinput", callback=self.changebuffersize)
|
||||
|
||||
|
||||
def menubar(self):
|
||||
with dpg.viewport_menu_bar():
|
||||
|
@ -40,8 +40,7 @@ class App:
|
||||
self.config = configparser.ConfigParser()
|
||||
self.config.read("config.ini")
|
||||
self.device_name_output = self.config["audio"]["device"]
|
||||
self.buffersize = 64 # can configable
|
||||
|
||||
self.buffersize = self.config["network"]["buffersize"]
|
||||
|
||||
self.working = False
|
||||
self.readchannel = 1
|
||||
@ -60,8 +59,6 @@ class App:
|
||||
self.lsitem = None
|
||||
self.ccconwithpubselect = False
|
||||
self.buffer = queue.Queue(maxsize=self.buffersize)
|
||||
self.okbuffer = False
|
||||
self.firstrunbuffer = True
|
||||
|
||||
def connecttoserverwithpubselect(self, sender, data):
|
||||
self.ccconwithpubselect = True
|
||||
@ -125,8 +122,6 @@ class App:
|
||||
dpg.configure_item("station_logo_config", show=False)
|
||||
dpg.configure_item("RDSinfo", show=False)
|
||||
dpg.configure_item("disconnectbutton", show=False)
|
||||
dpg.configure_item("connectservergroup", show=True)
|
||||
dpg.configure_item("serverstatus", default_value='disconnected', color=(255, 0, 0))
|
||||
dpg.configure_item("logostatus", show=False)
|
||||
self.firstrun = True
|
||||
self.firststart = True
|
||||
@ -136,9 +131,7 @@ class App:
|
||||
self.ccisdecryptpassword = None
|
||||
self.cciswaitlogoim = True
|
||||
self.ccthreadlogorecisworking = False
|
||||
self.buffer = queue.Queue(maxsize=self.buffersize)
|
||||
self.okbuffer = False
|
||||
self.firstrunbuffer = True
|
||||
# clear buffer
|
||||
|
||||
def RDSshow(self):
|
||||
try:
|
||||
@ -231,6 +224,11 @@ class App:
|
||||
self.config["audio"]["device"] = dpg.get_value(sender)
|
||||
self.config.write(open('config.ini', 'w'))
|
||||
|
||||
def changebuffersize(self, sender, data):
|
||||
self.buffersize = int(dpg.get_value(sender))
|
||||
self.config["network"]["buffersize"] = str(dpg.get_value(sender))
|
||||
self.config.write(open('config.ini', 'w'))
|
||||
|
||||
def pubserverselectone(self, sender, data):
|
||||
if data == False:
|
||||
dpg.configure_item("connectbuttonpubserverselect", show=False)
|
||||
@ -295,9 +293,8 @@ class App:
|
||||
self.pubserverselectsearch()
|
||||
|
||||
def streambuffer(self, socket):
|
||||
consecutive_above_threshold = 0 # Counter to track consecutive iterations above threshold
|
||||
tolerance_iterations = 5 # Number of consecutive iterations required above threshold
|
||||
while self.working:
|
||||
try:
|
||||
if self.cprotocol == "TCP":
|
||||
tempdata = b''
|
||||
# data = socket.recv(1580152)
|
||||
@ -307,13 +304,22 @@ class App:
|
||||
if len(part) < 1024:
|
||||
# either 0 or end of data
|
||||
break
|
||||
self.buffer.put(tempdata)
|
||||
self.buffer.put(tempdata, timeout=0.1)
|
||||
elif self.cprotocol == "ZeroMQ":
|
||||
self.buffer.put(socket.recv())
|
||||
self.buffer.put(socket.recv(), timeout=0.1)
|
||||
else:
|
||||
self.buffer.put(b"")
|
||||
|
||||
dpg.configure_item("bufferstatus", default_value=f'Buffer: {self.buffer.qsize()}/{self.buffersize}')
|
||||
dpg.configure_item("bufferstatus", default_value=f'Buffer: {self.buffer.qsize()}/{self.buffersize}', color=(0, 255, 0))
|
||||
except queue.Full:
|
||||
dpg.configure_item("bufferstatus", default_value=f'Buffer: {self.buffer.qsize()}/{self.buffersize}', color=(255, 0, 0))
|
||||
|
||||
while not self.buffer.empty():
|
||||
self.buffer.get()
|
||||
|
||||
dpg.configure_item("bufferstatus", default_value=f'Buffer: {self.buffer.qsize()}/{self.buffersize}', color=(255, 255, 0))
|
||||
dpg.configure_item("serverstatus", default_value='disconnected', color=(255, 0, 0))
|
||||
dpg.configure_item("connectservergroup", show=True)
|
||||
|
||||
def stream(self, socket):
|
||||
opus_decoder = None
|
||||
@ -339,6 +345,7 @@ class App:
|
||||
if self.buffer.not_empty:
|
||||
data = self.buffer.get()
|
||||
else:
|
||||
dpg.configure_item("serverstatus", default_value='Buffering...', color=(255, 255, 0))
|
||||
continue
|
||||
|
||||
bytesconunt += len(data)
|
||||
@ -589,7 +596,7 @@ class App:
|
||||
ctypes.CDLL("opus.dll")
|
||||
|
||||
dpg.create_context()
|
||||
dpg.create_viewport(title=f'IDRB Client v1.6.1 Beta', width=1280, height=720, large_icon="IDRBfavicon.ico", clear_color=(43, 45, 48)) # set viewport window
|
||||
dpg.create_viewport(title=f'IDRB Client v1.6.2 Beta', width=1280, height=720, large_icon="IDRBfavicon.ico", clear_color=(43, 45, 48)) # set viewport window
|
||||
dpg.setup_dearpygui()
|
||||
# -------------- add code here --------------
|
||||
noimage_texture_data = []
|
||||
@ -621,6 +628,7 @@ class App:
|
||||
output_devices.append(device_info['name'])
|
||||
|
||||
dpg.configure_item("selectaudiooutputdevicecombo", items=output_devices, default_value=self.config["audio"]["device"])
|
||||
dpg.configure_item("buffersizeintinput", default_value=int(self.config["network"]["buffersize"]))
|
||||
|
||||
# -------------------------------------------
|
||||
dpg.show_viewport()
|
||||
|
@ -1,6 +1,9 @@
|
||||
[audio]
|
||||
device = Speakers (2- USB Audio DAC )
|
||||
|
||||
[network]
|
||||
buffersize = 128
|
||||
|
||||
[debug]
|
||||
hideconsole = true
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
"""
|
||||
This file is part of IDRB Project.
|
||||
|
||||
IDRB Project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
IDRB Project is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with IDRB Project. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Protocol.KDF import scrypt
|
||||
import numpy as np
|
||||
|
@ -15,10 +15,17 @@ You should have received a copy of the GNU General Public License
|
||||
along with IDRB Project. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
# To config Muxer you need to goto server.py and find "Config Muxer"
|
||||
# To config RDS you need to goto RDS.py
|
||||
# To config Encoder you need to goto Encoder.py
|
||||
# Do not goto ThaiSDRDir.py and utils.py
|
||||
|
||||
# Server Settings
|
||||
protocol = "ZMQ_WS" # TCP ZMQ ZMQ_WS
|
||||
server_port = ('*', 6980) # if use other protocol ZMQ please use 0.0.0.0
|
||||
compression_level = 9 # 0-9
|
||||
buffersize = 32 # must be int (on working it use buffersize + (buffersize/2) to standby)
|
||||
# low buffersize = low delay
|
||||
|
||||
# Server Info
|
||||
ServerName = "DPCloudev"
|
||||
@ -40,4 +47,4 @@ public = True
|
||||
ServerIP = "localhost"
|
||||
#ServerPort = server_port[1]
|
||||
ServerPort = 6980
|
||||
ThaiSDRkey = "1N5LURICLIN1U9QNYZ4MHJ6FNXISFXFELZAX135CFM0HSD17O2.63E60BE9EEA2339C113A15EB"
|
||||
ThaiSDRkey = ""
|
Binary file not shown.
@ -22,6 +22,8 @@ import threading
|
||||
import zmq
|
||||
import logging
|
||||
import zlib
|
||||
import queue
|
||||
import math
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s')
|
||||
ServerLog = logging.getLogger("IDRBServer")
|
||||
@ -61,7 +63,6 @@ _RDS.startRDSThread()
|
||||
ServerLog.info('starting audio encoding')
|
||||
Encoder.StartEncoder()
|
||||
|
||||
|
||||
if protocol == "TCP":
|
||||
connected_users = 0
|
||||
elif protocol == "ZMQ":
|
||||
@ -74,9 +75,11 @@ timestart = time.time()
|
||||
connectionlist = []
|
||||
first = True
|
||||
|
||||
def handle_client():
|
||||
global connected_users, first
|
||||
try:
|
||||
Buffer = queue.Queue(maxsize=math.trunc(Settings.buffersize + (Settings.buffersize/2)))
|
||||
|
||||
# ---------------------------------- Config Muxer ---------------------------------------
|
||||
|
||||
def Muxer():
|
||||
while True:
|
||||
# Get the encoded audio from the buffer
|
||||
ENchannel1 = Encoder.channel1.get()
|
||||
@ -118,34 +121,52 @@ def handle_client():
|
||||
|
||||
compressedcontent = zlib.compress(pickle.dumps(content), level=Settings.compression_level)
|
||||
|
||||
#connection.sendall(pickle.dumps(content))
|
||||
Buffer.put(compressedcontent)
|
||||
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
|
||||
def handle_client():
|
||||
global connected_users, first
|
||||
try:
|
||||
while True:
|
||||
# Check if the buffer queue has enough data to send
|
||||
if Buffer.qsize() >= Settings.buffersize: # Adjust the threshold as needed
|
||||
if protocol == "TCP":
|
||||
for i in connectionlist:
|
||||
try:
|
||||
i.sendall(compressedcontent)
|
||||
# Send data from the buffer queue to connected clients
|
||||
for _ in range(Settings.buffersize):
|
||||
i.sendall(Buffer.get())
|
||||
except Exception as e:
|
||||
#print(f'Error sending data to {i.getpeername()}: {e}')
|
||||
# Remove disconnected client from the list
|
||||
if i in connectionlist:
|
||||
i.close()
|
||||
connectionlist.remove(i)
|
||||
connected_users -= 1
|
||||
# check if no user
|
||||
if not connectionlist:
|
||||
first = True
|
||||
ServerLog.info('server is standby now')
|
||||
break
|
||||
elif protocol == "ZMQ":
|
||||
s.send(compressedcontent)
|
||||
# Send data from the buffer queue to ZMQ socket
|
||||
for _ in range(Settings.buffersize):
|
||||
s.send(Buffer.get())
|
||||
except Exception as e:
|
||||
print(f'Error: {e}')
|
||||
|
||||
|
||||
# Your main server logic using threading for handling connections
|
||||
if __name__ == "__main__":
|
||||
if public:
|
||||
ServerLog.info('starting ThaiSDR Directory')
|
||||
ThaiSDRDir.run()
|
||||
ServerLog.info('server is running')
|
||||
|
||||
ServerLog.info('starting Muxer')
|
||||
|
||||
muxerthread = threading.Thread(target=Muxer)
|
||||
muxerthread.start()
|
||||
|
||||
ServerLog.info('starting server')
|
||||
|
||||
if protocol == "TCP":
|
||||
while True:
|
||||
connection, client_address = s.accept()
|
||||
@ -163,3 +184,5 @@ if __name__ == "__main__":
|
||||
client_thread = threading.Thread(target=handle_client)
|
||||
# client_thread.daemon = True # Set the thread as a daemon so it exits when the main thread exits
|
||||
client_thread.start()
|
||||
|
||||
ServerLog.info('server is running')
|
Loading…
x
Reference in New Issue
Block a user