Author Topic: IR remote receiver for Linux  (Read 4866 times)

0 Members and 1 Guest are viewing this topic.

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #25 on: January 07, 2023, 03:07:05 pm »
Why making a Linux kernel specification in such a lousy way that a click into another window will render useless any input controller with physical media buttons on it, like this play/pause button on a PC keyboard?  :-//
Nothing to do with Linux, and everything to do with X Windows.

Shouldn't such a standard specify to play/pause the last player in focus?
- specify in the standard to send the multimedia events to the last player that was in focus
- specify a switch current player mechanism (like the Alt+TAB for windows, but for players only), in case more players are already open
That would be the task of the Window Manager, or the application itself.  Any application can passively grab a specific keypress (including modifier state, so you can grab say Alt+Shift+K without affecting how K or Shift+K or Alt+K or Ctrl+K is handled) so that unless someone already focused has it also grabbed, it will be delivered to the application (see XGrabKey()).
One could argue that it is silly that media player applications do not do this for Play/Pause/Stop/Forward/Back.

(Then again, certain folks insist that instead of using X11, we should use D-Bus for these, and in e.g. Cinnamon desktop, register for such events provided by the csd-media-keys daemon.  Because.. you know.  I'd like to rant, but I'll try not to.)

Alternatively, you can bind the keypress to a script that determines which window the direct the event to, and synthesize a suitable X11 event directed to that window using e.g. xdotool.

Or, following Unix philosophy, you could use a small X11 application that manages such applications you call "players", by grabbing the keypresses.  It can obtain the list of X applications using XQueryTree  (similar to xwininfo -tree -root), and send synthesized events like multimedia keypresses to specific applications using XSendEvent().  It can even monitor focus change events using XSelectInput(display, window, FocusChangeMask).  This is low-level X11 stuff, too; very lightweight.

It seems to me that your needs would be best addressed using a small X11 application that reads codes/sequences/commands directly from your serial port (connected to a microcontroller via USB-Serial bridge, or to a microcontroller with native USB, and that microcontroller having at least one IR receiver already discussed).  It would of course also grab the multimedia keys, so that stuff would Just Work.  It would need to know how to tell which windows are "Players" (either by window title, or by executable name), and it might be useful to have it have OSD capability (backgroundless frameless windows at fixed position) to display applied actions, but it would be quite straightforward application.
This has the benefit that it would adapt to the desktop user, quietly staying on the background, and only consuming very little memory and CPU time whenever window focus changes (if you want it to track focus among player applications) –– or it could also use PulseAudio services to track applications that generate sound, associating them with their respective windows (if any) ––, so that the serial-IR-controller would Do What You Mean, by monitoring which players are active or capable of generating sounds, associating them with the windows, and using X11 to send them the events.

In fact, the absolute majority of such an application written in C would be in how to manage the underlying mappings.  And the UI for that if you want an UI for it instead of configuring it fully using only flat text config files.  Because only X11 (libX11) would be the requirement (plus possibly some PulseAudio crap), it would be very stable and easy to maintain.
 
The following users thanked this post: RoGeorge

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #26 on: January 07, 2023, 03:39:21 pm »
I expect a physical IR remote to interact with whatever it is playing now in the desktop, no mater the player.  This works as expected for system volume and system mute (because LIRC was set to control the pulseaudio mute/volume), but not for play/pause/next/previous.
I wonder if simply replicating the multimedia key events to all active windows (via a simple x11 application –– not much configuration) would suffice.

(I seriously dislike dbus stuff, you see.)



It does sound like playerctl might work for you out of the box.  No need to download and compile it, it should be available in the repositories (as playerctl).  You shouldn't even need to install the daemon (the 2.0.2-1 I installed doesn't even have it).

Use your Keyboard Shortcuts to bind:
 - Play and pause to /usr/bin/playerctl play-pause
 - Forward to /usr/bin/playerctl position +5 (to skip 5 seconds forwards)
 - Backward to /usr/bin/playerctl position -5 (to skip 5 seconds backwards)
 - Next (track) to /usr/bin/playerctl next
 - Previous (track) to /usr/bin/playerctl previous

