From 4c486199eda7fac0237b2bd534e0119e0a4efdd7 Mon Sep 17 00:00:00 2001 From: mathayay Date: Sun, 23 Nov 2025 23:39:43 +0100 Subject: [PATCH] travail d'un we (j'en ai big marre) --- .cache | 1 - final-loop/Dockerfile | 10 ++ final-loop/client-cache/credentials.json | 1 + final-loop/client-cache/volume | 1 + final-loop/compose.yml | 34 +++++++ final-loop/requirements.txt | 32 +++++++ final-loop/spotify-codes-part-2/.cache | 1 - .../spotify-codes-part-2/requirements.txt | 21 ----- .../src/decode_barcode.py | 57 ------------ ...potify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg | Bin 15154 -> 0 bytes .../spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg | Bin 15669 -> 0 bytes .../src/crc.py | 0 final-loop/src/decode_barcode.py | 86 ++++++++++++++++++ .../src/encode_decode.py | 0 .../src/get_heights.py | 40 ++++++-- .../src/get_uri.py | 0 .../src/permute.py | 0 .../src/simple_convolutional_code.py | 0 main.py => final-loop/src/start_song.py | 26 ++---- .../src/step_by_step.py | 0 old/.cache | 1 + anaislpb.py => old/anaislpb.py | 0 rebirth.jpg => old/rebirth.jpg | Bin .../shapeDetectionImageCrop.py | 0 .../spotify-codes-part-2/.cache | 0 .../spotify-codes-part-2/README.md | 0 .../spotify-codes-part-2/aa.jpg | Bin .../spotify-codes-part-2/allo.jpg | Bin .../spotify-codes-part-2/aloorrrrr.jpg | Bin .../spotify-codes-part-2/biz.jpg | Bin .../spotify-codes-part-2/biz.png | Bin .../spotify-codes-part-2/bizrog.jpg | Bin .../spotify-codes-part-2/bw.jpg | Bin .../spotify-codes-part-2/bz.jpg | Bin .../spotify-codes-part-2/code.jpeg | Bin .../spotify-codes-part-2/csq.jpg | Bin .../spotify-codes-part-2/imperdable.jpg | Bin .../spotify-codes-part-2/jtd.jpg | Bin .../spotify-codes-part-2/jtd.png | Bin .../spotify-codes-part-2/lala.jpeg | Bin .../spotify-codes-part-2/layayaya.jpg | Bin .../spotify-codes-part-2/maybe.jpg | Bin .../spotify-codes-part-2/maybe.png | Bin .../spotify-codes-part-2/nggyu.jpg | Bin .../spotify-codes-part-2/nggyu.png | Bin .../spotify-codes-part-2/parfd.jpg | Bin .../spotify-codes-part-2/print.jpg | Bin .../spotify-codes-part-2/rage.jpg | Bin .../spotify-codes-part-2/rbw.jpg | Bin .../spotify-codes-part-2/requirements.txt | 0 .../spotify-codes-part-2/rog.jpg | Bin .../spotify-codes-part-2/rogprint.jpg | Bin .../spotify-codes-part-2/rouuuge.jpg | Bin .../spotify-codes-part-2/rr.jpeg | Bin .../spotify-codes-part-2/src/crc.py | 0 .../src/decode_barcode.py | 0 .../spotify-codes-part-2/src/encode_decode.py | 0 .../spotify-codes-part-2/src/get_heights.py | 8 +- .../spotify-codes-part-2/src/get_uri.py | 0 .../spotify-codes-part-2/src/permute.py | 0 ...potify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg | Bin .../spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg | Bin .../src/simple_convolutional_code.py | 0 .../spotify-codes-part-2/src/step_by_step.py | 0 .../spotify-codes-part-2/st.jpeg | Bin .../spotify-codes-part-2/test.jpg | Bin .../spotify-codes-part-2/testrouge.jpg | Bin {test => old/test}/compose.yml | 0 {test => old/test}/spotifyd.conf | 0 69 files changed, 208 insertions(+), 111 deletions(-) delete mode 100644 .cache create mode 100644 final-loop/Dockerfile create mode 100644 final-loop/client-cache/credentials.json create mode 100644 final-loop/client-cache/volume create mode 100644 final-loop/compose.yml create mode 100644 final-loop/requirements.txt delete mode 100644 final-loop/spotify-codes-part-2/.cache delete mode 100644 final-loop/spotify-codes-part-2/requirements.txt delete mode 100644 final-loop/spotify-codes-part-2/src/decode_barcode.py delete mode 100644 final-loop/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg delete mode 100644 final-loop/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/crc.py (100%) create mode 100644 final-loop/src/decode_barcode.py rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/encode_decode.py (100%) rename final-loop/{spotify-codes-part-2 => }/src/get_heights.py (57%) rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/get_uri.py (100%) rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/permute.py (100%) rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/simple_convolutional_code.py (100%) rename main.py => final-loop/src/start_song.py (69%) rename {boonepeter.github.io-code/spotify-codes-part-2 => final-loop}/src/step_by_step.py (100%) create mode 100644 old/.cache rename anaislpb.py => old/anaislpb.py (100%) rename rebirth.jpg => old/rebirth.jpg (100%) rename shapeDetectionImageCrop.py => old/shapeDetectionImageCrop.py (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/.cache (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/README.md (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/aa.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/allo.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/aloorrrrr.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/biz.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/biz.png (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/bizrog.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/bw.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/bz.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/code.jpeg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/csq.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/imperdable.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/jtd.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/jtd.png (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/lala.jpeg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/layayaya.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/maybe.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/maybe.png (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/nggyu.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/nggyu.png (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/parfd.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/print.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rage.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rbw.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/requirements.txt (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rog.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rogprint.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rouuuge.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/rr.jpeg (100%) rename {final-loop => old}/spotify-codes-part-2/src/crc.py (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/src/decode_barcode.py (100%) rename {final-loop => old}/spotify-codes-part-2/src/encode_decode.py (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/src/get_heights.py (94%) rename {final-loop => old}/spotify-codes-part-2/src/get_uri.py (100%) rename {final-loop => old}/spotify-codes-part-2/src/permute.py (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg (100%) rename {final-loop => old}/spotify-codes-part-2/src/simple_convolutional_code.py (100%) rename {final-loop => old}/spotify-codes-part-2/src/step_by_step.py (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/st.jpeg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/test.jpg (100%) rename {boonepeter.github.io-code => old}/spotify-codes-part-2/testrouge.jpg (100%) rename {test => old/test}/compose.yml (100%) rename {test => old/test}/spotifyd.conf (100%) diff --git a/.cache b/.cache deleted file mode 100644 index 387f693..0000000 --- a/.cache +++ /dev/null @@ -1 +0,0 @@ -{"access_token": "BQDeVV_yylewo72n9ZtSMTn1WNhJKSbUBDKv18Cl-QY7dphidwC9jDuGuZWKaIWZv-fVIG1uuP1XvJFKwcj3GOxgRxYJbaWOLtogCHkAxC-iOaZe6uphn-vCy5rbX6Xlx9XVUG-jHNu0jaCf1-ueTRUQuyF0Btu4_aAcIktTnYyofSUJuk_Mdi1J6V3hmARkCl34Rv-4hgfXcIqQ_rpdCFHGheEU1rSL5oME", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1757966041, "refresh_token": "AQAxD3wm_8aDlK9w2ZsibKsrPY0SxUJb2UaqiT2ygxK-pEq2ojxPzgLa6DNt9EpP3mjFDCLmGO5glj5fSpR3ZnqEa26belG4EQv5FOeee38ix31o2xuxPbDsY44KR5Uj1KE"} \ No newline at end of file diff --git a/final-loop/Dockerfile b/final-loop/Dockerfile new file mode 100644 index 0000000..71c5ea5 --- /dev/null +++ b/final-loop/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt ./ + +RUN pip install --no-cache-dir -r requirements.txt + +COPY src/ . + diff --git a/final-loop/client-cache/credentials.json b/final-loop/client-cache/credentials.json new file mode 100644 index 0000000..42c2078 --- /dev/null +++ b/final-loop/client-cache/credentials.json @@ -0,0 +1 @@ +{"username":"mathias-120","auth_type":1,"auth_data":"QWdDZF9iOVZDTUltQ0Noc0lnSFdfNU5QOXBMdFdiQllFclJ3dHM3ZVRaY1lzUEpKd1Jwc1pOc3FzdjFwYnRYZ2ZRSXE2Q1ZiWTBjdzRDTUYzdkJMekdqOVliRTh1UldlZlJOdF94eEgydzJUWmhtT0RlX295ODdrTzZDYXFuMW5SVEQ4TV95S2R0aEJLTDZldkxPeDlva0wtcHJNY0p6Q3VzQl9YOGFhVHNYaw=="} \ No newline at end of file diff --git a/final-loop/client-cache/volume b/final-loop/client-cache/volume new file mode 100644 index 0000000..35ff949 --- /dev/null +++ b/final-loop/client-cache/volume @@ -0,0 +1 @@ +65535 \ No newline at end of file diff --git a/final-loop/compose.yml b/final-loop/compose.yml new file mode 100644 index 0000000..51b0d73 --- /dev/null +++ b/final-loop/compose.yml @@ -0,0 +1,34 @@ +services: + librespot: + container_name: spotvinyl-client + image: giof71/librespot:latest + network_mode: host + devices: + - /dev/snd:/dev/snd + environment: + - DEVICE=hw:x20,0 + - BACKEND=alsa + - BITRATE=320 + - INITIAL_VOLUME=100 + - DEVICE_NAME=spotvinyl + - ENABLE_OAUTH=headless # Enables OAuth headless mode + - ENABLE_SYSTEM_CACHE=Y # Cache token for persistent login + volumes: + - ./client-cache:/data/system-cache + stdin_open: true + tty: true + + spotvinyl: + build: . + container_name: spotvinyl + devices: + - /dev/video2 + volumes: + - ./src:/app + # - ./spotvinyl-cache + working_dir: /app + env_file: + - .env + command: python3 decode_barcode.py + ports: + - "5000:5000" diff --git a/final-loop/requirements.txt b/final-loop/requirements.txt new file mode 100644 index 0000000..f58bc59 --- /dev/null +++ b/final-loop/requirements.txt @@ -0,0 +1,32 @@ +certifi==2025.11.12 +chardet==5.2.0 +charset-normalizer==3.4.4 +contourpy==1.3.3 +crccheck==1.3.1 +cycler==0.12.1 +decorator==5.2.1 +fonttools==4.60.1 +idna==3.11 +ImageIO==2.37.2 +joblib==1.5.2 +kiwisolver==1.4.9 +lazy_loader==0.4 +matplotlib==3.10.7 +networkx==3.5 +numpy==2.2.6 +opencv-python==4.12.0.88 +packaging==25.0 +pillow==12.0.0 +pyparsing==3.2.5 +python-dateutil==2.9.0.post0 +PyWavelets==1.9.0 +redis==7.1.0 +requests==2.32.5 +scikit-image==0.25.2 +scikit-learn==1.7.2 +scipy==1.16.3 +six==1.17.0 +spotipy==2.25.1 +threadpoolctl==3.6.0 +tifffile==2025.10.16 +urllib3==2.5.0 diff --git a/final-loop/spotify-codes-part-2/.cache b/final-loop/spotify-codes-part-2/.cache deleted file mode 100644 index 573b327..0000000 --- a/final-loop/spotify-codes-part-2/.cache +++ /dev/null @@ -1 +0,0 @@ -{"access_token": "BQAHRFXWQMMKWNbUO3sfhk92iUGi5VJNZmB2lTjRim-g2AIe88mgDvyc1NywjCVBTeZK-b3PkXzGDANJDDOouitEt5P8z0jpVuPrpalwAg0PzEwtKBXr8PHvacajO9B3s7Wy0s7G3CFlfGfbOfmXtW_vF8G2_ooGnlFp_oM8RcOyBl7D5Okf6kr07CWIJty4mNeTf1Ifd212u1tBnbU64lckqlQ0f0W105mt", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "AQCSe9ARCDB-Q6gzna_KKAlcEuNOx2IC9BSVXS5GZxNDi4AjJdA4Kn3hp1YPfiPfogd2rz-5zLbyjUxiRj9oTd-q5EItEPZHIVt-eMf7gCGHfj6h-hLpRrnhgMZjzRAS7CY", "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1757966002} \ No newline at end of file diff --git a/final-loop/spotify-codes-part-2/requirements.txt b/final-loop/spotify-codes-part-2/requirements.txt deleted file mode 100644 index a77113c..0000000 --- a/final-loop/spotify-codes-part-2/requirements.txt +++ /dev/null @@ -1,21 +0,0 @@ -certifi>=2023.5.7 -chardet>=5.1.0 -crccheck>=1.0 -cycler>=0.11.0 -decorator>=5.1.1 -idna>=3.5 -imageio>=2.31.1 -kiwisolver>=1.4.4 -matplotlib>=3.7.1 -networkx>=3.1 -numpy>=1.24.2 -Pillow>=10.0.0 -pyparsing>=3.0.9 -python-dateutil>=2.8.2 -PyWavelets>=1.4.1 -requests>=2.31.0 -scikit-image>=0.25.2 -scipy>=1.11.1 -six>=1.16.0 -tifffile>=2023.7.23 -urllib3>=2.0.4 diff --git a/final-loop/spotify-codes-part-2/src/decode_barcode.py b/final-loop/spotify-codes-part-2/src/decode_barcode.py deleted file mode 100644 index 0bd7463..0000000 --- a/final-loop/spotify-codes-part-2/src/decode_barcode.py +++ /dev/null @@ -1,57 +0,0 @@ -import argparse -import pprint -from get_heights import get_heights -from encode_decode import spotify_bar_decode -from get_uri import get_uri, get_info -import cv2 - - -def process_frame(frame, token): - heights = get_heights(frame) - print(len(heights)) # assumes get_heights can take image array - if len(heights) != 23: - return None # skip bad frames - else: - print("ON TROUVE UN CODE") - - heights = heights[1:11] + heights[12:-1] - decoded = spotify_bar_decode(heights) - uri = get_uri(decoded, token) - summary, full_response = get_info(uri["target"], token) - return summary - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--token", required=True) - args = parser.parse_args() - token = args.token - - cap = cv2.VideoCapture(0) # 0 for default webcam - - while True: - ret, frame = cap.read() - if not ret: - break - - # Définir les dimensions et la marge du cadre - height, width, _ = frame.shape - margin = 100 # ajustez la taille du cadre ici - frame = frame[margin:height - margin, margin:width - margin] - - try: - summary = process_frame(frame, token) - except Exception: - continue - - if summary: - print("Summary:") - pprint.pprint(summary) - - cv2.imshow("Live Barcode", frame) - - if cv2.waitKey(1) & 0xFF == ord('q'): - break - - cap.release() - cv2.destroyAllWindows() diff --git a/final-loop/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg b/final-loop/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg deleted file mode 100644 index 64eb04b3bbd3ee22c72a647ef9d05f4cdbe36186..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15154 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 X8rUIf>;FA*`9E>u@*jC^(OD93 diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/crc.py b/final-loop/src/crc.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/crc.py rename to final-loop/src/crc.py diff --git a/final-loop/src/decode_barcode.py b/final-loop/src/decode_barcode.py new file mode 100644 index 0000000..a56cfdd --- /dev/null +++ b/final-loop/src/decode_barcode.py @@ -0,0 +1,86 @@ +import argparse +import pprint +from get_heights import get_heights +from encode_decode import spotify_bar_decode +from get_uri import get_uri, get_info +import cv2 +from start_song import start_song +import os +from flask import Flask, Response +import threading +import time +import numpy as np + +os.environ["QT_QPA_PLATFORM"] = "xcb" +def process_frame(frame, token): + + heights,preprocess = get_heights(frame) + cv2.imshow("frame", preprocess) + if len(heights)!=23: + return None # skip bad frames + else: + print("ON TROUVE UN CODE") + + + heights = heights[1:11] + heights[12:-1] + decoded = spotify_bar_decode(heights) + uri = get_uri(decoded, token) + summary, full_response = get_info(uri["target"], token) + print(f"SONG FOUND : {summary["name"]}") + if uri: + start_song(uri['target'],os.getenv('DEVICE_ID')) + return summary + + + + + + + + + + +if __name__ == "__main__": + + + + cap = cv2.VideoCapture('/dev/video0') + + + token = os.getenv('ACCESS_TOKEN') + if not token: + token = "BQCph85n2Cr-h8jKWhsdsdhywaX3h_bn4pJ_-jdque2u_gn9bI-OdthIowGSU6r058QozL0eJfzy_ClWezXYKrQO2npuyfWVphxSQrKqhBWkGr5bK0UrIfsKKAdJvoNrXD9Db-ObgP5D3-rMpF0Xq3RXwMpTal9NpzTJcHZs_PBjbNClJVy24Jk5WfGbKZPkMs_Hon5TjABx4QzxzE2vxjd4X4EyPlyPuKiIVp-f7yTSJbbRLqt-_O_VJ9mnQ1RgGK16afY7p3JZH_B6-VSCrFuhK_m9yhSieiWoqEeopFEX47Nc4-tuqe8CXcYGiRLZBIcc4w64ly36ZIftxRN7ehcJb2gcV26ZqMS1lg1Yxp0OD4ShJJsinA69X535_w" + print(token) + + + if not cap.isOpened(): + print("Error: Could not open camera.") + exit(1) + else: + print("Camera is working and ready to capture frames.") + + while True: + ret, frame = cap.read() + if not ret: + break + # Crop same as streaming for consistency + height, width, _ = frame.shape + margin = 100 + frame = frame[margin:height - margin, margin:width - margin] + + try: + + + summary = process_frame(frame, token) + + except Exception as e: + print(e) + print("") + continue + # cv2.imshow("preframe", frame) + + if cv2.waitKey(1) & 0xFF == ord('q'): + break + + cap.release() + cv2.destroyAllWindows() \ No newline at end of file diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/encode_decode.py b/final-loop/src/encode_decode.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/encode_decode.py rename to final-loop/src/encode_decode.py diff --git a/final-loop/spotify-codes-part-2/src/get_heights.py b/final-loop/src/get_heights.py similarity index 57% rename from final-loop/spotify-codes-part-2/src/get_heights.py rename to final-loop/src/get_heights.py index 38b8ea4..a2a6e50 100644 --- a/final-loop/spotify-codes-part-2/src/get_heights.py +++ b/final-loop/src/get_heights.py @@ -8,24 +8,46 @@ from skimage.color import rgb2gray import matplotlib.patches as patches from sklearn.cluster import KMeans import warnings +from skimage.morphology import remove_small_objects +from skimage.transform import resize +from skimage import exposure +from skimage.morphology import erosion, square +import cv2 +from skimage.filters import threshold_local +from scipy import ndimage as ndi +from skimage.segmentation import watershed +from skimage.morphology import opening, rectangle +from scipy.ndimage import gaussian_filter warnings.filterwarnings("ignore", category=FutureWarning, message=".*square.*deprecated.*") - +#### keep this. If does not work, remove black and reaply the logic only to not-black part of the picture def get_heights(image): # image = io.imread(filename) + + im = rgb2gray(image) - binary_im = im > threshold_otsu(im) - smooth_im = gaussian(binary_im.astype(float), sigma=1) - morph_im = closing(smooth_im > 0.5, square(3)) - labeled = label(morph_im) + + # Filtrage gaussien léger pour diminuer bruit + im_blur = gaussian_filter(im, sigma=1) + + # Calcul du seuil local avec block_size impair, ajuster offset si besoin + th = threshold_local(im_blur, block_size=71, offset=-0.09) + + binary_im = im_blur > th + + separated = binary_im + labeled = label(separated) + bar_dims = [r.bbox for r in regionprops(labeled)] bar_dims.sort(key=lambda x: x[1]) # left to right - bars = bar_dims[1:] # skip logo + bars = bar_dims#[1:] # skip logo bar_heights_raw = [] if(len(bars)!=23): - return [0] + print(len(bars)) + return [0], (separated.astype("uint8") * 255) # convert to 0/255 uint8 + for bar in bars: top, left, bottom, right = bar effective_height = bottom - top # use bounding box height directly @@ -44,5 +66,5 @@ def get_heights(image): closest_cluster = np.argmin(diffs) predicted_levels.append(int(closest_cluster)) - - return predicted_levels + print(predicted_levels) + return predicted_levels, (separated.astype("uint8") * 255) diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/get_uri.py b/final-loop/src/get_uri.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/get_uri.py rename to final-loop/src/get_uri.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/permute.py b/final-loop/src/permute.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/permute.py rename to final-loop/src/permute.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/simple_convolutional_code.py b/final-loop/src/simple_convolutional_code.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/simple_convolutional_code.py rename to final-loop/src/simple_convolutional_code.py diff --git a/main.py b/final-loop/src/start_song.py similarity index 69% rename from main.py rename to final-loop/src/start_song.py index 852fbfe..ac6e89d 100644 --- a/main.py +++ b/final-loop/src/start_song.py @@ -9,7 +9,7 @@ REDIRECT_URI = 'https://vinyly.couraud.xyz' SCOPE = 'user-modify-playback-state user-read-playback-state' -def main(): +def start_song(URI="spotify:track:0RoA7ObU6phWpqhlC9zH4Z",device_id="a499b8f3684d8098ffb5f9ff11392ebdd61fc6d1"): auth_manager = SpotifyOAuth(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=REDIRECT_URI, @@ -26,28 +26,18 @@ def main(): sp = spotipy.Spotify(auth_manager=auth_manager) - if len(sys.argv) < 2: - print('Usage: python play_spotify.py "song name"') - sys.exit(1) - - song_name = ' '.join(sys.argv[1:]) - - results = sp.search(q=song_name, type='track', limit=1) - if not results['tracks']['items']: - print(f'No track found for: {song_name}') - sys.exit(1) - - track_uri = results['tracks']['items'][0]['uri'] devices = sp.devices() if not devices['devices']: print('No active Spotify devices found. Please start playback on a device.') sys.exit(1) - active_device_id = devices['devices'][0]['id'] - - sp.start_playback(device_id=active_device_id, uris=[track_uri]) - print(f'Playing "{song_name}" on device ID: {active_device_id}') + current = sp.current_user_playing_track() + if current and current.get("item"): + current_uri = current["item"]["uri"] + + if current_uri != URI: + sp.start_playback(device_id=device_id, uris=[URI]) if __name__ == '__main__': - main() \ No newline at end of file + start_song(URI,device_id) diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/step_by_step.py b/final-loop/src/step_by_step.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/step_by_step.py rename to final-loop/src/step_by_step.py diff --git a/old/.cache b/old/.cache new file mode 100644 index 0000000..bb567df --- /dev/null +++ b/old/.cache @@ -0,0 +1 @@ +{"access_token": "BQBR3Dnu7QMSOnq8G_8lOiz858WKJmMxiCgskqjp3QDu17EcQWx3Y8ALVQGSXzUcTgkJb-z5oHjJxEQJNfz8tSYREfJGGMKQfoCo0P2tCUbnB0wdGm7iSmWOlYuvrnDTVleJ9nJBGG6vVGc2ZEIl43T54_TmKbkPzampV8FuuGIATUvzbjRO6uEHqzc3ImuBELCZJjj0n8-h4zImXifkJP6pssEY76_GWgKo_HVx", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1763737778, "refresh_token": "AQAxD3wm_8aDlK9w2ZsibKsrPY0SxUJb2UaqiT2ygxK-pEq2ojxPzgLa6DNt9EpP3mjFDCLmGO5glj5fSpR3ZnqEa26belG4EQv5FOeee38ix31o2xuxPbDsY44KR5Uj1KE"} \ No newline at end of file diff --git a/anaislpb.py b/old/anaislpb.py similarity index 100% rename from anaislpb.py rename to old/anaislpb.py diff --git a/rebirth.jpg b/old/rebirth.jpg similarity index 100% rename from rebirth.jpg rename to old/rebirth.jpg diff --git a/shapeDetectionImageCrop.py b/old/shapeDetectionImageCrop.py similarity index 100% rename from shapeDetectionImageCrop.py rename to old/shapeDetectionImageCrop.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/.cache b/old/spotify-codes-part-2/.cache similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/.cache rename to old/spotify-codes-part-2/.cache diff --git a/boonepeter.github.io-code/spotify-codes-part-2/README.md b/old/spotify-codes-part-2/README.md similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/README.md rename to old/spotify-codes-part-2/README.md diff --git a/boonepeter.github.io-code/spotify-codes-part-2/aa.jpg b/old/spotify-codes-part-2/aa.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/aa.jpg rename to old/spotify-codes-part-2/aa.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/allo.jpg b/old/spotify-codes-part-2/allo.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/allo.jpg rename to old/spotify-codes-part-2/allo.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/aloorrrrr.jpg b/old/spotify-codes-part-2/aloorrrrr.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/aloorrrrr.jpg rename to old/spotify-codes-part-2/aloorrrrr.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/biz.jpg b/old/spotify-codes-part-2/biz.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/biz.jpg rename to old/spotify-codes-part-2/biz.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/biz.png b/old/spotify-codes-part-2/biz.png similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/biz.png rename to old/spotify-codes-part-2/biz.png diff --git a/boonepeter.github.io-code/spotify-codes-part-2/bizrog.jpg b/old/spotify-codes-part-2/bizrog.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/bizrog.jpg rename to old/spotify-codes-part-2/bizrog.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/bw.jpg b/old/spotify-codes-part-2/bw.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/bw.jpg rename to old/spotify-codes-part-2/bw.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/bz.jpg b/old/spotify-codes-part-2/bz.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/bz.jpg rename to old/spotify-codes-part-2/bz.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/code.jpeg b/old/spotify-codes-part-2/code.jpeg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/code.jpeg rename to old/spotify-codes-part-2/code.jpeg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/csq.jpg b/old/spotify-codes-part-2/csq.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/csq.jpg rename to old/spotify-codes-part-2/csq.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/imperdable.jpg b/old/spotify-codes-part-2/imperdable.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/imperdable.jpg rename to old/spotify-codes-part-2/imperdable.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/jtd.jpg b/old/spotify-codes-part-2/jtd.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/jtd.jpg rename to old/spotify-codes-part-2/jtd.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/jtd.png b/old/spotify-codes-part-2/jtd.png similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/jtd.png rename to old/spotify-codes-part-2/jtd.png diff --git a/boonepeter.github.io-code/spotify-codes-part-2/lala.jpeg b/old/spotify-codes-part-2/lala.jpeg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/lala.jpeg rename to old/spotify-codes-part-2/lala.jpeg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/layayaya.jpg b/old/spotify-codes-part-2/layayaya.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/layayaya.jpg rename to old/spotify-codes-part-2/layayaya.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/maybe.jpg b/old/spotify-codes-part-2/maybe.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/maybe.jpg rename to old/spotify-codes-part-2/maybe.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/maybe.png b/old/spotify-codes-part-2/maybe.png similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/maybe.png rename to old/spotify-codes-part-2/maybe.png diff --git a/boonepeter.github.io-code/spotify-codes-part-2/nggyu.jpg b/old/spotify-codes-part-2/nggyu.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/nggyu.jpg rename to old/spotify-codes-part-2/nggyu.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/nggyu.png b/old/spotify-codes-part-2/nggyu.png similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/nggyu.png rename to old/spotify-codes-part-2/nggyu.png diff --git a/boonepeter.github.io-code/spotify-codes-part-2/parfd.jpg b/old/spotify-codes-part-2/parfd.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/parfd.jpg rename to old/spotify-codes-part-2/parfd.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/print.jpg b/old/spotify-codes-part-2/print.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/print.jpg rename to old/spotify-codes-part-2/print.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rage.jpg b/old/spotify-codes-part-2/rage.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rage.jpg rename to old/spotify-codes-part-2/rage.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rbw.jpg b/old/spotify-codes-part-2/rbw.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rbw.jpg rename to old/spotify-codes-part-2/rbw.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/requirements.txt b/old/spotify-codes-part-2/requirements.txt similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/requirements.txt rename to old/spotify-codes-part-2/requirements.txt diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rog.jpg b/old/spotify-codes-part-2/rog.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rog.jpg rename to old/spotify-codes-part-2/rog.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rogprint.jpg b/old/spotify-codes-part-2/rogprint.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rogprint.jpg rename to old/spotify-codes-part-2/rogprint.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rouuuge.jpg b/old/spotify-codes-part-2/rouuuge.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rouuuge.jpg rename to old/spotify-codes-part-2/rouuuge.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/rr.jpeg b/old/spotify-codes-part-2/rr.jpeg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/rr.jpeg rename to old/spotify-codes-part-2/rr.jpeg diff --git a/final-loop/spotify-codes-part-2/src/crc.py b/old/spotify-codes-part-2/src/crc.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/crc.py rename to old/spotify-codes-part-2/src/crc.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/decode_barcode.py b/old/spotify-codes-part-2/src/decode_barcode.py similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/decode_barcode.py rename to old/spotify-codes-part-2/src/decode_barcode.py diff --git a/final-loop/spotify-codes-part-2/src/encode_decode.py b/old/spotify-codes-part-2/src/encode_decode.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/encode_decode.py rename to old/spotify-codes-part-2/src/encode_decode.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/get_heights.py b/old/spotify-codes-part-2/src/get_heights.py similarity index 94% rename from boonepeter.github.io-code/spotify-codes-part-2/src/get_heights.py rename to old/spotify-codes-part-2/src/get_heights.py index a263351..fb5e051 100644 --- a/boonepeter.github.io-code/spotify-codes-part-2/src/get_heights.py +++ b/old/spotify-codes-part-2/src/get_heights.py @@ -21,12 +21,12 @@ def get_heights(filename: str): bars = bar_dims[1:] # skip logo bar_heights_raw = [] - + print(len(bars)) for bar in bars: top, left, bottom, right = bar effective_height = bottom - top # use bounding box height directly bar_heights_raw.append(effective_height) - print(len(bars)) + # Cluster measured heights to 8 clusters representing discrete bar levels bar_heights_raw_np = np.array(bar_heights_raw).reshape(-1, 1) @@ -38,8 +38,8 @@ def get_heights(filename: str): for h in bar_heights_raw: diffs = np.abs(cluster_centers - h) closest_cluster = np.argmin(diffs) - predicted_levels.append(closest_cluster) + predicted_levels.append(int(closest_cluster)) - print(len(predicted_levels)) + print((predicted_levels)) return predicted_levels diff --git a/final-loop/spotify-codes-part-2/src/get_uri.py b/old/spotify-codes-part-2/src/get_uri.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/get_uri.py rename to old/spotify-codes-part-2/src/get_uri.py diff --git a/final-loop/spotify-codes-part-2/src/permute.py b/old/spotify-codes-part-2/src/permute.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/permute.py rename to old/spotify-codes-part-2/src/permute.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg b/old/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg rename to old/spotify-codes-part-2/src/pics/spotify_playlist_37i9dQZF1DXcBWIGoYBM5M.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg b/old/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg rename to old/spotify-codes-part-2/src/pics/spotify_track_6vQN2a9QSgWcm74KEZYfDL.jpg diff --git a/final-loop/spotify-codes-part-2/src/simple_convolutional_code.py b/old/spotify-codes-part-2/src/simple_convolutional_code.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/simple_convolutional_code.py rename to old/spotify-codes-part-2/src/simple_convolutional_code.py diff --git a/final-loop/spotify-codes-part-2/src/step_by_step.py b/old/spotify-codes-part-2/src/step_by_step.py similarity index 100% rename from final-loop/spotify-codes-part-2/src/step_by_step.py rename to old/spotify-codes-part-2/src/step_by_step.py diff --git a/boonepeter.github.io-code/spotify-codes-part-2/st.jpeg b/old/spotify-codes-part-2/st.jpeg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/st.jpeg rename to old/spotify-codes-part-2/st.jpeg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/test.jpg b/old/spotify-codes-part-2/test.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/test.jpg rename to old/spotify-codes-part-2/test.jpg diff --git a/boonepeter.github.io-code/spotify-codes-part-2/testrouge.jpg b/old/spotify-codes-part-2/testrouge.jpg similarity index 100% rename from boonepeter.github.io-code/spotify-codes-part-2/testrouge.jpg rename to old/spotify-codes-part-2/testrouge.jpg diff --git a/test/compose.yml b/old/test/compose.yml similarity index 100% rename from test/compose.yml rename to old/test/compose.yml diff --git a/test/spotifyd.conf b/old/test/spotifyd.conf similarity index 100% rename from test/spotifyd.conf rename to old/test/spotifyd.conf