Compare commits

..

31 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
gitea 430b4de995 Search headless (#8)
* Fix

* Final fix to headless

* test

* Fix

* Ready for deployment
2024-04-24 17:31:52 +02:00
gitea 9d00e40b41 Starting work on librarian headless mode 2024-04-24 12:00:56 +02:00
gitea 7d29c1d397 Fix 2024-04-23 23:58:55 +02:00
gitea ce3ad9f8f0 Crossfadeing ctnd 2024-04-23 23:40:44 +02:00
gitea abef18f4ad Fix crossfade 2024-04-23 23:36:45 +02:00
gitea 5beb1c6fdd Optimization bug fix #1 2024-04-23 21:37:44 +02:00
gitea ff69091495 Fine tuning 2024-04-23 18:23:12 +02:00
gitea 69d3c8849c test requests 2024-04-23 16:10:14 +02:00
gitea b2aab28460 Even more logging in spotify download
Fix #1

Test fix 2

Fixing part 2

Fixing ctnd

Final fix

Fixing spotipy get bug

Same plusy kurwa

Fixing fucking spotipy

test

More logging
2024-04-23 15:09:51 +02:00
gitea 082b25c89c Music tunneling (#7)
* New requirement

* SMall fixes for tunnel

* First step towards cogization

* Tmp chng

* Testing of new functions in conjurer_musician.py and radio_conjurer.liq

* Fixes!

* Fix fix

* Mostly working ?

* Requests

* Fixes

* Fix

* Radio requests

* Radio hardkor

* Fix

* Fixes

* Change log to print

* Clearing fetch failed

* Small fix

* sx

* Fix fix fix

* test

* el fixo stupido

* test

* Maybe fix ?

* FIX!

* Fix fix fix

* FIx of volume
2024-04-23 12:59:33 +02:00
13 changed files with 350 additions and 217 deletions
+33 -20
View File
@@ -693,17 +693,19 @@ async def check_data_q():
ctx = fresh_data.ctx ctx = fresh_data.ctx
message += f' Dzielny poszukiwaczu @{searcher} w odpowiedzi na twoje zapytanie {query} nr {fresh_data.uuid}' message += f' Dzielny poszukiwaczu @{searcher} w odpowiedzi na twoje zapytanie {query} nr {fresh_data.uuid}'
else: else:
ctx = client.get_channel(1062047367337095268) ctx = client.get_channel(1062047571557744721)
message += f' Mam wynik dla zapytania {fresh_data.uuid} ale że Hammer coś grzebał nie pamiętam kto to chciał i co chciał' message += f' Mam wynik dla zapytania {fresh_data.uuid} ale że Hammer coś grzebał nie pamiętam kto to chciał i co chciał'
message += 'nasza biblioteka służy Ci odpowiedzią. Przy dźwięku fanfar winda się otwiera a w środku ' message += 'nasza biblioteka służy Ci odpowiedzią. Przy dźwięku fanfar winda się otwiera a w środku '
if len(entries)<1: if len(entries)<1:
message += "niestety nie ma nic" message += "niestety nie ma nic"
await ctx.send(message)
elif len(entries)>=1 and len(entries)<5: elif len(entries)>=1 and len(entries)<5:
message += " znajduje się coś:\n" message += " znajduje się coś:\n"
for item in entries: for item in entries:
message+=item message+=item
await ctx.send(message)
else: else:
message+= " znajduje się cholernie dużo:\n" message+= " znajduje się cholernie dużo:\n"
for item in entries: for item in entries:
@@ -712,7 +714,6 @@ async def check_data_q():
await ctx.send(message) await ctx.send(message)
message = "" message = ""
await ctx.send(message)
#Kept for sentimental reasons #Kept for sentimental reasons
#await ctx.send(f"O. A tak będzie wyglądało coś ciekawego w przyszłości: {data}") #await ctx.send(f"O. A tak będzie wyglądało coś ciekawego w przyszłości: {data}")
except Empty: except Empty:
@@ -1020,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
@@ -1064,11 +1072,15 @@ async def get_file(ctx, source, link):
if source == "Spotify": if source == "Spotify":
dir_path = None dir_path = None
item_type, item_id = spotify.parse_spotify_url(link) item_type, item_id = spotify.parse_spotify_url(link)
if item_id: if item_type in ["album", "track", "playlist"] and item_id:
coro = asyncio.to_thread(spotify.fetch_tracks, spotify_ctrl, item_type, link) logger.info(item_type)
file_list = await coro logger.info(item_id)
coro = asyncio.to_thread(spotify.get_item_name, spotify_ctrl, item_type, item_id) logger.info("Spotify link provided")
directory_name = await coro file_list = await asyncio.to_thread(spotify.fetch_tracks, spotify_ctrl, item_type, link)
logger.info(file_list)
directory_name = await asyncio.to_thread(spotify.get_item_name, spotify_ctrl, item_type, item_id)
logger.info(directory_name)
logger.info("Spotify scrape done")
url_data = {"urls": []} url_data = {"urls": []}
url_dict = {} url_dict = {}
url_dict["save_path"] = Path( url_dict["save_path"] = Path(
@@ -1078,6 +1090,7 @@ async def get_file(ctx, source, link):
url_dict["songs"] = file_list url_dict["songs"] = file_list
url_data["urls"].append(url_dict.copy()) url_data["urls"].append(url_dict.copy())
file_name_f = youtube_download.default_filename file_name_f = youtube_download.default_filename
logger.info("YT-DL")
coro = asyncio.to_thread( coro = asyncio.to_thread(
youtube_download.download_songs, youtube_download.download_songs,
songs=url_data, songs=url_data,
@@ -1093,6 +1106,7 @@ async def get_file(ctx, source, link):
proxy="", proxy="",
) )
_ = await coro _ = await coro
logger.info("YT-DL done")
dir_path = (url_dict["save_path"].resolve()).as_posix() dir_path = (url_dict["save_path"].resolve()).as_posix()
if platform == "win32": if platform == "win32":
dir_path = dir_path.replace("/", "\\") dir_path = dir_path.replace("/", "\\")
@@ -1829,9 +1843,8 @@ async def wyczysc_ulubione(ctx):
""" """
async with ctx.typing(): async with ctx.typing():
coroutine = asyncio.to_thread( coroutine = asyncio.to_thread(
requests.post, requests.get,
f"{FILE_SERVICE_ADDRESS}{CLEAR_PRIO}", f"{FILE_SERVICE_ADDRESS}{CLEAR_PRIO}",
json={},
timeout=360, timeout=360,
) )
_ = await coroutine _ = await coroutine
+8 -7
View File
@@ -102,18 +102,19 @@ def scan_incoming(_logger):
try: try:
answer = incoming_q.get(block=False) answer = incoming_q.get(block=False)
_logger.info("DATA FOUND") _logger.info("DATA FOUND")
record_stored = False
for record in awaiting_q: for record in awaiting_q:
if record.uuid in answer.keys(): if record.uuid in answer.keys():
record_stored = True
record.stop = True
record.entries = answer[record.uuid]
IN_COMM_Q.put(record)
if not record_stored:
for key in answer.keys():
record = QueryControl("Orphaned", key, "Orphan", _logger, None)
record.stop = True record.stop = True
record.entries = answer[record.uuid] record.entries = answer[record.uuid]
IN_COMM_Q.put(record) IN_COMM_Q.put(record)
else:
for key in answer.keys():
record = QueryControl("Orphaned", key, "Orphan", _logger, None)
record.stop = True
record.entries = answer[record.uuid]
record.uuid = "000000"
IN_COMM_Q.put(record)
except Empty: except Empty:
time.sleep(1) time.sleep(1)
@@ -1,3 +1,3 @@
habanero habanero
waitress waitress
flask flask[async]
+23 -18
View File
@@ -35,7 +35,7 @@ DATABASE_PATH = r"C:\\Database\\chunks\\"
ENCODING = "utf-8" ENCODING = "utf-8"
CHUNK = "_chunk.txt" CHUNK = "_chunk.txt"
_sentinel = object() _sentinel = object()
WORK_Q_SIZE = 15500000 WORK_Q_SIZE = 35500000
def producer(out_q, control_q, filename, _logger): def producer(out_q, control_q, filename, _logger):
@@ -68,7 +68,7 @@ def producer(out_q, control_q, filename, _logger):
# IMPORTANT!!! ONLY ONE CONSUMER THREAD AS WE ARE NOT PUTTING SENTINELS BACK # IMPORTANT!!! ONLY ONE CONSUMER THREAD AS WE ARE NOT PUTTING SENTINELS BACK
def consumer(in_q, control_q, doi, live_results, result_list, control_dict, _logger): def consumer(in_q, control_q, doi, live_results, result_list, control_dict, no, _logger):
""" """
Consumes items from an input queue and checks if DOI exists in the live results list. Consumes items from an input queue and checks if DOI exists in the live results list.
@@ -79,29 +79,34 @@ def consumer(in_q, control_q, doi, live_results, result_list, control_dict, _log
live_results (list): List to store the search results. live_results (list): List to store the search results.
_logger: Logger object for logging. _logger: Logger object for logging.
""" """
_logger.info("Consumer thread started:%s", no)
for item in doi: for item in doi:
result_list.append({"DOI": item[0], "exists": False, "data": item[1]}) result_list.append({"DOI": item[0], "exists": False, "data": item[1]})
while True: while True:
done_check = True done_check = True
data = in_q.get() try:
if data is _sentinel: data = in_q.get(block=False)
_logger.info("Worker finished") if data is _sentinel:
control_dict["sentinels"] += 1 _logger.info("Worker finished")
else: control_dict["sentinels"] += 1
for item in result_list: else:
if item["DOI"] in data and not item["exists"]: for item in result_list:
_logger.info(data) if item["DOI"] in data and not item["exists"]:
_logger.info("HIT") _logger.info(data)
item["exists"] = True _logger.info("HIT")
live_results.append(item) item["exists"] = True
done_check = done_check and item["exists"] live_results.append(item)
if done_check: done_check = done_check and item["exists"]
control_q.put(_sentinel) if done_check:
control_q.put(_sentinel)
except Empty:
pass
if control_dict["sentinels"] >= MAXTHREADS: if control_dict["sentinels"] >= MAXTHREADS:
_logger.info("All workers finished") _logger.info("All workers finished")
break break
def search_for_doi(doi, live_results, _logger): def search_for_doi(doi, live_results, _logger):
""" """
Search for DOI in live_results using _logger for logging. Search for DOI in live_results using _logger for logging.
@@ -116,9 +121,9 @@ def search_for_doi(doi, live_results, _logger):
threads = [] threads = []
work_q = Queue(maxsize=WORK_Q_SIZE) work_q = Queue(maxsize=WORK_Q_SIZE)
control_q = Queue() control_q = Queue()
for _ in range (1, len(doi)//1000+1): for i in range (0, (len(doi)//1000)+2):
t_cons = Thread( t_cons = Thread(
target=consumer, args=(work_q, control_q, doi, live_results, result_list, control_dict, _logger) target=consumer, args=(work_q, control_q, doi, live_results, result_list, control_dict, i, _logger)
) )
_logger.info("Consumer thread created") _logger.info("Consumer thread created")
threads.append(t_cons) threads.append(t_cons)
+45
View File
@@ -0,0 +1,45 @@
import asyncio
import json
import logging
from json.decoder import JSONDecodeError
from logging import handlers
import requests
MAIN_BOT_ADDRESS = "http://192.168.1.191:5000"
SEND_RESULTS = "/conjurer"
async def send_results():
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
h1 = handlers.RotatingFileHandler(
filename="D:\\logs\\librarian.log",
encoding="utf-8",
mode="a",
maxBytes=6 * 1024 * 1024,
backupCount=6,
)
logger.addHandler(h1)
with open("s_results.json", "r+", encoding="utf-8") as s_file:
try:
database = json.load(s_file)
except JSONDecodeError:
pass
result = database["4bacbca0-ce3b-45c6-90a1-05c70b46b740"]
result = {"4bacbca0-ce3b-45c6-90a1-05c70b46b740":result}
coroutine = asyncio.to_thread(
requests.post,
f"{MAIN_BOT_ADDRESS}{SEND_RESULTS}",
json=result,
timeout=360,
)
logger.info("SENT")
result = await coroutine
logger.info(result.status_code)
logger.info("SEND CONFIRMED")
async def main():
await send_results()
if __name__ == "__main__":
asyncio.run(main())
+24 -55
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"
@@ -41,41 +40,6 @@ if platform in ("linux", "linux2"):
music_file_list = [] music_file_list = []
priority_list = [] priority_list = []
def create_playlist():
"""
Reads a JSON file containing a playlist and writes the playlist items to a text file.
The JSON file path is '/home/pi/Conjurer/playlist.json',
and the text file path is '/home/pi/Conjurer/all_playlist.playlist'.
Raises:
JSONDecodeError: If the JSON file cannot be decoded.
"""
with open("/home/pi/Conjurer/playlist.json", "r+", encoding="utf-8") as r_file:
with open(
"/home/pi/Conjurer/all_playlist.playlist", "w", encoding="utf-8"
) as w_file:
try:
playlist = json.load(r_file)
for item in playlist:
w_file.write(item)
w_file.write("\n")
except json.JSONDecodeError:
pass
with open("/home/pi/Conjurer/prio_playlist.json", "r+", encoding="utf-8") as r_file:
with open("/home/pi/Conjurer/hit.playlist", "w", encoding="utf-8") as w_file:
try:
playlist = json.load(r_file)
for item in playlist:
w_file.write(item)
w_file.write("\n")
except json.JSONDecodeError:
pass
def rescan(): def rescan():
""" """
The `rescan` function logs a message, scans for mp3 files in a specified folder, The `rescan` function logs a message, scans for mp3 files in a specified folder,
@@ -95,18 +59,22 @@ def rescan():
temp_music_file = temp_music_file.replace("/", "\\") temp_music_file = temp_music_file.replace("/", "\\")
priority_list.append(temp_music_file) priority_list.append(temp_music_file)
with open("/home/pi/Conjurer/playlist.json", "r+", encoding="utf-8") as s_file: with open(
database = music_file_list "/home/pi/Conjurer/all_playlist.playlist", "w", encoding="utf-8"
# self.app.logger.info("DUMPING DATA") ) as w_file:
s_file.truncate(0) try:
s_file.seek(0) for item in music_file_list:
json.dump(database, s_file) w_file.write(item)
with open("/home/pi/Conjurer/prio_playlist.json", "r+", encoding="utf-8") as s_file: w_file.write("\n")
# self.app.logger.info("DUMPING DATA") except json.JSONDecodeError:
s_file.truncate(0) pass
s_file.seek(0) with open("/home/pi/Conjurer/hit.playlist", "w", encoding="utf-8") as w_file:
json.dump(priority_list, s_file) try:
create_playlist() for item in priority_list:
w_file.write(item)
w_file.write("\n")
except json.JSONDecodeError:
pass
def thread_rescan(): def thread_rescan():
@@ -277,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):
@@ -291,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():
""" """
@@ -313,10 +282,10 @@ def clear_pr_pls():
:return: A JSON response indicating the success of the operation. :return: A JSON response indicating the success of the operation.
""" """
with open( app.logger.info("CLEARING PLAYLIST")
"/home/pi/Conjurer/priority_queue.playlist", "w", encoding="utf-8" with open('/home/pi/Conjurer/priority_queue.playlist', 'w', encoding='utf-8') as cleared_pl:
) as s_file: cleared_pl.write('')
s_file.truncate(0)
return_data = jsonify(isError=False, message="Success", statusCode=200, data=[]) return_data = jsonify(isError=False, message="Success", statusCode=200, data=[])
return return_data, 200 return return_data, 200
+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()
+137 -115
View File
@@ -5,135 +5,157 @@
# 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
m = request.metadata(r)
if l.last(m) < 3600. then l = playlog(duration = 72000.0, persistency="/home/pi/Conjurer/persistence.log")
log.info("Rejecting #{m['filename']} (played #{l.last(m)}s ago).")
false # Function to check if a track can be played based on its metadata
else def check(r)
l.add(m) m = request.metadata(r)
true if l.last(m) < 36000. then
end log.info("Rejecting #{m['filename']} (played #{l.last(m)}s ago).")
false
else
l.add(m)
true
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")) f1=file.read("/home/pi/Conjurer/request.playlist")
s3 = replaygain(playlist(reload_mode="watch", check_next=check, "/home/pi/Conjurer/hit.playlist")) text = f1()
requests_queue = request.queue() if text != "" then
def queue_processing() requests_queue.push.uri(text)
f1=file.read("/home/pi/Conjurer/request.playlist") file.remove("/home/pi/Conjurer/request.playlist")
text = f1() f = file.open("/home/pi/Conjurer/request.playlist", create=true)
if text != "" then f.close()
requests_queue.push.uri(text)
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 end
thread.run(every=60., queue_processing) end
# Randomly select a playlist with weights # Randomly select a playlist with weights
s = random(id="randomizer", weights=[1, 3, 2], [s1, s2, s3]) s4 = random(id="randomizer", weights=[1, 3, 5], [s1, s2, s3])
#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 # Load jingles playlist
interactive.harbor(port = 9999) jingles = (playlist(reload_mode="watch", "/home/pi/Conjurer/jingles.playlist"))
# 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 # Create the main stream with random playlist and jingles
s = nrj(normalize(s)) s = rotate(id="randomizer", weights=[10, 1], [s4, jingles])
s = crossfade(fade_out=3., fade_in=3., duration=5., s)
s = amplify(a, s)
# Skip blank sections in the stream s = crossfade(fade_out=2., fade_in=2., duration=4., fallback(id="switcher", track_sensitive=false, [requests_queue, s]))
s = blank.skip(max_blank=2., s)
# Configure logging settings # Set up an interactive harbor for controlling the stream
log_to_stdout = true interactive.harbor(port = 9999)
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 # Set up interactive controls for bass boost
set("log.file", log_to_file) f = interactive.float("f", description="Frequency", min=0., max=1000., unit="Hz", 200.)
set("log.file.path", logpath) 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 emergency fallback track # Set up interactive control for main volume
emergency = single("/home/pi/RetroPie/mp3/Youtube/Dr. Peacock - Trip to Ireland [GvrvQTUbUcA].mp3") a = interactive.float("main_volume", min=0., max=20., 1.)
s = compress.multiband.interactive(bands=7, s)
# Create a fallback stream with the main stream and emergency track # Apply audio processing effects
radio = fallback(id="switcher", track_sensitive=true, [requests_queue, s, emergency]) s = nrj(normalize(s))
s = amplify(a, s)
# Handle metadata events mic = buffer(input.pulseaudio()) # Microphone
handle_metadata = fun (m) -> begin mic = gate(threshold=-30., range=-80., mic)
log.info(m["title"]) mic = blank.strip(max_blank=2., min_noise=.1, threshold=-20., mic)
log.info(m["artist"])
log.info(m["filename"]) 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
radio.on_metadata(handle_metadata) end
# Enable persistent script parameters # Run the queue processing function every 60 seconds
interactive.persistent("script.params") thread.run(every=60., queue_processing)
# Configure output formats and destinations
output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio) # Run the check_skip function every 5 seconds
output.icecast(%mp3, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio) thread.run(every=15., check_skip)
# 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(%aac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="aac-stream", radio) # Enable persistent script parameters
# output.icecast(%flac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="flac-stream", radio) interactive.persistent("script.params")
# output.icecast(%vorbis, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="vorbis-stream", radio)
# output.icecast(%speex, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="speex-stream", radio) # Configure output formats and destinations
# output.icecast(%wav, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="wav-stream", radio)
# output.icecast(%pcm, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="pcm-stream", radio) output.icecast(%mp3, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="mp3-stream", radio)
# output.icecast(%raw, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="raw-stream", radio) output.pulseaudio(radio)
# output.icecast(%s16l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s16l-stream", radio) #output.file.hls("/tmp/hls", [("mp3-low", %mp3(bitrate=96)), ("mp3-hi", %mp3(bitrate=160))], radio)
# output.icecast(%s16b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s16b-stream", radio) # Uncomment the following lines to enable additional output formats
# output.icecast(%s24l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s24l-stream", radio) # output.icecast(%opus, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="opus-stream", radio)
# output.icecast(%s24b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s24b-stream", radio) # output.icecast(%ogg, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="ogg-stream", radio)
# output.icecast(%s32l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s32l-stream", radio) # output.icecast(%aac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="aac-stream", radio)
# output.icecast(%s32b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s32b-stream", radio) # output.icecast(%flac, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="flac-stream", radio)
# output.icecast(%s64l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s64l-stream", radio) # output.icecast(%vorbis, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="vorbis-stream", radio)
# output.icecast(%s64b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s64b-stream", radio) # output.icecast(%speex, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="speex-stream", radio)
# output.icecast(%s128l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s128l-stream", radio) # output.icecast(%wav, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="wav-stream", radio)
# output.icecast(%s128b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s128b-stream", radio) # output.icecast(%pcm, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="pcm-stream", radio)
# output.icecast(%s256l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s256l-stream", radio) # output.icecast(%raw, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="raw-stream", radio)
# output.icecast(%s256b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s256b-stream", radio) # output.icecast(%s16l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s16l-stream", radio)
# output.icecast(%s512l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s512l-stream", radio) # output.icecast(%s16b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s16b-stream", radio)
# output.icecast(%s512b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s512b-stream", radio) # output.icecast(%s24l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s24l-stream", radio)
# output.icecast(%s1024l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s1024l-stream", radio) # output.icecast(%s24b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s24b-stream", radio)
# output.icecast(%s1024b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s1024b-stream", radio) # output.icecast(%s32l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s32l-stream", radio)
# output.icecast(%s2048l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s2048l-stream", radio) # output.icecast(%s32b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s32b-stream", radio)
# output.icecast(%s2048b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s2048b-stream", radio) # output.icecast(%s64l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s64l-stream", radio)
# output.icecast(%s4096l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s4096l-stream", radio) # output.icecast(%s64b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s64b-stream", radio)
# output.icecast(%s4096b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s4096b-stream", radio) # output.icecast(%s128l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s128l-stream", radio)
# output.icecast(%s8192l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s8192l-stream", radio) # output.icecast(%s128b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s128b-stream", radio)
# output.icecast(%s8192b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s8192b-stream", radio) # output.icecast(%s256l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s256l-stream", radio)
# output.icecast(%s256b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s256b-stream", radio)
# output.icecast(%s512l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s512l-stream", radio)
# output.icecast(%s512b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s512b-stream", radio)
# output.icecast(%s1024l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s1024l-stream", radio)
# output.icecast(%s1024b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s1024b-stream", radio)
# output.icecast(%s2048l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s2048l-stream", radio)
# output.icecast(%s2048b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s2048b-stream", radio)
# output.icecast(%s4096l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s4096l-stream", radio)
# output.icecast(%s4096b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s4096b-stream", radio)
# output.icecast(%s8192l, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s8192l-stream", radio)
# output.icecast(%s8192b, host="retropie", port=8000, password=credentials.password, icy_metadata="true", mount="s8192b-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 tiktoken
PyNaCl PyNaCl
flask flask
waitress waitress
clickupython
+7
View File
@@ -204,6 +204,13 @@
false, false,
false false
], ],
"same plusy\\b": [
"Jak na cmentarzu Szefie. Jak na cmentarzu",
15.0,
0,
false,
false
],
"kld\\b": [ "kld\\b": [
"KLD? Mieli tam burdel większy niż u Hammera. Ale o ile Hammer sprzątnął już nawet całkiem nieźle - to tam śmieci wyniosły się same. Uczcijmy ich minutą śmiechu.", "KLD? Mieli tam burdel większy niż u Hammera. Ale o ile Hammer sprzątnął już nawet całkiem nieźle - to tam śmieci wyniosły się same. Uczcijmy ich minutą śmiechu.",
15.0, 15.0,
+2
View File
@@ -239,6 +239,8 @@ def get_item_name(sp, item_type, item_id):
name = sp.album(album_id=item_id).get("name") name = sp.album(album_id=item_id).get("name")
elif item_type == "track": elif item_type == "track":
name = sp.track(track_id=item_id).get("name") name = sp.track(track_id=item_id).get("name")
elif item_type == "artist_top_tracks":
name = sp.artist_top_tracks(artist_id=item_id).get("name")
return sanitize(name) return sanitize(name)
+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)