As I am writing this, this works for at least Firefox in Linux Mint 20.3, Cinnamon desktop.  I have a hidden window with a Youtube video playing, and playerctl play-pause will correctly play and pause it.
 
The following users thanked this post: RoGeorge

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6176
  • Country: ro
Re: IR remote receiver for Linux
« Reply #27 on: January 07, 2023, 03:53:40 pm »
Indeed, playerctl does the expected job nope, when the player is not specified, plyerctl sends the commands to the first player seen (in alphabetical order  :palm:).  Well, at least it can be easily scripted to interface with whatever IR remote solution.

(Not very sure about this, but it seems mplayer is to control MPRIS compliant players through dbus ;D - though my Kubuntu has systemd anyways, not a problem for my current setup)
« Last Edit: January 07, 2023, 04:59:33 pm by RoGeorge »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3892
  • Country: gb
Re: IR remote receiver for Linux
« Reply #28 on: January 07, 2023, 05:06:18 pm »
(I seriously dislike dbus stuff, you see)

(me too
if entropy plays a role
dbus is a chaos agent)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #29 on: January 07, 2023, 05:44:36 pm »
Indeed, playerctl does the expected job nope, when the player is not specified, plyerctl sends the commands to the first player seen (in alphabetical order  :palm:).
Care to try later versions that have the playerctld daemon?

In your X session, you start the daemon using 'playerctld daemon', and it should monitor the active players as you describe, so that playerctl directs the commands to the "proper" application.  Or that's what the GitHub page says.  It does have quite a few issues, so one might wish to check the issue tracker first whether it is worth pursuing further.

My own solution approach would differ: I'd use the X11 approach, mapping windows to audio sources, and use X11 events rather than dbus events to control the players.  But that's just me.
 

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6176
  • Country: ro
Re: IR remote receiver for Linux
« Reply #30 on: January 07, 2023, 06:45:45 pm »
Meanwhile found out it needs the daemon playerctld, indeed, to keep track of the last player, just that I wanted to test it before posting it works OK when the daemon is started, and been delayed because I didn't know how to properly enable the service to start automatically.

Followed the Arch wiki https://wiki.archlinux.org/title/MPRIS "In order to start playerctld when you log in, you may create the following systemd/User service:" then enabled the service with systemctl --user enable playerctld.service.

Great, playerctld behaves just as expected, thank you.  :-+

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3892
  • Country: gb
Re: IR remote receiver for Linux
« Reply #31 on: January 07, 2023, 07:09:56 pm »
My own solution approach would differ: I'd use the X11 approach, mapping windows to audio sources, and use X11 events rather than dbus events to control the players.  But that's just me.

I have completely removed dbus from the last stage4's PowerPC GNU/Linux profile.
So none of the libraries and applications are compiled with dbus support.

Can you tell more about your approach? It's *exactly* what I'd like to do  :D
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #32 on: January 07, 2023, 07:48:07 pm »
Can you tell more about your [X11] approach?
A simple X11 application as I outlined in #25, using XGrabKey() to grab the multimedia keys (and optionally read remote commands from a serial port and/or socket), and redirect/synthesize them to specific windows using XSendEvent() (mapping to whatever keypresses one might want, although mpv and vlc at least do support the multimedia keys by default).

It does need to be tied in to the audio system also, to track which applications are generating sound.  Exactly how to do that, depends on what audio subsystem you're using.  Just monitoring which window has had focus last, is probably not going to cut it, you see.  X11 itself has no audio support at all.
Which one are you using?

Simply put, the X11 application needs to map windows to process ID's (PIDs), and processes or windows to audio streams.  Many non-player applications can produce sounds, like various alarms and dings, so I'd also use both executable name and window title (via POSIX regular expressions, regcomp() and regexec()) to determine which ones are "players".  I'm pretty sure I'd write it in two parts, so that one part is the UI that only runs when one configures it, and the other part is the "daemon" part (that really only needs to run in your X session; see your Autostart session configuration).

