diff --git a/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaOutput.kt b/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaOutput.kt index 11457730c..6075d766b 100644 --- a/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaOutput.kt +++ b/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaOutput.kt @@ -15,5 +15,9 @@ class MediaOutput( is Media.Pause -> ctx.getString(R.string.skill_media_pausing) is Media.Previous -> ctx.getString(R.string.skill_media_previous) is Media.Next -> ctx.getString(R.string.skill_media_next) + is Media.VolumeUp -> ctx.getString(R.string.skill_media_volume_up) + is Media.VolumeDown -> ctx.getString(R.string.skill_media_volume_down) + is Media.VolumeUpTimes -> ctx.getString(R.string.skill_media_volume_up) + is Media.VolumeDownTimes -> ctx.getString(R.string.skill_media_volume_down) } } diff --git a/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaSkill.kt b/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaSkill.kt index 20add711f..f9d1616f2 100644 --- a/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaSkill.kt +++ b/app/src/main/kotlin/org/stypox/dicio/skills/media/MediaSkill.kt @@ -17,18 +17,79 @@ class MediaSkill(correspondingSkillInfo: SkillInfo, data: StandardRecognizerData val audioManager = getSystemService(ctx.android, AudioManager::class.java) ?: return MediaOutput(performedAction = null) // no media session found - val key = when (inputData) { - is Media.Play -> KeyEvent.KEYCODE_MEDIA_PLAY - is Media.Pause -> KeyEvent.KEYCODE_MEDIA_PAUSE - is Media.Previous -> KeyEvent.KEYCODE_MEDIA_PREVIOUS - is Media.Next -> KeyEvent.KEYCODE_MEDIA_NEXT + when (inputData) { + is Media.Play -> { + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY)) + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY)) + } + is Media.Pause -> { + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE)) + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PAUSE)) + } + is Media.Previous -> { + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS)) + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PREVIOUS)) + } + is Media.Next -> { + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT)) + audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT)) + } + is Media.VolumeUp -> { + audioManager.adjustStreamVolume( + AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_RAISE, + AudioManager.FLAG_SHOW_UI + ) + } + is Media.VolumeDown -> { + audioManager.adjustStreamVolume( + AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_LOWER, + AudioManager.FLAG_SHOW_UI + ) + } + is Media.VolumeUpTimes -> { + val times = extractNumberFromString(ctx, inputData.times) + repeat(times) { + audioManager.adjustStreamVolume( + AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_RAISE, + if (it == 0) AudioManager.FLAG_SHOW_UI else 0 + ) + } + } + is Media.VolumeDownTimes -> { + val times = extractNumberFromString(ctx, inputData.times) + repeat(times) { + audioManager.adjustStreamVolume( + AudioManager.STREAM_MUSIC, + AudioManager.ADJUST_LOWER, + if (it == 0) AudioManager.FLAG_SHOW_UI else 0 + ) + } + } } - audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, key)) - audioManager.dispatchMediaKeyEvent(KeyEvent(KeyEvent.ACTION_UP, key)) return MediaOutput(performedAction = inputData) } + private fun extractNumberFromString(ctx: SkillContext, input: String?): Int { + if (input.isNullOrBlank()) { + return 1 + } + + return ctx.parserFormatter!! + .extractNumber(input) + .mixedWithText + .asSequence() + .filterIsInstance() + .filter { it.isInteger } + .map { it.integerValue().toInt() } + .firstOrNull() + ?.coerceIn(1, 10) // Limit to 1-10 steps for safety + ?: 1 + } + companion object { val TAG: String = MediaSkill::class.simpleName!! } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 58ec71269..eebb24ce5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -172,6 +172,8 @@ Pausing media… Previous media… Next media… + Increasing volume + Decreasing volume No media session is active I could not calculate your request No contact found, try again diff --git a/app/src/main/sentences/de/media.yml b/app/src/main/sentences/de/media.yml index e4a43a4dc..1974fd9e0 100644 --- a/app/src/main/sentences/de/media.yml +++ b/app/src/main/sentences/de/media.yml @@ -14,4 +14,12 @@ previous: next: - skip|überspring|ueberspring das|den|die|ein? audio|film|hör|lied|musik|podcast|song|stream|stück|track|video - - spiel|spring|geh? das|den|die|zu? nächste|folgende audio|film|hör|lied|musik|podcast|song|stream|stück|track|video? (in der schlange)? \ No newline at end of file + - spiel|spring|geh? das|den|die|zu? nächste|folgende audio|film|hör|lied|musik|podcast|song|stream|stück|track|video? (in der schlange)? + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/app/src/main/sentences/en/media.yml b/app/src/main/sentences/en/media.yml index 7e4ffca88..806bf15fb 100644 --- a/app/src/main/sentences/en/media.yml +++ b/app/src/main/sentences/en/media.yml @@ -14,3 +14,25 @@ previous: next: - skip the|a|one? song|media|track|music|audio|video|movie|stream|film - play|(go|switch|skip|jump|(move forward) to)? the? next|following song|media|track|music|audio|video|movie|stream|film? (in the queue)? + +volume_up: + - increase|raise|(turn up) the? volume|sound + - (turn the?)? volume|sound up + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film louder + +volume_down: + - decrease|lower|(turn down) the? volume|sound + - (turn the?)? volume|sound down + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film quieter + +volume_up_times: + - increase|raise|(turn up) the? volume|sound by? .times. times|clicks|steps|notches|levels? + - (turn the?)? volume|sound up by? .times. times|clicks|steps|notches|levels? + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film louder by .times. times|clicks|steps|notches|levels? + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film .times. times|clicks|steps|notches|levels louder + +volume_down_times: + - decrease|lower|(turn down) the? volume|sound by? .times. times|clicks|steps|notches|levels? + - (turn the?)? volume|sound down by? .times. times|clicks|steps|notches|levels? + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film quieter by .times. times|clicks|steps|notches|levels? + - (make the?)? volume|sound|song|media|track|music|audio|video|movie|stream|film .times. times|clicks|steps|notches|levels quieter diff --git a/app/src/main/sentences/es/media.yml b/app/src/main/sentences/es/media.yml index 1b784426e..b7428a8f4 100644 --- a/app/src/main/sentences/es/media.yml +++ b/app/src/main/sentences/es/media.yml @@ -16,4 +16,12 @@ previous: next: - reproducir|sonar|saltar el|la? cancion|media|pista|musica|audio|video|film|peli|stream|transmision siguiente|posterior|sucesor (de|en la cola|fila)? - reproducir|sonar|saltar el|la? siguiente|posterior|sucesor cancion|media|pista|musica|audio|video|film|peli|stream|transmision (de|en la cola|fila)? - - ir|saltar|omitir (a el)|al|la siguiente|sucesor \ No newline at end of file + - ir|saltar|omitir (a el)|al|la siguiente|sucesor + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/app/src/main/sentences/fr/media.yml b/app/src/main/sentences/fr/media.yml index 5713ea58d..4e640970e 100644 --- a/app/src/main/sentences/fr/media.yml +++ b/app/src/main/sentences/fr/media.yml @@ -12,3 +12,11 @@ previous: next: - (joue|jouer|jouez|mais|mets|mettez|mettre|(passe à)|(passer à)|(passez à))? la|le? chanson|média|piste|musique|audio|film|stream suivant + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/app/src/main/sentences/it/media.yml b/app/src/main/sentences/it/media.yml index 5ccb8def6..aa4c38178 100644 --- a/app/src/main/sentences/it/media.yml +++ b/app/src/main/sentences/it/media.yml @@ -16,3 +16,19 @@ next: - vai|butta? in? avanti di una canzone|traccia|musica|audio|brano|video - (metti il|la)|(passa|vai al)? canzone|traccia|musica|audio|brano|video successiv|dopo - (metti il|la)|(passa|vai al)? successiv|prossim canzone|traccia|musica|audio|brano|video + +volume_up: + - alza|aumenta|incrementa il|l? volume|suono|audio + - volume su|(più alto|forte) + +volume_down: + - abbassa|diminuisci|riduci il|l? volume|suono|audio + - volume giù|(più basso|silenzioso) + +volume_up_times: + - alza|aumenta|incrementa il|l? volume|suono|audio di? .times. volte|passi|tacche|livelli? + - volume su|(più alto|forte) di? .times. volte|passi|tacche|livelli? + +volume_down_times: + - abbassa|diminuisci|riduci il|l? volume|suono|audio di? .times. volte|passi|tacche|livelli? + - volume giù|(più basso|silenzioso) di? .times. volte|passi|tacche|livelli? diff --git a/app/src/main/sentences/nl/media.yml b/app/src/main/sentences/nl/media.yml index 38c4508f1..53473f65f 100644 --- a/app/src/main/sentences/nl/media.yml +++ b/app/src/main/sentences/nl/media.yml @@ -15,3 +15,11 @@ next: - skip (dit|deze)? (lied|nummer|song|muziek|audio|video|film|stream|clip)? - speel|start|begin|(skip naar)|(ga (verder met)|naar) (de|het)? volgende lied|nummer|song|muziek|audio|video|film|stream|clip afspelen? - volgende (lied|nummer|song|muziek|audio|video|film|stream|clip)? + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/app/src/main/sentences/skill_definitions.yml b/app/src/main/sentences/skill_definitions.yml index ed347e967..1be7e68e4 100644 --- a/app/src/main/sentences/skill_definitions.yml +++ b/app/src/main/sentences/skill_definitions.yml @@ -44,6 +44,16 @@ skills: - id: pause - id: previous - id: next + - id: volume_up + - id: volume_down + - id: volume_up_times + captures: + - id: times + type: string + - id: volume_down_times + captures: + - id: times + type: string - id: joke specificity: high diff --git a/app/src/main/sentences/sv/media.yml b/app/src/main/sentences/sv/media.yml index 95d43cd11..e964f7d45 100644 --- a/app/src/main/sentences/sv/media.yml +++ b/app/src/main/sentences/sv/media.yml @@ -11,4 +11,12 @@ previous: next: - skippa|(hoppa över?) en|nästa? sång|media|låt|musik|audio|video|film|stream - - spela|(byt|hoppa|växla till) nästa|följande sång|media|låt|musik|audio|video|film|stream (i kön)? \ No newline at end of file + - spela|(byt|hoppa|växla till) nästa|följande sång|media|låt|musik|audio|video|film|stream (i kön)? + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/app/src/main/sentences/tr/media.yml b/app/src/main/sentences/tr/media.yml index a66e32b53..5b0327fe4 100644 --- a/app/src/main/sentences/tr/media.yml +++ b/app/src/main/sentences/tr/media.yml @@ -12,3 +12,11 @@ previous: next: - (bir? sonraki)|(bir? ilerideki|sıradaki) (şarkı|medya|parça|müzi|ses|video|dizi|yayın<ı|a?>|film) geç|oynat|git|değiş|geç|zıpla|(ileri sar) - ileri sar + +volume_up: + +volume_down: + +volume_up_times: + +volume_down_times: diff --git a/sentences-compiler-plugin/src/main/kotlin/org/stypox/dicio/sentencesCompilerPlugin/data/ExtractDataFromFiles.kt b/sentences-compiler-plugin/src/main/kotlin/org/stypox/dicio/sentencesCompilerPlugin/data/ExtractDataFromFiles.kt index b3d11f372..7c5f6b31a 100644 --- a/sentences-compiler-plugin/src/main/kotlin/org/stypox/dicio/sentencesCompilerPlugin/data/ExtractDataFromFiles.kt +++ b/sentences-compiler-plugin/src/main/kotlin/org/stypox/dicio/sentencesCompilerPlugin/data/ExtractDataFromFiles.kt @@ -21,7 +21,7 @@ fun extractDataFromFiles(logger: Logger, inputDirFile: File): ExtractedData { continue } - val parsedSentences: Map?> = parseYamlFile(file) + val parsedSentences: Map = parseYamlFile(file) val expectedSentenceIds = skill.sentences.map { it.id }.toSet() if (!parsedSentences.keys.containsAll(expectedSentenceIds)) { throw SentencesCompilerPluginException( @@ -41,22 +41,21 @@ fun extractDataFromFiles(logger: Logger, inputDirFile: File): ExtractedData { ) } - val emptySentences = parsedSentences - .filter { it.value.isNullOrEmpty() } - .map { it.key } - if (emptySentences.isNotEmpty()) { - logger.error( - "[Warning] Skill sentences file ${lang.name}/${ - file.name - } has no sentence definitions for these sentence ids ${ - emptySentences - }: ${file.absolutePath}" - ) - } - + val emptySentenceIds = ArrayList() for ((sentenceId, parsedSentencesWithoutId) in parsedSentences) { - if (parsedSentencesWithoutId == null) { - continue // the warning was issued above + if ((parsedSentencesWithoutId as? String)?.isBlank() == true + || (parsedSentencesWithoutId as? List<*>)?.isEmpty() == true + ) { + emptySentenceIds.add(sentenceId) + continue // a warning is raised below + } else if ((parsedSentencesWithoutId as? List<*>)?.all { it is String } != true) { + throw SentencesCompilerPluginException( + "Skill sentences file ${lang.name}/${ + file.name + } contains an invalid value for sentence id ${ + sentenceId + }: ${file.absolutePath}" + ) } // only mark as true if there actually is a sentence for this language @@ -69,11 +68,21 @@ fun extractDataFromFiles(logger: Logger, inputDirFile: File): ExtractedData { RawSentence( id = sentenceId, file = file, - rawConstructs = sentence, + rawConstructs = sentence as String, ) ) } } + + if (emptySentenceIds.isNotEmpty()) { + logger.warn( + "[Warning] Skill sentences file ${lang.name}/${ + file.name + } has no sentence definitions for these sentence ids ${ + emptySentenceIds + }: ${file.absolutePath}" + ) + } } if (langHasSentence) {