rhysmorgan134 / node-CarPlay

MIT License
131 stars 23 forks source link

Revive node server example #62

Closed steelbrain closed 9 months ago

steelbrain commented 9 months ago

Creating a tracking issue, will open a PR for this.

There are quite a few reasons that have led me down this path. For context, I have a car with an AUX port, and a pop-up nav. That's where I am trying to fit my carplay setup.

While there are quite a few upsides to the web version, for example:

There are also some downsides, which I hit in my usecase

The raspberry pi I used for testing (4; model b) was already not super-fast in comparison to regular in-car infotainment systems, but add on to the fact that you have to wait for the desktop environment to get ready (I was using sway) and then for the browser to load (sway config had exec for chrome), and then for the browser to initialize the dongle, the delay adds up.

In contrast, one can have a simple systemd daemon that starts the node.js dongle server as soon as the device boots up, in parallel to initialization of the dongle

In my usecase, I have quite a few different paths/pages and it is a lot more convinient to have a built carplay and dump it in a folder and navigate to it when you need to show carplay. It is harder to do it in current config because the dongle gets reset/loses state when you navigate away.

This requires all the other infotainment code to be written in the same repository as the dongle handler, and makes mixing and matching much less practical.

While 3.5mm jack works okay for audio output, audio input on the pi is a bit tricky. I wanted to use a USB audio device to handle input, while having some usb capture cards attached that handle reverse and forward cameras, (and I tested many audio usb dongles from different brands, not sure if with different underlying chipsets) and it was an utterly tiresome, frustrating experience that made me finally understand "At least my macOS has working audio lolx" memes I see all around the internet

I mainly used Raspbian bullseye for my testing, and during testing, Alsa devices would get a random index each time so you couldn't rely on the config to have the same effect each time, disabling/blocklisting some USB devices from audio recording while allowing others was also buggy, even if you got everything right there would just be no sound. So after wasting a few days on it, I just gave up.

My current solution (not yet implemented) is to use a USB Bluetooth to Aux adapter (like this; non-affiliate link). Then I can configure the audio output to box in the carplay dongle config and just offload the entire audio problem to dedicated hardware that works reliably well.

This is not directly related to the web version but just noting a frustration of the platform/environment itself.


With the node version, the idea is to resurrent the PR from old, and yank out the audio (since it'll be going to dongle) and publishing it in case people want to use it.

Is there any interest in this @gozmanyoni @rhysmorgan134?

Edit: Could be interesting to create a bun executable of the node version: https://bun.sh/docs/bundler/executables

rhysmorgan134 commented 9 months ago

Definitely some interest from me. I did have a good stab at making one to use with electron. I got quite far, video worked well, relaying messages from node over electronIPC. However I really struggled with getting the audio quality where it needed to be. This is likely down to me rather than the code itself, but odd nontheless that video worked great still. I also quite like the seperation of the dongle driver to the front end for the exact same reasons you have mentioned around navigation etc.

In the end I managed to get the web version to play nicely with all the electron quirks, and it is actually really smooth and just works. So I think for now I am going to see how I can implement like this without the need for the node version. I am going to give Yoni's suggestion a go and see if I can store the carplay instance at the top level and deterministicly trickle down the messages based on page being viewed, however I do think there's a possibility of creating a store that contains the carplay instance and various components can subscribe to it.

Either way the node version certainly has interest from me!

gozmanyoni commented 9 months ago

@steelbrain I think this is very much needed - this is why the package has node/web versions.

We don't have to be tied to a web browser at all and this simply allows for greater flexibility and larger array of use-cases. - we could also ditch jmuxer and use WebRTC (perhaps gain some performance as well, as chrome will be handling raw h264 data and decoding it without any need for muxing, I suspect it also uses a separate thread for that)

With the web version I wanted to see how far I can push a modern fully web-browser implementation and it ended up being pretty successful, I learned a lot - and for a standalone App, or a SPA that starts the worker and always keeps it running the web version is not bad at all (Pi boot times can be optimized (SSD, removing modules that we don't need/want), and it can be woken up on CAN messages as the car is unlocked, rather than waiting for it to start the engine/ignition on - This is what my E90 BMW does to make sure infotainment is ready when i sit in the car).

Also - curious to see how this all works on the newly announced Pi 5 🥳

steelbrain commented 9 months ago

@gozmanyoni That would be quite interesting. I had looked into wrtc before (https://github.com/node-webrtc/node-webrtc) but it's no longer maintained and lost hope. I just discovered https://github.com/murat-dogan/node-datachannel however which does look maintained and looks like it could do the job

gozmanyoni commented 9 months ago

@steelbrain found this golang implementation which does not seem active but is sending h264 via webRTC https://github.com/mzyy94/gocarplay

steelbrain commented 9 months ago

Seems like there are problems no matter where you go: https://github.com/mzyy94/gocarplay/issues/2#issuecomment-1005571525

gozmanyoni commented 9 months ago

Yeah I read the code a bit - It does not handle key frame requests, or efficiently play audio, so these may be non-issue for this implementation

steelbrain commented 9 months ago

Offtopic // @gozmanyoni Is there a prebuilt HAT or something custom made that you're using for power management for your car? I'm looking for something similar and would welcome any suggestions. I've seen CarPiHAT but it looks overkill and there's probably gonna be fitment issues for me

gozmanyoni commented 9 months ago

@steelbrain I am actually not using it in the car yet, still on a test bench or occasionally connected to the car for testing and diagnostics.

I have the PiMOST HAT (made by Rhys) which I use to send audio to the cars amp, it also detects the bus traffic stops, triggering a sleep command, I wonder if it can also wake it up when traffic begins? @rhysmorgan134 I believe has a bunch of Pi's active in vehicles and can give much better advice!

rhysmorgan134 commented 9 months ago

@gozmanyoni Yeah you are correct it will wake up and sleep based on Most network. Idle current will largely depend on the 12v-5v step down converter, but using the unreleased 12v pimost it is ~0.5ma.

@steelbrain For my two cars though before the pimost, I have just never worried about it and just cut the power with the ignition. I have run pi's in two cars for around 3 years and have never had an SD card corrupt, maybe running an electron app mainly runs in RAM, as I understand it, it's only writes the file system that have the potential to corrupt it, either way it hasn't happened to me.

Apparently from my research the new pi is likely to support more sleep modes, so potentially we can sleep/hibernate, power consumption needs more research.

Tigo2000 commented 9 months ago

@steelbrain The creator of volvo-rtvi, LRYMND, was also looking for a way to power the pi and shut it down in a safe way, he found this: https://dontpressthat.wordpress.com/2017/10/13/in-car-raspberry-pi-psu-controller/

In short when ignition goes low, a shutdown command is issued to the pi. Once the pi is completely shutdown, the circuit will cut (pretty much) all power to the pi.

The board was modified slightly (by LRYMND and me) to also accommodate a LIN-transceiver which can be used to read (volvo) steering wheel controls. I have quite a few boards left over, shoot me a message if you want a pcb as well.

PCB_PSU_LIN_2023-01-12

steelbrain commented 9 months ago

@Tigo2000 Thank you for sharing that. My circuit design skills are pretty limited so I do appreciate anything prebuilt I can get my hands on. I'll reach out to you on Discord