Unless the audio daemon already provides an interface to list currently active clients (and their PIDs or X11 window IDs), one way is to monitor which processes connect to it via local sockets (/proc/PID/fd/N in Linux).  I do know PulseAudio does (see e.g. pactl list clients), I do believe GStreamer and others do as well.  Even applications directly using the OSS device nodes can be tracked.

For those using various phone apps, it might be useful to add support to auto-pause current player if a specific application generates audio –– say, Skype ringing would auto-pause your media playback, and so on.
« Last Edit: January 07, 2023, 07:50:16 pm by Nominal Animal »
 
The following users thanked this post: DiTBho

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6176
  • Country: ro
Re: IR remote receiver for Linux
« Reply #33 on: January 08, 2023, 08:06:43 am »
To add MPRIS (Media Player Remote Interfacing Specification) for MPV and playerctl:
Code: [Select]
sudo apt install mpv-mpris
sudo apt install playerctl

Create a unit file to start the playerctld service.  Without playerctld daemon the MPRIS doesn't know what was the last active player to send further commands to.
Code: [Select]
mkdir -p ~/.config/systemd/user && touch ~/.config/systemd/user/playerctld.service
nano ~/.config/systemd/user/playerctld.service
Add this content to it and save the playerctld.service file
Code: [Select]
[Unit]
Description=Keep track of media player activity

[Service]
Type=oneshot
ExecStart=/usr/bin/playerctld daemon

[Install]
WantedBy=default.target

Start and enable the playerctld.service to auto reload
Code: [Select]
systemctl --user daemon-reload
systemctl --user start playerctld.service
systemctl --user enable playerctld.service



To enable MPRIS for Firefox check this checkbox in Firefox's Settings -> General -> Browser -> Control media via keyboard, headset, or virtual interface Learn more (Mozilla Firefox pages)



Quick note about the setup with LIRC v0.9.0/Xenial, irexec, MPRIS and playerctl.  Won't work with irexec service started as root.  irexec has to be started as --user service, or else playerctl won't see the DBUS session of the current user, and won't be able to talk with MPRIS player.

To fix this I had to
- disable the root irexec.service
Code: [Select]
sudo systemctl stop irexec
sudo systemctl disable irexec

- create a new unit to start irexec as --user service, nano ~/.config/systemd/user/irexec.service with the following content
Code: [Select]
[Unit]
Documentation=man:irexec(1)
Documentation=http://lirc.org/html/configure.html
Documentation=http://lirc.org/html/configure.html#lircrc_format
Description=Handle events from IR remotes decoded by lircd(8)
After=network.target
Wants=lirc.service
Requires=dbus.service

[Service]
Type=simple
ExecStart=/usr/bin/irexec
Restart=on-failure
SuccessExitStatus=3 4
RestartForceExitStatus=3 4

[Install]
WantedBy=default.target

- start irexec with --user and enable it to start automatically (without sudo):
Code: [Select]
systemctl --user daemon-reload
systemctl --user start irexec
systemctl --user enable irexec

- add IR remote buttons associations with playerctl commands nano ~/.lircrc (append the following text to it):
Code: [Select]
##
# playerctl LIRC key bindings
#   send play/pause/next/prev to the last active player
#   require playerctl installed and running playerctld daemon
##

# last active player cycle pause       KEY_PAUSE
begin
        remote = EBODA_DVD_black
        prog   = irexec
        button = KEY_PAUSE
        config = playerctl play-pause
end

# last active player cycle pause       KEY_PLAY
begin
        remote = EBODA_DVD_black
        prog   = irexec
        button = KEY_PLAY
        config = playerctl play-pause
end

# last active player playlist-next     KEY_RIGHT
begin
        remote = EBODA_DVD_black
        prog   = irexec
        button = KEY_RIGHT
        config = playerctl next
end

# last active player playlist-prev     KEY_RIGHT
begin
        remote = EBODA_DVD_black
        prog   = irexec
        button = KEY_LEFT
        config = playerctl previous
end

To restart all, either reboot or
Code: [Select]
sudo systemctl daemon-reload && sudo systemctl restart lirc && systemctl --user daemon-reload && systemctl --user restart irexec && systemctl --user restart playerctld && pulseaudio -k


