Jump to content

Trying to write my first Plug WakeOnAccess


Jack187

Recommended Posts

Jack187

Hello everybody,

 

I'm new to emby and I want to write my first plugin, because I was looking for a functionality that the emby server doesn't seem to provide out of the box.

 

I have the following constellation:

One server acts a a Sat server and emby server. This server is always on.

Besides of that, I have a second server that acts as a NAS. Because of the high power consumption (120W idle), this NAS is usually in standby (maybe 22h a day).

 

 

What I want to achieve is that as soon as a client requests a video, my plugin should wake the NAS via wake on lan.

I allready have a basic plugin (from the wiki) up and running. I was also able to attach to the playback started event.

So when the NAS is up an running and a client (e.g. in chrome) requests playback of a movie, then my plugin gets called when playback starts and writes a message to the logfile that I can see afterwards. But unfortunately that's too late, because if the NAS is in standby playback can't start.

 

 

It would be great if anyone could point me in the right direction, what I have to do to be called as soon as the user hits the Play button, that I'm able to check if the NAS is up and if not to wake it via wake on lan.

 

Thank you!

 

Regards

Jack

Edited by Jack187
Link to comment
Share on other sites

chef

Would it be better to use the session events to wake the NAS. When a session starts, look to see if the NAS is up.

Link to comment
Share on other sites

Jack187

Hi chef,

 

thank you for your reply :) ! 

When I understood your suggestion right, the wake up signal will then be send as soon as the user logs in (or new session is started). I thought about that, too. But I don't want always start playing a movie when I start a session. Often I just want to watch Live-TV, which is also served completly on the emby server (sat server)...

 

Or did I get something wrong? Perhaps you or someone else have another approach?

 

Regards

Jack

Link to comment
Share on other sites

chef

Yeah, that was suggestion. Tying into playback commands will be troublesome like you say.

 

There is just not enough time to wake up the NAS before playback attempts to start and you'll most likely get an error.

 

In a standalone app, not a plugin, there are browsing events.

There are ways in a standalone app, that could wake up the NAS when you browse into a library which contains media items on the NAS.

 

That might be possible... But it wouldn't be a plugin. It would also need login authentication (the standalone app).

Link to comment
Share on other sites

Jack187

Thx again for your reply!

 

Hmm... that sounds not that good. I thought this would be an easy task :-).

 

@@Luke

Can you tell me if you think to add this as a feature in future? If you could help me a little, I'm happy to contribute to this feature.

 

Regards

Michael

Link to comment
Share on other sites

chef

Well, you could poll the server with a threading timer...

 

How much power do you have on your sat machine?

 

Start the timer with session started event and poll session info NowViewing Item.

 

But, again, not good to continuously make calls to the API... Lol

 

I'm just full of bad ideas...

Link to comment
Share on other sites

Just an fyi, I don't think you'll be able to do this as a plugin because you're not going to find out about playback until it has already started.

Link to comment
Share on other sites

  • 2 weeks later...
Jack187

Sry for the delay... but time is always a problem :-)

 

I forked eht emby repo and had a look into the source code. For testin purposes I added my wake on lan code into the GetPlaybackInfo method (changes starting in Line 216).

It's working somehow, but it takes two times hitting the Play Button. 

private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId, string[] supportedLiveMediaTypes, string mediaSourceId = null, string liveStreamId = null)
        {
            var result = new PlaybackInfoResponse();

            if (string.IsNullOrWhiteSpace(liveStreamId))
            {
                IEnumerable<MediaSourceInfo> mediaSources;
                try
                {
                    mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, supportedLiveMediaTypes, CancellationToken.None).ConfigureAwait(false);
                }
                catch (PlaybackException ex)
                {
                    mediaSources = new List<MediaSourceInfo>();
                    result.ErrorCode = ex.ErrorCode;
                }

                result.MediaSources = mediaSources.ToList();

                if (!string.IsNullOrWhiteSpace(mediaSourceId))
                {
                    result.MediaSources = result.MediaSources
                        .Where(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase))
                        .ToList();
                }
            }
            else
            {
                var mediaSource = await _mediaSourceManager.GetLiveStream(liveStreamId, CancellationToken.None).ConfigureAwait(false);

                result.MediaSources = new List<MediaSourceInfo> { mediaSource };
            }

            if (result.MediaSources.Count == 0)
            {
                if (!result.ErrorCode.HasValue)
                {
                    result.ErrorCode = PlaybackErrorCode.NoCompatibleStream;
                }
            }
            else
            {
                foreach(var mediaSource in result.MediaSources.Where(msi => !File.Exists(msi.Path)))
                {
                    byte[] mac = new byte[] { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; // NAS Mac
                    
                    // path doesn't exist - try wake up
                    WakeOnLan(mac);

                    // give server time to wake up
                    int oneSecond = 1000;
                    int timeout = 30 * oneSecond; //30 sec
                    int elapsed = 0;
                    while(!File.Exists(mediaSource.Path) && elapsed <= timeout)
                    {
                        elapsed += oneSecond;
                    }                    
                }
                result.PlaySessionId = Guid.NewGuid().ToString("N");
            }

            return result;
        }

Because I don't know how much time it does take to bring this to a proper solution for the product, I think I'll try the approach of chef to start my NAS when a new session is started. 

 

@Luke:

Or do you think that this functionality could be added to the emby server without much effort. I would like to help if you could give me advice on where to add what to keep your achitecture clean.

 

Regards

Jack

Edited by Jack187
Link to comment
Share on other sites

There are more places that would have to wake the nas, and not only that but figure out the right nas based on the file path required. and then we would need a friendly place where users can enter the wake on lan info. so there's some work required here.

Link to comment
Share on other sites

MikePlanet

+1 - really interested to get this available, as this is a setup I know for several people.

So what would be needed:

- A config for 1...n NAS devices - they could be populated automagically by pulling the server names from the media pathes from the library. MAC adresses could also be pulled automatically, if the NAS is online, a refresh button might be good to get MAC addresses at a later point (when NAS was offline when initial activation of the feature was done)

- playback methods need to get the required server from the media path and check, if the path is online - if not, send magic packet to wake up and wait until it is online, then start playback

- library updater also needs a small update - as the setup will have sleeping NAS during the scans, the user must be able to select, if the missing mediapathes should be deleted from library - or ignored, if the respective NAS device if offline (again, the online state has to be checked and known internally to act accordingly)

- Maybe a hint, that using sleep for NAS devices should not be used together with storing metadata in the media directory - if that is done, a wakeup would also be needed for simple GUI browsing, as otherwise metadate is not available (imho sleeping devices should only be used with emby storing metadata locally)

Edit: would also be nice to inform the user, that the server is waiting for the remote storage to become available (instead of just doing 10 seonds nothing)

Edited by MikePlanet
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...