forked from Shinonome/dots-hyprland
initial commit of musicRecognition
This commit is contained in:
@@ -374,6 +374,7 @@ Singleton {
|
|||||||
|
|
||||||
property JsonObject resources: JsonObject {
|
property JsonObject resources: JsonObject {
|
||||||
property int updateInterval: 3000
|
property int updateInterval: 3000
|
||||||
|
property int musicRecognitionTimeout: 16
|
||||||
}
|
}
|
||||||
|
|
||||||
property JsonObject search: JsonObject {
|
property JsonObject search: JsonObject {
|
||||||
|
|||||||
@@ -17,13 +17,16 @@ function findSuitableMaterialSymbol(summary = "") {
|
|||||||
'time': 'scheduleb',
|
'time': 'scheduleb',
|
||||||
'installed': 'download',
|
'installed': 'download',
|
||||||
'configuration reloaded': 'reset_wrench',
|
'configuration reloaded': 'reset_wrench',
|
||||||
|
'unable': 'indeterminate_question_box',
|
||||||
'config': 'reset_wrench',
|
'config': 'reset_wrench',
|
||||||
'update': 'update',
|
'update': 'update',
|
||||||
'ai response': 'neurology',
|
'ai response': 'neurology',
|
||||||
'control': 'settings',
|
'control': 'settings',
|
||||||
'upsca': 'compare',
|
'upsca': 'compare',
|
||||||
|
'music': 'music_note',
|
||||||
'install': 'deployed_code_update',
|
'install': 'deployed_code_update',
|
||||||
'startswith:file': 'folder_copy', // Declarative startsWith check
|
'startswith:file': 'folder_copy', // Declarative startsWith check
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const lowerSummary = summary.toLowerCase();
|
const lowerSummary = summary.toLowerCase();
|
||||||
|
|||||||
@@ -54,6 +54,17 @@ ContentPage {
|
|||||||
Config.options.resources.updateInterval = value;
|
Config.options.resources.updateInterval = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ConfigSpinBox {
|
||||||
|
icon: "timer_off"
|
||||||
|
text: Translation.tr("Music recognition timeout (s)")
|
||||||
|
value: Config.options.resources.musicRecognitionTimeout
|
||||||
|
from: 2
|
||||||
|
to: 100
|
||||||
|
stepSize: 2
|
||||||
|
onValueChanged: {
|
||||||
|
Config.options.resources.musicRecognitionTimeout = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentSection {
|
ContentSection {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ AbstractQuickPanel {
|
|||||||
readonly property real baseCellHeight: 56
|
readonly property real baseCellHeight: 56
|
||||||
|
|
||||||
// Toggles
|
// Toggles
|
||||||
readonly property list<string> availableToggleTypes: ["network", "bluetooth", "idleInhibitor", "easyEffects", "nightLight", "darkMode", "cloudflareWarp", "gameMode", "screenSnip", "colorPicker", "onScreenKeyboard", "mic", "audio", "notifications", "powerProfile"]
|
readonly property list<string> availableToggleTypes: ["network", "bluetooth", "idleInhibitor", "easyEffects", "nightLight", "darkMode", "cloudflareWarp", "gameMode", "screenSnip", "colorPicker", "onScreenKeyboard", "mic", "audio", "notifications", "powerProfile","musicrecognition"]
|
||||||
readonly property int columns: Config.options.sidebar.quickToggles.android.columns
|
readonly property int columns: Config.options.sidebar.quickToggles.android.columns
|
||||||
readonly property list<var> toggles: Config.ready ? Config.options.sidebar.quickToggles.android.toggles : []
|
readonly property list<var> toggles: Config.ready ? Config.options.sidebar.quickToggles.android.toggles : []
|
||||||
readonly property list<var> toggleRows: toggleRowsForList(toggles)
|
readonly property list<var> toggleRows: toggleRowsForList(toggles)
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ AndroidQuickToggleButton {
|
|||||||
name: Translation.tr("EasyEffects")
|
name: Translation.tr("EasyEffects")
|
||||||
|
|
||||||
toggled: EasyEffects.active
|
toggled: EasyEffects.active
|
||||||
buttonIcon: "graphic_eq"
|
buttonIcon: "instant_mix"
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
EasyEffects.fetchActiveState()
|
EasyEffects.fetchActiveState()
|
||||||
|
|||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
import qs
|
||||||
|
import qs.modules.common
|
||||||
|
import qs.modules.common.widgets
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
|
||||||
|
AndroidQuickToggleButton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int timeoutInterval: 5
|
||||||
|
property int timeoutDuration: Config.options.resources.musicRecognitionTimeout
|
||||||
|
property string resultsJSON
|
||||||
|
|
||||||
|
property string recognizedTrackTitle
|
||||||
|
property string recognizedTrackSubtitle
|
||||||
|
property string recognizedTrackURL
|
||||||
|
|
||||||
|
name: Translation.tr("Identify Music")
|
||||||
|
statusText: toggled ? Translation.tr("Listening...") : Translation.tr("Inactive")
|
||||||
|
toggled: false
|
||||||
|
buttonIcon: toggled ? "cadence" : "graphic_eq"
|
||||||
|
onClicked: {
|
||||||
|
if (!toggled){
|
||||||
|
recognizeMusicProc.running = true
|
||||||
|
} else {
|
||||||
|
recognizeMusicProc.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
root.toggled = !root.toggled
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: recognizeMusicProc
|
||||||
|
running: false
|
||||||
|
command: [`${Directories.scriptPath}/musicRecognition/musicRecognition.sh`, "-i", root.timeoutInterval, "-t", root.timeoutDuration]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
root.resultsJSON = this.text
|
||||||
|
if (this.text.length < 100) {
|
||||||
|
Quickshell.execDetached(["notify-send", "No music recognized", "Please make sure your music is playing and try again", "-a", "Shell"])
|
||||||
|
toggled = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var obj = JSON.parse(root.resultsJSON)
|
||||||
|
root.recognizedTrackTitle = obj.track.title
|
||||||
|
root.recognizedTrackSubtitle = obj.track.subtitle
|
||||||
|
root.recognizedTrackURL = obj.track.url
|
||||||
|
musicReconizedProc.running = true
|
||||||
|
toggled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: musicReconizedProc
|
||||||
|
running: false
|
||||||
|
command: [ "notify-send" , "Music Recognized" , root.recognizedTrackTitle + " by " + root.recognizedTrackSubtitle , "-A" , "Shazam Link" , "-a" , "Shell"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
if (this.text !== ""){
|
||||||
|
Qt.openUrlExternally(root.recognizedTrackURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StyledToolTip {
|
||||||
|
//text: Translation.tr("Identifies the song that’s playing right now")
|
||||||
|
text: "Identifies the song that’s playing right now"
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -232,4 +232,17 @@ DelegateChooser {
|
|||||||
cellSize: modelData.size
|
cellSize: modelData.size
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
DelegateChoice { roleValue: "musicrecognition"; AndroidMusicRecognition {
|
||||||
|
required property int index
|
||||||
|
required property var modelData
|
||||||
|
buttonIndex: root.startingIndex + index
|
||||||
|
buttonData: modelData
|
||||||
|
editMode: root.editMode
|
||||||
|
expandedSize: modelData.size > 1
|
||||||
|
baseCellWidth: root.baseCellWidth
|
||||||
|
baseCellHeight: root.baseCellHeight
|
||||||
|
cellSpacing: root.spacing
|
||||||
|
cellSize: modelData.size
|
||||||
|
} }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
MONITOR_SOURCE="alsa_output.pci-0000_00_1f.3.analog-stereo.monitor"
|
||||||
|
|
||||||
|
# Default değerler
|
||||||
|
INTERVAL=5
|
||||||
|
TOTAL_DURATION=30
|
||||||
|
|
||||||
|
# Parametreleri oku
|
||||||
|
while getopts "i:t:" opt; do
|
||||||
|
case $opt in
|
||||||
|
i) INTERVAL=$OPTARG ;;
|
||||||
|
t) TOTAL_DURATION=$OPTARG ;;
|
||||||
|
*) echo "Usage: $0 [-i interval_seconds] [-t total_duration_seconds]"
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
START_TIME=$(date +%s)
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
CURRENT_TIME=$(date +%s)
|
||||||
|
ELAPSED=$((CURRENT_TIME - START_TIME))
|
||||||
|
|
||||||
|
if (( ELAPSED >= TOTAL_DURATION )); then
|
||||||
|
echo "Total duration reached. Exiting."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_FILE=$(mktemp /tmp/recording.XXXXXX.wav)
|
||||||
|
|
||||||
|
parec --device="$MONITOR_SOURCE" --format=s16le --rate=44100 --channels=2 \
|
||||||
|
> >(ffmpeg -f s16le -ar 44100 -ac 2 -i - -t $INTERVAL -acodec libmp3lame "$TMP_FILE" -y -hide_banner -loglevel error) \
|
||||||
|
2>/dev/null
|
||||||
|
|
||||||
|
RESULT=$(songrec audio-file-to-recognized-song "$TMP_FILE" 2>/dev/null || true)
|
||||||
|
rm -f "$TMP_FILE"
|
||||||
|
|
||||||
|
if [ -n "$RESULT" ] && [ ${#RESULT} -gt 300 ]; then
|
||||||
|
echo "$RESULT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user