Jump to content

Recommended Posts

crusher11
Posted

I just added some Philips Hue lights to my theater, and got Home Assistant set up on the NAS which runs my Emby server. I've added Emby to Home Assistant via editing config.yaml, which is apparently the only way you can do that, but...now what? The Webhooks page lets me send something to a URL, but I have no idea what the URL is supposed to be or how to receive that URL and act on it.

Posted

Sorry, I don't know but sure am interested!

BillOatman
Posted (edited)
6 hours ago, crusher11 said:

I just added some Philips Hue lights to my theater, and got Home Assistant set up on the NAS which runs my Emby server. I've added Emby to Home Assistant via editing config.yaml, which is apparently the only way you can do that, but...now what? The Webhooks page lets me send something to a URL, but I have no idea what the URL is supposed to be or how to receive that URL and act on it.

This exists in the plugins catalog.  Though I have not tried it in quite some time. It is open source as well.
https://github.com/chefbennyj1/Emby.PhillipsHue

image.png.b583c22d21d857a51c3d5ce0e0b78939.png

Edited by BillOatman
seanbuff
Posted
10 hours ago, crusher11 said:

The Webhooks page lets me send something to a URL, but I have no idea what the URL is supposed to be or how to receive that URL and act on it.

First generate the Webhook URL using the instructions I posted here:

Just make sure the "Action" is to control the Hue lights accordingly, rather than send a notification like my example.


Then in Emby use the above URL to send a webhook to on a specific Emby event, i.e. Playback

image.png.911042a7f6b4a6a44297ab4d97f3b6ab.png

image.png.0c25ede40b0945e48e2cd5a8085af22c.png

Do the reverse to bring the lights back up on Pause and Stop triggers.

crusher11
Posted

Okay, I've got that working.

Now, how do I access what's actually in the JSON? Trying to perform an action if the filename is a partial match to a string.

seanbuff
Posted
13 hours ago, crusher11 said:

Now, how do I access what's actually in the JSON? Trying to perform an action if the filename is a partial match to a string.

Does it have to be the filename specifically? Otherwise you can use anything that Emby sends in the JSON payload.

Is this still for your projector adjustments based on aspect ratio? Anyway...

To use your "filename" example. Let's say you wanted to know if the filename had the word '2160p' in it.

BTW, you can look at the full JSON payload by checking out the 'Changed Variables' when you look at the 'Traces' of your HA automation

image.png.003e0cb4a2dde227f6bbee7d7cc496f8.png

You would create a simple Automation with the Webhook as the "When" trigger, and then you could add some "And If" conditions at that point if you wanted.
Or alternatively, for the "Then do" action, select an "If-then" action by clicking "Add Building Block"

For the "IF" condition, you would use a Template, and use something like this:

{{ '2160p' in trigger.json.Item.FileName }}

