Compare commits

...

21 Commits

Author SHA1 Message Date
gitea 3684003150 Fine tune 2024-05-18 12:50:49 +02:00
gitea f3b03827e2 Adding script logging current tracks in queue 2024-05-18 12:45:18 +02:00
gitea 848668b8ed Fine tuning 2024-04-29 21:15:15 +02:00
gitea f1cc24cc06 Fx 2024-04-29 21:12:41 +02:00
gitea 1cbd44c333 Fix 2024-04-29 21:07:30 +02:00
gitea 9ba3f1d3ed Local output 2024-04-29 17:59:27 +01:00
gitea 032cc41c9b Fixing memory of Conjurer 2024-04-28 12:27:29 +02:00
gitea 217533c91f Add microphone 2024-04-25 22:42:52 +02:00
gitea 80f4254ebe Fine tune 2024-04-25 21:54:04 +02:00
gitea 5967aefda7 Fine tuning 2024-04-25 21:53:09 +02:00
gitea 3b232ac3d7 Small improvements 2024-04-25 14:29:30 +02:00
gitea 7c0de660fd Revert fix 2024-04-25 13:22:26 +01:00
gitea 7de1ad43fd Small fixes 2024-04-25 14:06:23 +02:00
gitea fcbda81213 Fxs 2024-04-24 20:40:58 +02:00
gitea 1e00c1fe33 Fx bug 2024-04-24 20:39:31 +02:00
gitea 5e810d23ab Streaming hls 2024-04-24 20:31:35 +02:00
gitea 439c5c753c Comments in radio script 2024-04-24 20:15:39 +02:00
gitea cc11d3f75e This language is officially insane 2024-04-24 20:06:29 +02:00
gitea a35d7da6e3 testing skip 2024-04-24 20:02:37 +02:00
gitea 2c50318f1c Skipping tracks 2024-04-24 19:58:23 +02:00
gitea addc534c36 JINGLES! 2024-04-24 18:57:14 +02:00
7 changed files with 228 additions and 131 deletions
+18 -11
View File
@@ -1021,26 +1021,33 @@ async def handle_response(
logger.info(result) logger.info(result)
temp = {"role": "assistant", "content": result} temp = {"role": "assistant", "content": result}
history.append(temp) history.append(temp)
if request_type: if request_type == "MUSIC":
with open(MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING) as file: with open(MEMORY_FIVE_MUZYKA, "r+", encoding=ENCODING) as file_music_memory:
# First we load existing data into a dict. # 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 # Join new_data with file_data inside emp_details
file_data.append(temp) file_data.append(temp)
# Sets file's current position at offset. file_music_memory.seek(0)
file.seek(0)
# convert back to json. # 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: 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. # 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 # Join new_data with file_data inside emp_details
file_data.append(temp) file_data.append(temp)
# Sets file's current position at offset. file_memory.seek(0)
file.seek(0)
# convert back to json. # convert back to json.
json.dump(file_data, file, indent=4) json.dump(file_data, file_memory, indent=4)
return result, MESSAGE_TABLE return result, MESSAGE_TABLE
+4 -4
View File
@@ -14,8 +14,7 @@ from logging import handlers
from pathlib import Path from pathlib import Path
from platform import uname from platform import uname
from sys import platform from sys import platform
from flask import Flask, jsonify, redirect, request, send_from_directory, render_template
from flask import Flask, jsonify, redirect, request, send_from_directory
from waitress import serve from waitress import serve
HOST_ADDRESS = "192.168.1.15" 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: 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>") @app.route("/<string:file_name>")
def stream(file_name): def stream(file_name):
@@ -260,10 +260,10 @@ def stream(file_name):
Returns: Returns:
Response: The response containing the streamed file. Response: The response containing the streamed file.
""" """
# trunk-ignore(bandit/B108)
video_dir = "/tmp/hls" video_dir = "/tmp/hls"
return send_from_directory(video_dir, file_name) return send_from_directory(video_dir, file_name)
@app.route("/stream_mp3", methods=["GET"]) @app.route("/stream_mp3", methods=["GET"])
def stream_music_mp3(): 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()
+97 -76
View File
@@ -5,28 +5,35 @@
# Load icecast credentials from a JSON file # Load icecast credentials from a JSON file
let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentials.json") let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentials.json")
# Enable replaygain metadata processing # Enable replaygain metadata processing
enable_replaygain_metadata() enable_replaygain_metadata()
l = playlog(duration = 14400.0, persistency="/home/pi/Conjurer/persistence.log")
def check(r) # Set up a playlog for tracking played tracks
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) 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).") log.info("Rejecting #{m['filename']} (played #{l.last(m)}s ago).")
false false
else else
l.add(m) l.add(m)
true true
end end
end end
# Define playlists to be used in the stream
s1 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/all_playlist.playlist"))
s2 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/priority_queue.playlist"))
s3 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/hit.playlist"))
# Create a request queue for user-generated requests
requests_queue = request.queue()
# Define playlists to be used in the stream # Function to process the request queue and add new requests
s1 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/all_playlist.playlist")) def queue_processing()
s2 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/priority_queue.playlist"))
s3 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/hit.playlist"))
requests_queue = request.queue()
def queue_processing()
f1=file.read("/home/pi/Conjurer/request.playlist") f1=file.read("/home/pi/Conjurer/request.playlist")
text = f1() text = f1()
if text != "" then if text != "" then
@@ -34,79 +41,93 @@ let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentia
file.remove("/home/pi/Conjurer/request.playlist") file.remove("/home/pi/Conjurer/request.playlist")
f = file.open("/home/pi/Conjurer/request.playlist", create=true) f = file.open("/home/pi/Conjurer/request.playlist", create=true)
f.close() f.close()
log.info("done")
else
log.info("no requests")
end end
end
# Randomly select a playlist with weights
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=[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)
# Set up interactive controls for bass boost
f = interactive.float("f", description="Frequency", min=0., max=1000., unit="Hz", 200.)
g = interactive.float("g", description="Gain", min=0., max=20., unit="dB", 8.)
b = bass_boost(frequency=f, gain=g, s)
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=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)
# Configure logging settings
log_to_stdout = true
log_to_file = true
logpath = "/home/pi/Conjurer/radio_log.log"
loglevel = 3
set("log.stdout", log_to_stdout)
set("log.level", loglevel)
# Enable logging to file
set("log.file", log_to_file)
set("log.file.path", logpath)
# Set up emergency fallback track
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
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()
if p() then
log.info("Skipping current track.")
radio.skip()
p.set(false)
end end
end
# Randomly select a playlist with weights # Run the queue processing function every 60 seconds
s = random(id="randomizer", weights=[1, 3, 2], [s1, s2, s3]) thread.run(every=60., queue_processing)
#s = delay(duration=5., s)
#radio = add([delay(1800., jingles), music])
#radio = fallback([delay(1800., jingles), music])
#p = predicate.signal()
#radio = switch([(p, jingles), ({true}, music)])
#thread.run(every=1200., {p.signal()})
# def cmd(_)
# p.signal()
# "Jingle inserted!"
# end
# server.register("insert_jingle", cmd)
# Set up an interactive harbor for controlling the stream
interactive.harbor(port = 9999)
# Set up interactive controls for bass boost
f = interactive.float("f", description="Frequency", min=0., max=1000., unit="Hz", 200.)
g = interactive.float("g", description="Gain", min=0., max=20., unit="dB", 8.)
b = bass_boost(frequency=f, gain=g, s)
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)
# Apply audio processing effects # Run the check_skip function every 5 seconds
s = nrj(normalize(s)) thread.run(every=15., check_skip)
s = amplify(a, s)
# Skip blank sections in the stream
s = blank.skip(max_blank=2., s)
# Configure logging settings # Enable persistent script parameters
log_to_stdout = true interactive.persistent("script.params")
log_to_file = true
logpath = "/home/pi/Conjurer/radio_log.log"
loglevel = 4
set("log.stdout", log_to_stdout)
set("log.level", loglevel)
# Enable logging to file # Configure output formats and destinations
set("log.file", log_to_file)
set("log.file.path", logpath)
# Set up emergency fallback track output.icecast(%mp3, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3") output.pulseaudio(radio)
#output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
# Create a fallback stream with the main stream and emergency track # Uncomment the following lines to enable additional output formats
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])
thread.run(every=60., queue_processing)
# 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.icecast(%opus, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="opus-stream", radio) # 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) # output.icecast(%ogg, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="ogg-stream", radio)
# output.icecast(%aac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="aac-stream", radio) # output.icecast(%aac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="aac-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>
+1
View File
@@ -13,3 +13,4 @@ tiktoken
PyNaCl PyNaCl
flask 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)