Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
75 changes: 68 additions & 7 deletions app/src/main/kotlin/org/stypox/dicio/skills/media/MediaSkill.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Comment on lines +22 to +23
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe deduplicate this (and the below) with some member function

}
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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why FLAG_SHOW_UI only the first time? Please add a comment

)
}
}
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!!
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will crash if there is no number parser. You should disable the volume up/down sentences for this skill if the number parser for the current language is null. I would suggest adding a fun withoutSentenceIds(vararg sentenceIds: String) in StandardRecognizerData, and then calling that function when building the MediaSkill in MediaInfo if the number parser is null. The function should throw if some passed sentence id is not present.

.extractNumber(input)
.mixedWithText
.asSequence()
.filterIsInstance<org.dicio.numbers.unit.Number>()
.filter { it.isInteger }
.map { it.integerValue().toInt() }
.firstOrNull()
?.coerceIn(1, 10) // Limit to 1-10 steps for safety
?: 1
Comment on lines +82 to +90
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.extractNumber(input)
.mixedWithText
.asSequence()
.filterIsInstance<org.dicio.numbers.unit.Number>()
.filter { it.isInteger }
.map { it.integerValue().toInt() }
.firstOrNull()
?.coerceIn(1, 10) // Limit to 1-10 steps for safety
?: 1
.extractNumber(input)
.first
?.takeIf { it.isInteger }
?.integerValue()
?.toInt()
?.coerceIn(1, 10) // Limit to 1-10 steps for safety
?: 1

}

companion object {
val TAG: String = MediaSkill::class.simpleName!!
}
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@
<string name="skill_media_pausing">Pausing media…</string>
<string name="skill_media_previous">Previous media…</string>
<string name="skill_media_next">Next media…</string>
<string name="skill_media_volume_up">Increasing volume</string>
<string name="skill_media_volume_down">Decreasing volume</string>
<string name="skill_media_no_media_session">No media session is active</string>
<string name="skill_calculator_could_not_calculate">I could not calculate your request</string>
<string name="skill_telephone_unknown_contact">No contact found, try again</string>
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/sentences/de/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@ previous:

next:
- skip<e?>|überspring<e?>|ueberspring<e?> das|den|die|ein<e|en?>? audio|film|hör<buch|spiel>|lied|musik<stück?>|podcast|song|stream|stück|track|video
- spiel<e?>|spring<e?>|geh<e?>? das|den|die|zu<m|r>? nächste<s|n?>|folgende<s|n?> audio|film|hör<buch|spiel>|lied|musik<stück?>|podcast|song|stream|stück|track|video? (in der <warte?>schlange)?
- spiel<e?>|spring<e?>|geh<e?>? das|den|die|zu<m|r>? nächste<s|n?>|folgende<s|n?> audio|film|hör<buch|spiel>|lied|musik<stück?>|podcast|song|stream|stück|track|video? (in der <warte?>schlange)?

volume_up:

volume_down:

volume_up_times:

volume_down_times:
22 changes: 22 additions & 0 deletions app/src/main/sentences/en/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 9 additions & 1 deletion app/src/main/sentences/es/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ previous:
next:
- reproducir|sonar|saltar el|la? cancion|<multi?>media|pista|musica|audio|video|film|peli<cula?>|stream|transmision siguiente|posterior<a?>|sucesor<a?> (de|en la cola|fila)?
- reproducir|sonar|saltar el|la? siguiente|posterior<a?>|sucesor<a?> cancion|<multi?>media|pista|musica|audio|video|film|peli<cula?>|stream|transmision (de|en la cola|fila)?
- ir|saltar|omitir (a el)|al|la siguiente|sucesor<a?>
- ir|saltar|omitir (a el)|al|la siguiente|sucesor<a?>

volume_up:

volume_down:

volume_up_times:

volume_down_times:
8 changes: 8 additions & 0 deletions app/src/main/sentences/fr/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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<e?>

volume_up:

volume_down:

volume_up_times:

volume_down_times:
16 changes: 16 additions & 0 deletions app/src/main/sentences/it/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,19 @@ next:
- vai|butta? in? avanti di una canzone|traccia|musica|audio|brano|video
- (metti il|la)|(passa|vai al<la?>)? canzone|traccia|musica|audio|brano|video successiv<a|o>|dopo
- (metti il|la)|(passa|vai al<la?>)? successiv<a|o>|prossim<a|o> canzone|traccia|musica|audio|brano|video

volume_up:
- alza|aumenta|incrementa il|l<o|a?>? volume|suono|audio
- volume su|(più alto|forte)

volume_down:
- abbassa|diminuisci|riduci il|l<o|a?>? volume|suono|audio
- volume giù|(più basso|silenzioso)

volume_up_times:
- alza|aumenta|incrementa il|l<o|a?>? 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<o|a?>? volume|suono|audio di? .times. volte|passi|tacche|livelli?
- volume giù|(più basso|silenzioso) di? .times. volte|passi|tacche|livelli?
8 changes: 8 additions & 0 deletions app/src/main/sentences/nl/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ next:
- skip (dit|deze)? (lied<je?>|nummer|song|muziek<je?>|audio|video|film<pje?>|stream|clip)?
- speel|start|begin|(skip naar)|(ga (verder met)|naar) (de|het)? volgende lied<je?>|nummer|song|muziek<je?>|audio|video|film<pje?>|stream|clip afspelen?
- volgende (lied<je?>|nummer|song|muziek<je?>|audio|video|film<pje?>|stream|clip)?

volume_up:

volume_down:

volume_up_times:

volume_down_times:
10 changes: 10 additions & 0 deletions app/src/main/sentences/skill_definitions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/sentences/sv/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ previous:

next:
- skippa|(hoppa över?) en|nästa? sång<en?>|media|låt<en?>|musik<en?>|audio|video<n?>|film<en?>|stream<en?>
- spela|(byt|hoppa|växla till) nästa|följande sång<en?>|media|låt<en?>|musik<en?>|audio|video<n?>|film<en?>|stream<en?> (i kön)?
- spela|(byt|hoppa|växla till) nästa|följande sång<en?>|media|låt<en?>|musik<en?>|audio|video<n?>|film<en?>|stream<en?> (i kön)?

volume_up:

volume_down:

volume_up_times:

volume_down_times:
8 changes: 8 additions & 0 deletions app/src/main/sentences/tr/media.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ previous:
next:
- (bir? sonraki)|(bir? ilerideki|sıradaki) (şarkı<yı|ya?>|medya<yı|ya?>|parça<yı|ya?>|müzi<k|ği|ğe?>|ses<i|e?>|video<yu|ya?>|dizi<yi|ye?>|yayın<ı|a?>|film<i|e?>) geç|oynat|git|değiş<tir?>|geç|zıpla|(ileri sar<dır|dırt?>)
- ileri sar

volume_up:

volume_down:

volume_up_times:

volume_down_times:
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ fun extractDataFromFiles(logger: Logger, inputDirFile: File): ExtractedData {
continue
}

val parsedSentences: Map<String, List<String>?> = parseYamlFile(file)
val parsedSentences: Map<String, Any?> = parseYamlFile(file)
val expectedSentenceIds = skill.sentences.map { it.id }.toSet()
if (!parsedSentences.keys.containsAll(expectedSentenceIds)) {
throw SentencesCompilerPluginException(
Expand All @@ -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<String>()
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
Expand All @@ -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) {
Expand Down