Intermediate commits (oldest → newest):
- Streaming hls
- Fx bug
- Fxs
- Small fixes
- Revert fix
- Small improvements
- Fine tuning
- Fine tune
- Add microphone
- Fixing memory of Conjurer
- Local output
- Fix
- Fx
- Fine tuning
- Adding script logging current tracks in queue
This commit is contained in:
2025-10-30 16:59:02 +01:00
parent 95db8302e8
commit a63368adb5
7 changed files with 117 additions and 40 deletions
+18 -11
View File
@@ -1021,26 +1021,33 @@ async def handle_response(
logger.info(result)
temp = {"role": "assistant", "content": result}
history.append(temp)
if request_type:
with open(MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING) as file:
if request_type == "MUSIC":
with open(MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING) as file_music_memory:
# First we load existing data into a dict.
file_data = json.load(file)
file_data = json.load(file_music_memory)
# Join new_data with file_data inside emp_details
file_data.append(temp)
# Sets file's current position at offset.
file.seek(0)
file_music_memory.seek(0)
# convert back to json.
json.dump(file_data, file, indent=4)
json.dump(file_data, file_music_memory, indent=4)
elif request_type == "RANDOM":
with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file_memory:
# First we load existing data into a dict.
file_data = json.load(file_memory)
# Join new_data with file_data inside emp_details
file_data.append(temp)
file_memory.seek(0)
# convert back to json.
json.dump(file_data, file_memory, indent=4)
else:
with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file:
with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file_memory:
# First we load existing data into a dict.
file_data = json.load(file)
file_data = json.load(file_memory)
# Join new_data with file_data inside emp_details
file_data.append(temp)
# Sets file's current position at offset.
file.seek(0)
file_memory.seek(0)
# convert back to json.
json.dump(file_data, file, indent=4)
json.dump(file_data, file_memory, indent=4)
return result, MESSAGE_TABLE
+4 -4
View File
@@ -14,8 +14,7 @@ from logging import handlers
from pathlib import Path
from platform import uname
from sys import platform
from flask import Flask, jsonify, redirect, request, send_from_directory
from flask import Flask, jsonify, redirect, request, send_from_directory, render_template
from waitress import serve
HOST_ADDRESS = "192.168.1.15"
@@ -246,8 +245,9 @@ def stream_music():
:return: A JSON response containing a key "music_file_list" with the value of the variable `music_file_list`.
"""
return send_from_directory("/tmp/hls", "stream.m3u8")
#return send_from_directory("/tmp/hls", "stream.m3u8")
return render_template("/home/pi/Conjurer/stream.html")
@app.route("/<string:file_name>")
def stream(file_name):
@@ -260,10 +260,10 @@ def stream(file_name):
Returns:
Response: The response containing the streamed file.
"""
# trunk-ignore(bandit/B108)
video_dir = "/tmp/hls"
return send_from_directory(video_dir, file_name)
@app.route("/stream_mp3", methods=["GET"])
def stream_music_mp3():
"""
+26
View File
@@ -0,0 +1,26 @@
# This Python file uses the following encoding: utf-8
"""This module contains utility scripts used by musi radiostation Conjurer"""
import time
import re
NAME = "/home/pi/Conjurer/persistence.log"
def print_top():
"""
Prints the top 65 lines from a file specified by the NAME variable.
"""
while True:
line = ""
buffer = ""
with open(NAME, "r", encoding="utf-8") as f:
for _ in range (45):
line = f.readline()
if re.match(".*mp3", line):
buffer += line
print("=====================================")
print(buffer)
print("=====================================")
time.sleep(180)
if __name__ == "__main__":
print_top()
+25 -24
View File
@@ -9,12 +9,13 @@ let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentia
enable_replaygain_metadata()
# Set up a playlog for tracking played tracks
l = playlog(duration = 14400.0, persistency="/home/pi/Conjurer/persistence.log")
l = playlog(duration = 72000.0, persistency="/home/pi/Conjurer/persistence.log")
# Function to check if a track can be played based on its metadata
def check(r)
m = request.metadata(r)
if l.last(m) < 3600. then
if l.last(m) < 36000. then
log.info("Rejecting #{m['filename']} (played #{l.last(m)}s ago).")
false
else
@@ -40,20 +41,19 @@ def queue_processing()
file.remove("/home/pi/Conjurer/request.playlist")
f = file.open("/home/pi/Conjurer/request.playlist", create=true)
f.close()
log.info("done")
else
log.info("no requests")
end
end
# Randomly select a playlist with weights
s4 = random(id="randomizer", weights=[1, 3, 2], [s1, s2, s3])
s4 = random(id="randomizer", weights=[1, 3, 5], [s1, s2, s3])
# Load jingles playlist
jingles = (playlist(reload_mode="watch", "/home/pi/Conjurer/jingles.playlist"))
# Create the main stream with random playlist and jingles
s = rotate(id="randomizer", weights=[20, 1], [s4, jingles])
s = rotate(id="randomizer", weights=[10, 1], [s4, jingles])
s = crossfade(fade_out=2., fade_in=2., duration=4., fallback(id="switcher", track_sensitive=false, [requests_queue, s]))
# Set up an interactive harbor for controlling the stream
interactive.harbor(port = 9999)
@@ -66,12 +66,21 @@ s = add([s, b])
# Set up interactive control for main volume
a = interactive.float("main_volume", min=0., max=20., 1.)
s = compress.multiband.interactive(bands=3, s)
s = compress.multiband.interactive(bands=7, s)
# Apply audio processing effects
s = nrj(normalize(s))
s = amplify(a, s)
mic = buffer(input.pulseaudio()) # Microphone
mic = gate(threshold=-30., range=-80., mic)
mic = blank.strip(max_blank=2., min_noise=.1, threshold=-20., mic)
s = add([s, mic])
#w = interactive.float("wetness", min=0., max=1., 1.)
#s = dry_wet(w,s,s2)
# Skip blank sections in the stream
s = blank.skip(max_blank=2., s)
@@ -79,7 +88,7 @@ s = blank.skip(max_blank=2., s)
log_to_stdout = true
log_to_file = true
logpath = "/home/pi/Conjurer/radio_log.log"
loglevel = 4
loglevel = 3
set("log.stdout", log_to_stdout)
set("log.level", loglevel)
@@ -89,10 +98,9 @@ set("log.file.path", logpath)
# Set up emergency fallback track
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
# Create a fallback stream with the main stream and emergency track
cross_s = crossfade(fade_out=3., fade_in=3., duration=5., fallback(id="switcher", track_sensitive=false, [requests_queue, s]))
radio = fallback(id="switcher2", track_sensitive=false, [cross_s, emergency])
radio = fallback(id="switcher2", track_sensitive=false, [s, emergency])
# Set up an interactive control for skipping tracks
p = interactive.bool("Skip track", false)
# Function to process the request queue and skip the current track if requested
def check_skip()
@@ -106,26 +114,19 @@ end
# Run the queue processing function every 60 seconds
thread.run(every=60., queue_processing)
# Set up an interactive control for skipping tracks
p = interactive.bool("r1", false)
# Run the check_skip function every 5 seconds
thread.run(every=5., check_skip)
thread.run(every=15., check_skip)
# Handle metadata events
handle_metadata = fun (m) -> begin
log.info(m["title"])
log.info(m["artist"])
log.info(m["filename"])
end
radio.on_metadata(handle_metadata)
# Enable persistent script parameters
interactive.persistent("script.params")
# Configure output formats and destinations
output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
output.icecast(%mp3, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
output.pulseaudio(radio)
#output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
# Uncomment the following lines to enable additional output formats
# output.icecast(%opus, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="opus-stream", radio)
# output.icecast(%ogg, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="ogg-stream", radio)
+9
View File
@@ -0,0 +1,9 @@
<html>
<head>
<title>HTTP Live Streaming Example</title>
</head>
<body>
<video src="/tmp/hls/stream.m3u8" height="300" width="400">
</video>
</body>
</html>
+2 -1
View File
@@ -12,4 +12,5 @@ spotipy
tiktoken
PyNaCl
flask
waitress
waitress
clickupython
+33
View File
@@ -0,0 +1,33 @@
import json
MEMORY_FIVE_SIARA = "/home/pi/Conjurer/pamiec.json"
ENCODING = "utf-8"
messages = [
{"role": "user", "content" : "Hammer: All systems operational"},
{"role": "assistant", "content": "Aye, Szefie! Wszystkie systemy działają sprawnie. Gotów do dalszej służby! Co podać?"},
{"role": "user", "content" : "Hammer: Podaj coś na orzeźwienie i przebudzenie. COś co rozgrzeje moje stare kości po ciężkiej pracy!"},
{"role": "assistant", "content": "Z przyjemnością Szefie! Dla Ciebie przygotuję Midzynarodówkę Interstelarną Wolf's Dragoon - wysoce energetyczny koktajl rozgrzewający i pobudzający jednocześnie."+
"Do przygotowania potrzebuję:"+
"\n"+
"60 ml mocnego rumu z Wolfa (lub innego, jeśli wolisz)"+
"30 ml soku z cytryny"+
"35 ml domowego syropu z mięty"+
"15 ml świeżo zmielonej kawy"+
"\n"+
"Mieszam wszystko w shakerze z lodem, a potem przelewam przez sitko do kieliszka koktajlowego. W górę serwuję z bigoskiem z miętą i zestem z cytryny. Rozgrzewa, orzeźwia i daje kopa na resztę nocy."+
"\n"+
"Co powiesz Szefie, podać Ci taki?"},
{"role": "user", "content" : "Hammer: Brzmi jak coś co zrobi robotę! Skal!"},
]
for temp in messages:
with open(MEMORY_FIVE_SIARA, "r+", encoding=ENCODING) as file_memory:
# First we load existing data into a dict.
file_data = json.load(file_memory)
# Join new_data with file_data inside emp_details
file_data.append(temp)
file_memory.seek(0)
# convert back to json.
json.dump(file_data, file_memory, indent=4)