This commit is contained in:
@@ -30,15 +30,15 @@ class AudioStream:
|
|||||||
if _input:
|
if _input:
|
||||||
self.paInstance_kwargs['input_device_index'] = _input_device_index
|
self.paInstance_kwargs['input_device_index'] = _input_device_index
|
||||||
else:
|
else:
|
||||||
LOGGER.warning(f"[AudioStream.__init__]:\tInput was not enabled."
|
LOGGER.warning("[AudioStream.__init__]:\tInput was not enabled."
|
||||||
f" Reinitialize with '_input=True'")
|
" Reinitialize with '_input=True'")
|
||||||
|
|
||||||
if _output_device_index:
|
if _output_device_index:
|
||||||
if _output:
|
if _output:
|
||||||
self.paInstance_kwargs['output_device_index'] = _output_device_index
|
self.paInstance_kwargs['output_device_index'] = _output_device_index
|
||||||
else:
|
else:
|
||||||
LOGGER.warning(f"[AudioStream.__init__]:\tOutput was not enabled."
|
LOGGER.warning("[AudioStream.__init__]:\tOutput was not enabled."
|
||||||
f" Reinitialize with '_output=True'")
|
" Reinitialize with '_output=True'")
|
||||||
|
|
||||||
if _init_on_startup:
|
if _init_on_startup:
|
||||||
# Init PyAudio instance
|
# Init PyAudio instance
|
||||||
@@ -59,15 +59,15 @@ class AudioStream:
|
|||||||
if self.paInstance_kwargs['input']:
|
if self.paInstance_kwargs['input']:
|
||||||
self.paInstance_kwargs['input_device_index'] = _new_input_device_index
|
self.paInstance_kwargs['input_device_index'] = _new_input_device_index
|
||||||
else:
|
else:
|
||||||
LOGGER.warning(f"[AudioStream.init_stream]:\tInput was not enabled when initialized."
|
LOGGER.warning("[AudioStream.init_stream]:\tInput was not enabled when initialized."
|
||||||
f" Reinitialize with '_input=True'")
|
" Reinitialize with '_input=True'")
|
||||||
|
|
||||||
if _new_output_device_index:
|
if _new_output_device_index:
|
||||||
if self.paInstance_kwargs['output']:
|
if self.paInstance_kwargs['output']:
|
||||||
self.paInstance_kwargs['output_device_index'] = _new_output_device_index
|
self.paInstance_kwargs['output_device_index'] = _new_output_device_index
|
||||||
else:
|
else:
|
||||||
LOGGER.warning(f"[AudioStream.init_stream]:\tOutput was not enabled when initialized."
|
LOGGER.warning("[AudioStream.init_stream]:\tOutput was not enabled when initialized."
|
||||||
f" Reinitialize with '_output=True'")
|
" Reinitialize with '_output=True'")
|
||||||
|
|
||||||
self.close_if_open()
|
self.close_if_open()
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ class AudioStream:
|
|||||||
if self.stream.is_active():
|
if self.stream.is_active():
|
||||||
self.stream.stop_stream()
|
self.stream.stop_stream()
|
||||||
self.stream.close()
|
self.stream.close()
|
||||||
LOGGER.debug(f"[ReopenStream.close_if_open]:\t Stream was open; It was closed.")
|
LOGGER.debug("[ReopenStream.close_if_open]:\t Stream was open; It was closed.")
|
||||||
|
|
||||||
def list_devices(self, _display_input_devices: bool = True, _display_output_devices: bool = True):
|
def list_devices(self, _display_input_devices: bool = True, _display_output_devices: bool = True):
|
||||||
LOGGER.info('Getting a list of the devices connected')
|
LOGGER.info('Getting a list of the devices connected')
|
||||||
@@ -126,7 +126,7 @@ class NoiseGate(AudioStream):
|
|||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
global voice_connection
|
global voice_connection
|
||||||
# Start the audio stream
|
# Start the audio stream
|
||||||
LOGGER.debug(f"Starting stream")
|
LOGGER.debug("Starting stream")
|
||||||
self.stream.start_stream()
|
self.stream.start_stream()
|
||||||
# Start the stream to discord
|
# Start the stream to discord
|
||||||
self.core()
|
self.core()
|
||||||
@@ -139,15 +139,15 @@ class NoiseGate(AudioStream):
|
|||||||
time.sleep(.2)
|
time.sleep(.2)
|
||||||
|
|
||||||
if not voice_connection.is_playing():
|
if not voice_connection.is_playing():
|
||||||
LOGGER.debug(f"Playing stream to discord")
|
LOGGER.debug("Playing stream to discord")
|
||||||
voice_connection.play(self.NGStream, after=self.core)
|
voice_connection.play(self.NGStream, after=self.core)
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
LOGGER.debug(f"Closing")
|
LOGGER.debug("Closing")
|
||||||
await voice_connection.disconnect()
|
await voice_connection.disconnect()
|
||||||
if self.stream.is_active:
|
if self.stream.is_active:
|
||||||
self.stream.stop_stream()
|
self.stream.stop_stream()
|
||||||
LOGGER.debug(f"Stopping stream")
|
LOGGER.debug("Stopping stream")
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
@@ -155,7 +155,7 @@ class NoiseGateStream(discord.AudioSource):
|
|||||||
def __init__(self, _stream):
|
def __init__(self, _stream):
|
||||||
super(NoiseGateStream, self).__init__()
|
super(NoiseGateStream, self).__init__()
|
||||||
self.stream = _stream # The actual audio stream object
|
self.stream = _stream # The actual audio stream object
|
||||||
self.NG_fadeout = 240/20 # Fadeout value used to hold the noisegate after de-triggering
|
self.NG_fadeout = 240 / 20 # Fadeout value used to hold the noisegate after de-triggering
|
||||||
self.NG_fadeout_count = 0 # A count set when the noisegate is triggered and was de-triggered
|
self.NG_fadeout_count = 0 # A count set when the noisegate is triggered and was de-triggered
|
||||||
self.process_set_count = 0 # Counts how many processes have been made
|
self.process_set_count = 0 # Counts how many processes have been made
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import platform
|
import platform
|
||||||
import os
|
import os
|
||||||
from discord import VoiceClient, VoiceChannel, opus, Activity, ActivityType, Intents
|
from discord import VoiceClient, VoiceChannel, opus, Activity, ActivityType, Intents
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from typing import Optional, Dict
|
from typing import Optional, Dict
|
||||||
from internal.NoiseGatev2 import NoiseGate
|
from internal.NoiseGatev2 import NoiseGate
|
||||||
@@ -84,16 +84,16 @@ class DiscordBotManager:
|
|||||||
|
|
||||||
if guild_id in self.voice_clients:
|
if guild_id in self.voice_clients:
|
||||||
raise RuntimeError("Already connected to this guild's voice channel.")
|
raise RuntimeError("Already connected to this guild's voice channel.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
voice_client = await channel.connect(timeout=60.0, reconnect=True)
|
voice_client = await channel.connect(timeout=60.0, reconnect=True)
|
||||||
LOGGER.debug(f"Voice Connected.")
|
LOGGER.debug("Voice Connected.")
|
||||||
streamHandler = NoiseGate(
|
streamHandler = NoiseGate(
|
||||||
_input_device_index=device_id,
|
_input_device_index=device_id,
|
||||||
_voice_connection=voice_client,
|
_voice_connection=voice_client,
|
||||||
_noise_gate_threshold=ng_threshold)
|
_noise_gate_threshold=ng_threshold)
|
||||||
streamHandler.run()
|
streamHandler.run()
|
||||||
LOGGER.debug(f"Stream is running.")
|
LOGGER.debug("Stream is running.")
|
||||||
self.voice_clients[guild_id] = voice_client
|
self.voice_clients[guild_id] = voice_client
|
||||||
LOGGER.info(f"Joined guild {guild_id} voice channel {channel_id} and stream is running.")
|
LOGGER.info(f"Joined guild {guild_id} voice channel {channel_id} and stream is running.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -117,18 +117,18 @@ class DiscordBotManager:
|
|||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
LOGGER.debug("Processor: ", processor)
|
LOGGER.debug("Processor: ", processor)
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
if processor == "AMD64":
|
if processor == "AMD64":
|
||||||
opus.load_opus(os.path.join(script_dir, './opus/libopus_amd64.dll'))
|
opus.load_opus(os.path.join(script_dir, './opus/libopus_amd64.dll'))
|
||||||
LOGGER.info(f"Loaded OPUS library for AMD64")
|
LOGGER.info("Loaded OPUS library for AMD64")
|
||||||
return "AMD64"
|
return "AMD64"
|
||||||
else:
|
else:
|
||||||
if processor == "aarch64":
|
if processor == "aarch64":
|
||||||
opus.load_opus(os.path.join(script_dir, './opus/libopus_aarcch64.so'))
|
opus.load_opus(os.path.join(script_dir, './opus/libopus_aarcch64.so'))
|
||||||
LOGGER.info(f"Loaded OPUS library for aarch64")
|
LOGGER.info("Loaded OPUS library for aarch64")
|
||||||
return "aarch64"
|
return "aarch64"
|
||||||
elif processor == "armv7l":
|
elif processor == "armv7l":
|
||||||
opus.load_opus(os.path.join(script_dir, './opus/libopus_armv7l.so'))
|
opus.load_opus(os.path.join(script_dir, './opus/libopus_armv7l.so'))
|
||||||
LOGGER.info(f"Loaded OPUS library for armv7l")
|
LOGGER.info("Loaded OPUS library for armv7l")
|
||||||
return "armv7l"
|
return "armv7l"
|
||||||
|
|
||||||
async def set_presence(self, presence: str):
|
async def set_presence(self, presence: str):
|
||||||
@@ -136,4 +136,4 @@ class DiscordBotManager:
|
|||||||
try:
|
try:
|
||||||
await self.bot.change_presence(activity=Activity(type=ActivityType.listening, name=presence))
|
await self.bot.change_presence(activity=Activity(type=ActivityType.listening, name=presence))
|
||||||
except Exception as pe:
|
except Exception as pe:
|
||||||
LOGGER.error(f"Unable to set presence: '{pe}'")
|
LOGGER.error(f"Unable to set presence: '{pe}'")
|
||||||
|
|||||||
@@ -4,52 +4,52 @@ from logging.handlers import RotatingFileHandler
|
|||||||
def create_logger(name, level=logging.DEBUG, max_bytes=10485760, backup_count=2):
|
def create_logger(name, level=logging.DEBUG, max_bytes=10485760, backup_count=2):
|
||||||
"""
|
"""
|
||||||
Creates a logger with a console and rotating file handlers for both debug and info log levels.
|
Creates a logger with a console and rotating file handlers for both debug and info log levels.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name for the logger.
|
name (str): The name for the logger.
|
||||||
level (int): The logging level for the logger. Defaults to logging.DEBUG.
|
level (int): The logging level for the logger. Defaults to logging.DEBUG.
|
||||||
max_bytes (int): Maximum size of the log file in bytes before it gets rotated. Defaults to 10 MB.
|
max_bytes (int): Maximum size of the log file in bytes before it gets rotated. Defaults to 10 MB.
|
||||||
backup_count (int): Number of backup files to keep. Defaults to 2.
|
backup_count (int): Number of backup files to keep. Defaults to 2.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
logging.Logger: Configured logger.
|
logging.Logger: Configured logger.
|
||||||
"""
|
"""
|
||||||
# Set the log file paths
|
# Set the log file paths
|
||||||
debug_log_file = "./client.debug.log"
|
debug_log_file = "./client.debug.log"
|
||||||
info_log_file = "./client.log"
|
info_log_file = "./client.log"
|
||||||
|
|
||||||
# Create a logger
|
# Create a logger
|
||||||
logger = logging.getLogger(name)
|
logger = logging.getLogger(name)
|
||||||
logger.setLevel(level)
|
logger.setLevel(level)
|
||||||
|
|
||||||
# Check if the logger already has handlers to avoid duplicate logs
|
# Check if the logger already has handlers to avoid duplicate logs
|
||||||
if not logger.hasHandlers():
|
if not logger.hasHandlers():
|
||||||
# Create console handler
|
# Create console handler
|
||||||
console_handler = logging.StreamHandler()
|
console_handler = logging.StreamHandler()
|
||||||
console_handler.setLevel(level)
|
console_handler.setLevel(level)
|
||||||
|
|
||||||
# Create rotating file handler for debug level
|
# Create rotating file handler for debug level
|
||||||
debug_file_handler = RotatingFileHandler(debug_log_file, maxBytes=max_bytes, backupCount=backup_count)
|
debug_file_handler = RotatingFileHandler(debug_log_file, maxBytes=max_bytes, backupCount=backup_count)
|
||||||
debug_file_handler.setLevel(logging.DEBUG)
|
debug_file_handler.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
# Create rotating file handler for info level
|
# Create rotating file handler for info level
|
||||||
info_file_handler = RotatingFileHandler(info_log_file, maxBytes=max_bytes, backupCount=backup_count)
|
info_file_handler = RotatingFileHandler(info_log_file, maxBytes=max_bytes, backupCount=backup_count)
|
||||||
info_file_handler.setLevel(logging.INFO)
|
info_file_handler.setLevel(logging.INFO)
|
||||||
|
|
||||||
# Create formatter and add it to the handlers
|
# Create formatter and add it to the handlers
|
||||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
console_handler.setFormatter(formatter)
|
console_handler.setFormatter(formatter)
|
||||||
debug_file_handler.setFormatter(formatter)
|
debug_file_handler.setFormatter(formatter)
|
||||||
info_file_handler.setFormatter(formatter)
|
info_file_handler.setFormatter(formatter)
|
||||||
|
|
||||||
# Add the handlers to the logger
|
# Add the handlers to the logger
|
||||||
logger.addHandler(console_handler)
|
logger.addHandler(console_handler)
|
||||||
logger.addHandler(debug_file_handler)
|
logger.addHandler(debug_file_handler)
|
||||||
logger.addHandler(info_file_handler)
|
logger.addHandler(info_file_handler)
|
||||||
|
|
||||||
return logger
|
return logger
|
||||||
|
|
||||||
# Example usage:
|
# Example usage:
|
||||||
# logger = create_logger('my_logger')
|
# logger = create_logger('my_logger')
|
||||||
# logger.debug('This is a debug message')
|
# logger.debug('This is a debug message')
|
||||||
# logger.info('This is an info message')
|
# logger.info('This is an info message')
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
import asyncio
|
from fastapi import FastAPI
|
||||||
import discord
|
|
||||||
from discord.ext import commands
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import Optional, Dict
|
|
||||||
import routers.op25_controller as op25_controller
|
import routers.op25_controller as op25_controller
|
||||||
import routers.pulse as pulse
|
import routers.pulse as pulse
|
||||||
import routers.bot as bot
|
import routers.bot as bot
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
import asyncio
|
|
||||||
import discord
|
|
||||||
from discord.ext import commands
|
|
||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import Optional, Dict
|
|
||||||
from models import BotConfig, VoiceChannelRequest
|
from models import BotConfig, VoiceChannelRequest
|
||||||
from internal.bot_manager import DiscordBotManager
|
from internal.bot_manager import DiscordBotManager
|
||||||
from internal.logger import create_logger
|
from internal.logger import create_logger
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
from fastapi import HTTPException, APIRouter
|
from fastapi import HTTPException, APIRouter
|
||||||
from pydantic import BaseModel
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import json
|
import json
|
||||||
import csv
|
import csv
|
||||||
from models import *
|
from models import ConfigGenerator, DecodeMode, ChannelConfig, DeviceConfig, TrunkingConfig, TrunkingChannelConfig, AudioConfig, TerminalConfig, TalkgroupTag
|
||||||
from internal.logger import create_logger
|
from internal.logger import create_logger
|
||||||
|
from typing import List
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
LOGGER = create_logger(__name__)
|
LOGGER = create_logger(__name__)
|
||||||
|
|||||||
Reference in New Issue
Block a user