note the JSON nested structure to get to the FileName (it's also case-sensitive)

Add the appropriate action in the "Then" field and optionally something else for the "Else"

This is what my basic test automation looks like, it simply gets the Playback event from Emby and checks the filename for '2160p', if it detects it, it sends my phone a message saying "This movie is 4K", and if it doesn't match, then sends me a different message.

image.thumb.png.b149a2647225489938b972a8611e39fa.png

  • Like 1
seanbuff
Posted

Also, if you wanted to pull something from the MediaStreams nested array:

{
...
    "Item": {
...
      "MediaStreams": [
        {
          "Codec": "hevc",
          "ColorTransfer": "smpte2084",
          "ColorPrimaries": "bt2020",
          "ColorSpace": "bt2020nc",
          "TimeBase": "1/1000",
          "VideoRange": "HDR 10",
          "DisplayTitle": "4K HDR 10 HEVC",
          "IsInterlaced": false,
          "BitRate": 9317542,
          "BitDepth": 10,
          "RefFrames": 1,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Height": 2076,
          "Width": 3840,
          "AverageFrameRate": 23.976025,
          "RealFrameRate": 23.976025,
          "Profile": "Main 10",
          "Type": "Video",
          "AspectRatio": "320:173",
          "Index": 0,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "PixelFormat": "yuv420p10le",
          "Level": 150,
          "IsAnamorphic": false,
          "ExtendedVideoType": "Hdr10",
          "ExtendedVideoSubType": "Hdr10",
          "ExtendedVideoSubTypeDescription": "HDR 10",
          "AttachmentSize": 0
        },
        {
          "Codec": "ac3",
          "Language": "eng",
          "TimeBase": "1/1000",
          "DisplayTitle": "English AC3 5.1 (Default)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "ChannelLayout": "5.1",
          "BitRate": 512000,
          "Channels": 6,
          "SampleRate": 48000,
          "IsDefault": true,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Audio",
          "Index": 1,
          "IsExternal": false,
          "IsTextSubtitleStream": false,
          "SupportsExternalStream": false,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0
        },
        {
          "Codec": "subrip",
          "Language": "eng",
          "TimeBase": "1/1000",
          "DisplayTitle": "English (SUBRIP)",
          "DisplayLanguage": "English",
          "IsInterlaced": false,
          "IsDefault": false,
          "IsForced": false,
          "IsHearingImpaired": false,
          "Type": "Subtitle",
          "Index": 2,
          "IsExternal": false,
          "IsTextSubtitleStream": true,
          "SupportsExternalStream": true,
          "Protocol": "File",
          "ExtendedVideoType": "None",
          "ExtendedVideoSubType": "None",
          "ExtendedVideoSubTypeDescription": "None",
          "AttachmentSize": 0,
          "SubtitleLocationType": "InternalStream"
        },
      ]

You would need to define the index list within the array (it's zero based index)

So if you wanted to return the "Aspect Ratio" which is in the first list of the array, you would use:

The aspect ratio is '{{ trigger.json.Item.MediaStreams[0].AspectRatio }}'


However, if you wanted to return the "SubtitleLocationType" which is in the last list, you would use:

The subtitle is an '{{ trigger.json.Item.MediaStreams[2].SubtitleLocationType }}'

 

  • Like 2
crusher11
Posted (edited)

Yep, I got there in the end - it was the nesting that was tripping me up at first, but it also seems that Emby sends the 1080p filename irrespective of which file is playing, which is not great.

But I switched over to the color primaries, which broke it all again until I figured out the array thing, and now it...kind of works?

I'm telling it to pause playback, wait five seconds if it's bt2020 and three seconds if it isn't, then resume playback. I'm doing this via EmbyCon. Basically, I'm allowing the HDMI handshake and projector WCG filter (if applicable) to sort themselves out, then starting the movie. The times are arbitrary right now, as I'm testing on a TV - my theater is going through fitout at the moment so I don't have access to the projector. But I can sort that out later.

It pauses just fine. It refuses to resume. The "choose" action is working perfectly, I can follow it in Traces and it makes the right decision, and the "pause" command is getting through but I don't understand why the "play" one isn't. Traces says it's happening, and I've tried both "play" and "toggle play/pause," to no avail.

It also takes an extra second to pause when playing HDR, which defeats the purpose of the exercise...

 

Here's the code:

- id: '############'
  alias: Emby UGOOS Wait
  description: ''
  triggers:
  - trigger: webhook
    allowed_methods:
    - POST
    - PUT
    local_only: true
    webhook_id: lorem_ipsum
  conditions: []
  actions:
  - action: media_player.media_pause
    metadata: {}
    data: {}
    target:
      entity_id: media_player.emby_embycon
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.json.Item.MediaStreams[0].ColorPrimaries == "bt2020"
          }}'
      sequence:
      - delay:
          hours: 0
          minutes: 0
          seconds: 5
          milliseconds: 0
    default:
    - delay:
        hours: 0
        minutes: 0
        seconds: 3
        milliseconds: 0
  - action: media_player.media_play
    metadata: {}

 

 

EDIT: I added a "Stop" command after the "Play" command, like so:

  actions:
  - action: media_player.media_pause
    metadata: {}
    data: {}
    target:
      entity_id: media_player.emby_embycon
  - choose:
    - conditions:
      - condition: template
        value_template: '{{ trigger.json.Item.MediaStreams[0].ColorPrimaries == "bt2020"
          }}'
      sequence:
      - delay:
          hours: 0
          minutes: 0
          seconds: 5
          milliseconds: 0
    default:
    - delay:
        hours: 0
        minutes: 0
        seconds: 3
        milliseconds: 0
  - action: media_player.media_play
    metadata: {}
    data: {}
    target:
      entity_id: media_player.emby_embycon
  - action: media_player.media_stop
    metadata: {}
    data: {}
    target:
      entity_id: media_player.emby_embycon
  mode: single

And now it just stops, immediately. So it appears the delay isn't properly firing either, even though Traces says it's all working perfectly.

Edited by crusher11
crusher11
Posted

Well I was wrong about it taking an extra second to pause HDR: it's now taking an extra second to pause anything. It just paused instantly one time on a non-HDR source, but that hasn't repeated.

I've set the same thing up on the Shield, and that's not working at all. The mini-OSD is displayed at the start of playback, which implies some commands are being sent that are activating it, but it just plays as normal, there's no pause at the start.

crusher11
Posted

Having sat there and watched entity states for EmbyCon, Emby Shield, and Android TV:

All three shift from "idle" to "playing" basically as soon as I hit the button, before the media has actually loaded.
EmbyCon shifts from "playing" to "paused" before the video has loaded. The video then plays for a second, and pauses. It gets stuck there.
Emby Shield shifts from "playing" to "paused" before the video has loaded. The video starts playing, and then shortly thereafter the Shield shifts from "paused" to "playing."
Android TV doesn't shift to "playing" until well into the video. It never pauses.

If I switch the "play" and "pause" commands from the Android TV to the Emby Shield, then none of the commands get passed at all. If I set up a dashboard button to pause the Shield, it works fine.

I am, needless to say, very confused.

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...