Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headphone remote control - enable next and previous navigation option on Android #847

Open
sandreas opened this issue Aug 27, 2023 · 7 comments · May be fixed by #1218
Open

Headphone remote control - enable next and previous navigation option on Android #847

sandreas opened this issue Aug 27, 2023 · 7 comments · May be fixed by #1218

Comments

@sandreas
Copy link

sandreas commented Aug 27, 2023

I'm not sure this is documented anywhere, but I think currently, it is not possible to enable the ability of navigating to next or previous via headphone remote control on android.

pause and play rewinds 10 seconds by default, which is sane, but I'm missing the other player functions (next, previous, fast forward, rewind) via headphone remote.

So there are multiple different implementations / tap codings, where some share common ground (e.g. toggle play is almost everywhere a single tap. For android there actually is an expected behaviour: https://source.android.com/docs/core/interaction/accessories/headset/expected-behavior

I would love to see this at least partly configurable. I use a Samsung EG920 EO-EG920BW headset with three buttons (for reference, let's call them vol+, vol-, toggle):

  |
┌───┐
│   │
│ + │    -> vol+
│   │ 
│   │ 
│ - │    -> vol-
│   │
│   │
│   │
│ > │    -> toggle
│   │
└───┘
  |

so my personal preference would be:

  • play / pause: single tap toggle
  • next: double tap toggle
  • previous: triple tap toggle (alternative: single tap and hold toggle)
  • fast forward: double tap and hold toggle
  • rewind: triple tap and hold toggle

This would be the way iPods EarPod remotes work. But I would accept any other implementation as long as the other features are working somehow.

Possible code reference:

@advplyr
Copy link
Owner

advplyr commented Sep 10, 2023

What do you expect to happen when you use a next/prev action?

@sandreas
Copy link
Author

sandreas commented Sep 11, 2023

What do you expect to happen when you use a next/prev action?

Depends on the content / personal preferences.

Music / audio books with multiple files:

  • Next: Next track, if available, stop when no more tracks available
  • Prev: If within the first 3 seconds of a track, skip to previous, otherwise skip to the beginning of a track

Files with chapters (audio books, podcasts):

  • Next: Next chapter, if available, stop when no more chapters available
  • Prev: If within the first 3 seconds of a chapter, skip to previous, otherwise skip to the beginning of a chapter

However, there are some minor tweaks I would love to see in the settings, although they would take a lot of effort to implement:

  • Instead of next / prev track or chapter, I would configure next/prev to fast forward / rewind 5 minutes on files with chapters
    • Reason: Chapters are unpredictable - some books have 3 minute chapters, some have 15 minute chapters

For play/pause i would like to see an increasing amount of rewind seconds, that resets after 3 seconds of no action, example:

  • First Pause: Rewind 10 seconds and pause
  • Play again
  • Pause again (within 3 seconds): Rewind 20 seconds and pause
  • Play again
  • Pause again (within 3 seconds): Rewind 30 seconds and pause
  • Play again
  • Pause again (within 3 seconds): Rewind 60 seconds and pause
  • Play again (more than 3 seconds) => reset the increasing timer
  • Pause again: rewind 10 seconds

Same of course applies to step back and step forward on the player and lockscreen controls. You could also increase that to 2 times per time step (increase timer after 2 rounds of rewinding). I think in most cases you pause multiple times you want to rewind the book just a few seconds, because you missed something. But the more you do it the more you want to go back.

So possible settings could be:

  • Play / Pause: Rewind [ ] seconds where
    • A single value would be a fixed one
    • A comma separated value would behave like described above (10,10,20,20,30,30,60,60)
  • Next/Prev: Default behaviour / Skip fixed amount of time: [ ] seconds
    • Default behaviour: Next or Previous
    • Fixed amount of time: Just fast forward or rewind.

@gazpachoking
Copy link

Just weighing in on how I use headphone buttons: I'd never want my headphone buttons to do next or previous track/chapter. That's way too long in an audio book, and way too easy to mess up with no way to get back to where you just were. The only button I would personally use from my headphones is a short rewind 30-60s. When I'm out running or walking, sometimes I need to skip back because I got distracted and missed something.

@sandreas
Copy link
Author

sandreas commented May 22, 2024

Ok, I played around with the click handler in a fork and think I found a pretty neat solution for the click detection. Unfortunately I'm not a kotlin native and can't get it translate to the player actions - so I could use some help.

So here is the diff:
master...sandreas:audiobookshelf-app:master

how does this work:

  • every keyDown and keyUp triggers a scheduled handler (!)
  • the handler takes clickCount:int and clickPressed:bool (if held down)
  • another keyDown or keyUp cancels the active scheduled handler and re-triggers it
  • keyCodes increase the number of clicks (PlayPause+=1, Next+=2, Prev+=3)
  • depending on the number of clicks, the playerNotificationService handles the configured action

problems:

  • the logs show pretty accurate click / hold detection, but it does not really translate well in the player
  • since the trigger is scheduled, it does run in a different thread
  • this leads to strange behaviour - probably easy to fix, but I'm no kotlin native (Coroutines)
  • probably after some actions the thread of the player is no longer accessible...

missing things:

  • FastForward and Rewind are not implemented in the player
  • Next (Chapter) and Previous (Chapter) are not implemented either

@advplyr
What do you think of this? Would you be able to help me a little bit? ;)

@sandreas
Copy link
Author

sandreas commented May 23, 2024

@advplyr
As said in matrix chat, I would suggest the following settings and actions as default:

click sequence selected action
click play / pause
double click next chapter / track
triple click previous chapter / track
hold jump backwards
click + hold jump forward
============ ============
double click + hold rewind
quadruple click - none / ignore -

whereas the second column is a select box with the following options:

selected action
- none / ignore -
play / pause
next chapter / track
previous chapter / track
jump backwards
jump backwards (2min)
jump backwards (5min)
jump forward
jump forward (2min)
jump forward (5min)
reset sleep timer
==============
fast forward
rewind
increase speed
decrease speed
time announcement
metadata announcement
  • increase / decrease speed refers to playback speed
  • reset sleep timer refers to the auto sleep timer
  • time announcement would try to synthesize speech to read the current time over headphones
  • metadata announcement would try to synthesize speech to read the current track name over headphones

Additionally, the click-timeout could be a setting:

  • Click timeout: 600 ms

Since some of the actions would need additional implementation steps, the items below the ======== are just ideas for future improvements. Starting with the existing actions would be totally fine.

@sandreas
Copy link
Author

@advplyr
UPDATE: I think I got it working with Coroutines. It works flawlessly on my testing device, but I did not have the time to check for side effects (regression issues with other player features).

I think this would be a GREAT addition to Audiobookshelf, maybe we should start with a configuration less default setting (like described above).

I think the most important part missing is the fastForward, rewind, next, previous steps in the player notification service.

@sandreas
Copy link
Author

sandreas commented May 26, 2024

UPDATE: Setting enableExperimentalHeadsetControls is now integrated. It is not persisted yet, but you CAN test the behaviour, if you start a track and let it play, then go to the settings and enable the setting.

Using a headset now uses the following experimental click-codes by default:

click sequence selected action
click play / pause
double click jump forward 5 min
triple click jump backwards 5 min
hold jump backwards
click + hold fast forward (new implementation)
double click + hold rewind (new implementation)

I would love to get some feedback on this. Fastest way to check it out is probably cloning my repo and just build it:

git clone https://github.com/sandreas/audiobookshelf-app.git
cd audiobookshelf-app
npm install
npm run generate
npx cap sync
npx cap open android

Then start the Android session of your liking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants