That Marc
That Marc

Reputation: 1224

Media player as windows service

I've been looking for info for a while now but haven't been able to find anything useful for us. We're building kind of a SmartCar complex system, which controls more or less everything in a car.. Its a dev project, nothing "reinventing the wheel" here, just the point of doing it completely from the scratch.

Since it's going to have quite a heavy load, we built a PC based on i5 proc with 8GB of ram, running Windows Server 2012 Datacenter on Intel's S335 SSD hard drive.

So far so good, the main controllers are running as services and all respond well for operations such as lock/unlock, side mirrors movement, windows movement, complete climatronic control, ignition, lights etc... However, we kinda can't get to play a sound from it...

The reason we use all as services is because it has no monitor at all, but rather communicate via WiFi and 3G with Android tablet and phone, and Windows tablet as well. We've tried doing it via remote desktop connection, but it's waste of resources on both sides, so we rather use Tcp/ip client/server version. Also, since it needs to hibernate/shutdown in order not to waste energy resources, instant power on is vital, and without a need to log in it all works within a few seconds, which is perfect.

So, my question here is, how could I make a music player to run as a service and play audio files, which we select via our remore app? The remote part is not an issue here, but rather the player part. I've tried several delphi demo music player example codes transformed into services, but nome of them played the sound. I guess it has something to do with services not being normally allowed to interact directly with user interface, but I know it's possible, just dont have a clue on how.

Also, I guess its not possible, but still worth asking: if we'd want to extend it to use as a video player as well, could this be done without any user logged in? Such as having vga/dvi video monitor connected, but to only show a video when it's selected to be played? (the monitor would be as extended monitor in this case, so that no login sceen would ever be shown).

I make all of the services in Delphi. Any info would be appreciated. Thanks.

Upvotes: 1

Views: 1231

Answers (3)

Roman Ryltsov
Roman Ryltsov

Reputation: 69706

Audio APIs work well from a service (just to make sure because there is some confusing around: by service I mean user mode service process, which has nothing to do with kernel mode driver), just the same way they do it on interactive session. Specifically, you can open default endpoint device for audio rendering (IMMDeviceEnumerator::GetDefaultAudioEndpoint, IAudioClient::Initialize) and send data for playback (IAudioRenderClient::GetBuffer). I don't expect other APIs like DirectShow to be limited in part of audio output from service.

There is a different story with video devices: standard video rendering eventually takes place on desktop, where you service does not have access to. To have desktop video on system running without explicit user logon, you might prefer to design a regular app and set Windows to auto-logon and auto-start your application. If you however prefer to use a sort of external video output (HDMI video output on Intensity Pro board - just an example), this should be working from service - no desktop needed for this video output.

To control a service application you are to implement something to accept external commands. This can be a web server or otherwise something listening on a socket and responding to incoming data. If you want to control the service from another process, such as interactive, you can simply put a COM interface on Running Object Table from the service and then grab it from the application to call its methods.

Update: Here is some sample code proving audio operation from service. It works under assumption that default mixing format is 32-bit float audio and emits five seconds of high frequency signal to default audio output device.

  • PlayService.exe /regserver - registers to run as app
  • cscript PlayService_Play.js - starts code within .exe and plays sound
  • PlayService.exe /service - re-registers to run as service
  • cscript PlayService_Play.js - plays the same sound from service
  • PlayService.exe /unregserver - unregisters and cleans things up

This code block shows API used (C++ code).

Upvotes: 3

haz
haz

Reputation: 116

Windows Embedded Automotive 7 provides Audio and Video support and can be deployed on x86 or ARM

Upvotes: 3

mg30rg
mg30rg

Reputation: 1349

I know a solution to both your problems, but it is somewhat nasty. (At this point I would like to point out, that for starters, I would not do what I'm suggesting here, only no more viable solutions were provided. No "This is a terrible suggestion" comments required - I already know that.)


About my solution: If you wish to use audio- or video devices to work outside the user interface, it can be realised by custom-built kernel mode drivers. Kernel mode drivers can communicate directly with windows services and have access to all hardware components in your device. However if you wish to utilise such solution you will have to deal with some caveeats:

  • You can't use Pascal for creating a Windows driver (at least not a reliable one, there might be opensource DDK's based on Pascal, but I don't know about any). If you wish to create a windows driver, you will have to use WDK (practically together with a powerful IDE like MSVS).
  • You will have limited access to the software environment of your computer. (Harder to read registry, more complex memory reservation etc.)
  • Writing a windows driver is a hell of a job. I did that a few times, and I would not wish it for my sworn enemies. (There are pointless conventions, outdated datatypes, underdocumented functionality... and so on.)
  • There are no huge component and API libraries to help you create your driver. On ring 0 you are almost completely on your own.
  • If a windows kernel driver is buggy, it won't throw an exception or fail gracefully. It will create a BSOD error and you have to reset your system to gain control over it again.

Update:

  • One of my friends in the open-source industry told me, that there is a way to target kernel mode drivers with project Lazarus.
  • Some further research showed maybe a filter-driver might also help the OP with his troubles. (And filter-drivers don't exist in ring-0.)

Upvotes: 1

Related Questions