Compare commits

...

16 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
7 changed files with 117 additions and 40 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()
+25 -24
View File
@@ -9,12 +9,13 @@ let json.parse credentials = file.contents("/home/pi/Conjurer/icecast_credentia
enable_replaygain_metadata() enable_replaygain_metadata()
# Set up a playlog for tracking played tracks # 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 # Function to check if a track can be played based on its metadata
def check(r) 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
@@ -40,20 +41,19 @@ def queue_processing()
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 end
# Randomly select a playlist with weights # 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 # Load jingles playlist
jingles = (playlist(reload_mode="watch", "/home/pi/Conjurer/jingles.playlist")) jingles = (playlist(reload_mode="watch", "/home/pi/Conjurer/jingles.playlist"))
# Create the main stream with random playlist and jingles # 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 # Set up an interactive harbor for controlling the stream
interactive.harbor(port = 9999) interactive.harbor(port = 9999)
@@ -66,12 +66,21 @@ s = add([s, b])
# Set up interactive control for main volume # Set up interactive control for main volume
a = interactive.float("main_volume", min=0., max=20., 1.) 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 # Apply audio processing effects
s = nrj(normalize(s)) s = nrj(normalize(s))
s = amplify(a, 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 # Skip blank sections in the stream
s = blank.skip(max_blank=2., s) s = blank.skip(max_blank=2., s)
@@ -79,7 +88,7 @@ s = blank.skip(max_blank=2., s)
log_to_stdout = true log_to_stdout = true
log_to_file = true log_to_file = true
logpath = "/home/pi/Conjurer/radio_log.log" logpath = "/home/pi/Conjurer/radio_log.log"
loglevel = 4 loglevel = 3
set("log.stdout", log_to_stdout) set("log.stdout", log_to_stdout)
set("log.level", loglevel) set("log.level", loglevel)
@@ -89,10 +98,9 @@ set("log.file.path", logpath)
# Set up emergency fallback track # Set up emergency fallback track
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3") emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3")
radio = fallback(id="switcher2", track_sensitive=false, [s, emergency])
# Create a fallback stream with the main stream and emergency track # Set up an interactive control for skipping tracks
cross_s = crossfade(fade_out=3., fade_in=3., duration=5., fallback(id="switcher", track_sensitive=false, [requests_queue, s])) p = interactive.bool("Skip track", false)
radio = fallback(id="switcher2", track_sensitive=false, [cross_s, emergency])
# Function to process the request queue and skip the current track if requested # Function to process the request queue and skip the current track if requested
def check_skip() def check_skip()
@@ -106,26 +114,19 @@ end
# Run the queue processing function every 60 seconds # Run the queue processing function every 60 seconds
thread.run(every=60., queue_processing) 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 # 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 # Enable persistent script parameters
interactive.persistent("script.params") interactive.persistent("script.params")
# Configure output formats and destinations # 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(%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 # 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(%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)
+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)