Been 10+ days since keep configuring LIRC and halfway there already, easy-peasy!  ;D
« Last Edit: January 08, 2023, 10:22:03 am by RoGeorge »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #34 on: January 08, 2023, 09:31:32 am »
Been 10+ days since keep configuring LIRC and halfway there already, easy-peasy!  ;D
Reminds me of how I accidentally found out how to easily configure OpenWRT as a WiFi-Ethernet bridge with dedicated management interface on one local Ethernet interface and an isolated LAN on the rest of the local Ethernet connectors, but forgot to write it up, so afterwards, trying to do it twice, I've just managed to lock myself completely out...  ::)

(The WiFi-Ethernet bridge itself being transparent to the traffic, without an IP address OpenWRT userspace can react to.  The use scenario is such that I have a dedicated 4G/5G/LTE modem and firewall between the router (Asus RT-AC51U running OpenWRT) and the internet, this being a guest/untrusted network segment, for stuff like tablets and browsing and media streamers, relying on just WPA2/WPA3 security for local devices.  The firewall does some fancy IP filtering, based on incoming connection attempts.  The order of creating the management interface and bringing up its IP address, moving the services to that IP address, and then configuring the bridging of the WAN and WiFI is the key, obviously.  But I always seem to get it wrong: I need to type the sequence up first, before I try it the next time...)
 
The following users thanked this post: DiTBho

Online RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 6176
  • Country: ro
Re: IR remote receiver for Linux
« Reply #35 on: January 08, 2023, 10:16:42 am »
That's why I keep posting here my settings, so I won't have to discover all that again at the next install.

Though, now that LIRC v0.9.0 kind of works as expected, I'm tempted to remove it and try to install one more time the current version of LIRC v0.10+, the one with that uses the kernel LIRC features.  ::)

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3892
  • Country: gb
Re: IR remote receiver for Linux
« Reply #36 on: January 08, 2023, 11:12:48 pm »
Which one are you using?

vlc compiled with OSS on SBC#1, and with ALSA support on SBC#2
(PowerPC boards)

OSS is simpler for me to be implemented/hacked/fixed, at kernel side.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3892
  • Country: gb
Re: IR remote receiver for Linux
« Reply #37 on: January 08, 2023, 11:15:58 pm »
I don't have an audio daemon running; OSS/ALSA at the kernel side, and nothing else in userspace, except mpg123 and VLC.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6227
  • Country: fi
    • My home page and email address
Re: IR remote receiver for Linux
« Reply #38 on: January 09, 2023, 01:07:31 pm »
Quote from: DiTBho
[OSS and ALSA, vlc and mpg123]
We'll want to monitor processes having the /dev/dsp (OSS) or /dev/snd/pcm* (ALSA) devices open.  Since we are only interested in a few applications, we can do that by checking their /proc/PID/fd/ (using readlink()/readlinkat()), to determine which one is potentially playing audio.

This will fail for PulseAudio, because it will be the PulseAudio daemon that has the device open.

Could you please check what
    lsof /dev/dsp /dev/snd/pcm*
outputs when you have both vlc and mpg123 running, with a combination of one playing and one paused or stopped?
If only the active one is shown, then the X11 redirector will be very straightforward to implement.

(If you don't have lsof, you can do the same by finding out the PIDs of the two processes, and using ls -l /proc/PID/fd/ or stat -c '%N' /proc/PID/fd/*)

Also, please compare the output to wmctrl -l -p, especially the PIDs in the third column.  I am assuming the PIDs should match.

If you want the same without X, then feeding them the events is a bit more complicated.  The issue is that while we can easily determine the controlling terminal for them, we'd need to find a way to feed additional input to the master side of the terminal –– we can only easily determine the slave side.  If they only used terminal consoles (/dev/ttyN), we could use chvt, but for things like ssh'ing in and playing audio via mpg123, it gets tricky.
I suspect that it would then be easiest to configure the players to accept control from a local socket or named pipe also.
« Last Edit: January 09, 2023, 01:11:00 pm by Nominal Animal »
 
The following users thanked this post: DiTBho


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf