Customized Displays: OK to share?

To be fair to Roon, this is in the Tinkering section, for a feature that isn’t designed to be tinkered with from the GUI by the user.

I wasn’t getting at roon, I was getting at the entire Universe :wink:

3 Likes

This isn’t the future I ordered…

Sheldon

1 Like

I’m runnning a ‘MOCK’ instead of ROCK so that my core can also act as a display. This is working great and I have no issues with the display itself working. I can’t seem to find where it’s storing the HTML file for it to be handling the display. I understand with the ROCK installation that it does not build the file because it’s not meant as an output implementation. However mine is outputting a display so it must be drawing from a file somewhere.

I have searched all files (while the display is up showing playing content even) but still not seeing what it’s drawing from. I am using Qutebrowser and can view the page source and clearly shows the default display_ui.html contents. I’m wondering if there is a way to have a browser show me the file path for that HTML code to find it. Can anyone provide any guidance?

I’ve searched all directories from Windows (via Samba) and have used grep for various strings that are contained in the name and contents of the file to no avail. There’s got to be a file the core is using to serve the display.

You can’t get at it on a ROCK over Samba since the Roon program files aren’t exposed over Samba.

If you have Roon installed on a desktop computer, you can get at a copy of the webroot contents there (I gave the path in a post earlier in this thread), make a copy, and serve it from a webserver running on a machine on your network (or someplace else, I suppose). You may need to hardcode the IP and port of the core, as shown in the line 1095 diff from my post of July 10, 2019. (Note that just changing the contents of the webroot directory on your desktop won’t do anything, since nothing’s using that copy in a situation where that machine is not your core.)

And remember: don’t ask Roon for support if it breaks! This is way into “probably shouldn’t work as well as it does and could get broken at any time by a Roon update” territory. :slight_smile:

Thanks @Joe_Gratz for the information about how to adapt the display_ui.html and display_ui.js, which I have been able to do on my Mac, producing this - a more minimal display which strips out the artist image, lyrics, and progress bar/time:

I would like to be able to add more tags to the display. I managed to add the album tag, by looking at the diff you shared, but I am not sure how to add other tags (I would like to also add year of release and record label tags). It looks like it was easy to add the album tag as this is displayed on the Roon Playing Now screen - is this right? Either way, I am clueless as to how to pull in the other tags!

I would like variable height linecontainer class divs - i.e. the height adjusts depending on how many lines of text show in the div (I currently have the divs set to use a maximum of 3 lines) - but it looks like I have to set a fixed height for these divs, as they have the position:absolute value in order to handle the transition of text. Is this so, and if so, is there a workaround?

Finally, the standard Roon ‘Now Playing’ view is now able to pull in album art from the album folder that local files are stored in and I have multiple artwork in most of my album folders. Do you know how to also pull this artwork into the HTML page in order to create a slideshow, like on the Now Playing view? I would like to have all artwork displayed, not just the cover art.

If anyone can help with any of the above, I’d be glad to hear from you!

Thanks,

Nick

The “now playing” information provided by the API does not include metadata other than the three-line display you’re already using, and it only supplies one “now playing” image. That’s documented here: https://roonlabs.github.io/node-roon-api/Zone.html .

If you wanted to add artist images, it looks like there’s an undocumented “artist_image_keys” property available in the “now playing” information.

Thanks Joe. I have already stripped out the artist image from the web display, as I’m not so keen on that. It’s the folder images that I’m after. I will post a feature request to get this added (seems like a small step as Roon have already implemented a slideshow built from folder images in the Playing Now view in the Roon app).

It may be that there’s another way I can achieve the slideshow by adding some custom JS that would build the slideshow from a folder path built from the performer and album tags, but this would be a pretty steep learning curve for me!

I’ll also ask Roon for more tags to be available to the web display. I’ve seen quite a few requests for this across the forum.

Appreciate your response Joe.

I ended up finding the files on my ‘MOCK’ on Ubuntu Server. Turns out I just needed to know what I was doing a bit more to find the files. For me the webroot folder is located under \opt\RoonServer\Appliance\

Seems so obvious in retrospect, but for whatever reason I just could not find that folder or the webroot contents until I decided to take another crack at it this week.

With some help from all of the posts here I’ve come up with this:

Slightly modified the index.html page as well:

Thanks to Joe_Gratz for the all of the information you’ve posted!

2 Likes

I think it looks great and its something that should be available in the product.
I tried to apply the non-unified diff as a patch on the display_ui.html on a copied version of the file.
Didnt work out too well:

root@scarpe:~# patch display_ui.html display_ui.html.diff
patching file display_ui.html
Hunk #4 succeeded at 255 (offset 236 lines).
Hunk #5 succeeded at 278 (offset 249 lines).
Hunk #6 succeeded at 286 (offset 249 lines).
Hunk #7 succeeded at 287 (offset 249 lines).
Hunk #8 succeeded at 297 (offset 249 lines).
Hunk #9 FAILED at 74.
Hunk #10 succeeded at 337 (offset 249 lines).
Hunk #11 succeeded at 341 (offset 249 lines).
Hunk #12 succeeded at 348 (offset 249 lines).
Hunk #13 succeeded at 351 (offset 249 lines).
Hunk #14 succeeded at 359 (offset 249 lines).
Hunk #15 succeeded at 365 (offset 249 lines).
Hunk #16 succeeded at 376 (offset 249 lines).
Hunk #17 FAILED at 133.
Hunk #18 succeeded at 389 (offset 249 lines).
Hunk #19 succeeded at 397 (offset 249 lines).
Hunk #20 succeeded at 399 (offset 249 lines).
Hunk #21 succeeded at 401 (offset 249 lines).
Hunk #22 succeeded at 407 (offset 249 lines).
Hunk #23 succeeded at 411 (offset 249 lines).
Hunk #24 succeeded at 421 (offset 249 lines).
Hunk #25 succeeded at 423 (offset 249 lines).
Hunk #26 succeeded at 449 (offset 249 lines).
Hunk #27 FAILED at 232.
Hunk #28 succeeded at 496 (offset 250 lines).
Hunk #29 succeeded at 506 (offset 250 lines).
Hunk #30 succeeded at 519 (offset 250 lines).
Hunk #31 succeeded at 524 (offset 250 lines).
3 out of 31 hunks FAILED -- saving rejects to file display_ui.html.rej

Maybe its a version thing.

Yeah, it’s a version thing; Roon updated the display files since last year. Here’s an updated diff of display_ui.html (to the one in 100700667):

2,80d1
< #background-albumart {
<     z-index: 0;
<     width: 100%;
<     height: 100%;
<     top: 0;
<     left: 0;
<     position: fixed;
< }
< 
< #background-albumart div.front,#background-albumart div.back {
<     background-size: cover;
<     background-repeat: no-repeat;
<     background-position: center center;
<     width: 100%;
<     height: 100%;
<     top: 0;
<     left: 0;
<     position: absolute;
<     animation-name: fadein;
<     animation-duration: 1s;
<     transition: opacity 1s linear;
<     will-change: opacity;
< }
< 
< #background-artistart {
<     display: block;
<     z-index: 1;
<     width: 100%;
<     height: 70%;
<     overflow: hidden;
< }
< 
< #background-artistart div {
<     background-size: cover;
<     background-repeat: no-repeat;
<     background-position: center center;
<     width: 100%;
<     height: 70%;
<     position: absolute;
<     top: 0;
<     left: 0;
<     transition: opacity 1s linear;
<     will-change: opacity;
< }
< 
< #background-gradient {
<     background-size: 100% 100%;
<     background-position: left bottom;
<     height: 22vh;
<     visibility: visible;
<     opacity:0;
<     animation-name: fadein;
<     animation-duration: 1s;
<     transition: opacity 1s linear;
<     will-change: opacity;
< }
< 
< #background-dimming {
<     background-size: cover;
<     background-repeat: no-repeat;
<     background-position: center center;
<     background-color: rgba(20,19,19,1); /* #141313, which is the same as the desktop client background dimming layer color */
<     width: 100%;
<     height: 100%;
<     top: 0;
<     left: 0;
<     position: absolute;
<     animation-name: fadein;
<     animation-duration: 1s;
<     transition: opacity 1s linear;
<     will-change: opacity;
<     z-index:2;
<     opacity:0;
< }
< 
< #background-footer {
<     background: linear-gradient(to right, rgba(255, 255, 255, 0.65), rgba(255, 255, 255, 0.4));
<     height: 30%;
< }
94,237d14
< #lyricscontainer {
<     opacity: 0;
<     z-index: 3;
<     width: 100%;
<     height: 70%;
<     position: fixed;
<     top: 0;
<     left: 0;
<     overflow: hidden;
<     transition: opacity 0.7s linear;
< }
< 
< #background-lyrics {
<     display: flex;
<     flex-direction: column;
<     background-color: rgba(0, 0, 0, 0.7);
<     z-index: 1;
<     width: 100%;
<     height: 100%;
<     position: absolute;
<     top: 0;
<     left: 0;
< }
< 
< #lyricscountdown {
<     display: flex;
<     flex-direction: row;
<     justify-content: center;
<     opacity: 0;
<     text-align: center;
<     font-size: 4vw;
<     font-family: "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
<     font-weight: bold;
<     transition: opacity 0.7s linear;
<     will-change: opacity;
< }
< 
< #lyricscountdown > * {
<     margin: 1.4vw;
< }
< 
< #lyricscountdown > span {
<     color: white;
<     opacity: 0.4;
<     transition: opacity 0.2s linear;
<     will-change: opacity;
< }
< 
< #lyricscountdown > span.active {
<     opacity: 1;
< }
< 
< #lyricscountdown.reducedAnimation > span {
<     transition: none;
< }
< 
< #lyricscountdownicon {
<     height: 2.5vw;
<     width: 2.5vw;
<     align-self: center;
<     background-repeat: no-repeat;
<     background-size: contain;
<     background-position: center center;
< }
< 
< #lyricsicon {
<     opacity: 0;
<     height: 2.8vh;
<     width: 2.8vh;
<     z-index: 3;
<     position: absolute;
<     right: 11.2vw;
<     bottom: 32vh;
<     background-repeat: no-repeat;
<     background-size: contain;
<     background-position: right bottom;
<     transition: opacity 1s linear;
< }
< 
< #lyricstextcontainer {
<     background-color: transparent;
<     z-index: 2;
<     width: 100%;
<     height: 100%;
<     position: absolute;
<     -webkit-mask-image: linear-gradient(-180deg, rgba(0,0,0,0.00) 5%, rgba(0,0,0,1) 45%, rgba(0,0,0,1) 55%, rgba(0,0,0,0.00) 85%);
<     mask-image: linear-gradient(-180deg, rgba(0,0,0,0.00) 5%, rgba(0,0,0,1) 45%, rgba(0,0,0,1) 55%, rgba(0,0,0,0.00) 85%);
< }
< 
< #lyricstextcontainer.reducedAlpha {
<     -webkit-mask-image: none;
<     mask-image: none;
< }
< 
< .lyricstext {
<     width: 80%;
<     position: absolute;
<     top: 70vh;
<     left: 10vw;
<     margin: 0px;
<     padding: 0px;
<     color: white;
<     font-size: 3.3vw;
<     font-family: "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
<     line-height: 150%;
<     font-weight: bold;
<     text-align: center;
<     user-select: none;
<     -webkit-user-select: none;
<     -moz-user-select: none;
<     transition: transform 0.7s cubic-bezier(0.70, 0, 0.30, 1);
<     will-change: transform;
< }
< 
< .lyricstext > * {
<     opacity: 0.4;
<     padding: 0px;
<     margin: 3.1vw 0px 3.1vw 0px;
<     transition: transform 0.7s linear, opacity 0.7s linear;
<     will-change: opacity;
<     transform: scale(1); /* Edge won't smoothly transition back to original size without this */
< }
< 
< #lyricstextcontainer.reducedAnimation .lyricstext > * {
<     opacity: 0.1;
< }
< 
< .lyricstext > .current {
<     opacity: 1;
<     transform: scale(1.125);
< }
< 
< #lyricstextcontainer.reducedAnimation .lyricstext > .current {
<     opacity: 1;
< }
< 
< .lyricstext > .prevnext {
<     opacity: 0.6;
< }
< 
< #lyricstextcontainer.reducedAnimation .lyricstext > .prevnext {
<     opacity: 0.4;
< }
< 
239a17
> 	position: fixed;
241,245c19,22
<     width: 22%;
<     height: 39%;
<     left: 10%;
<     bottom: 10%;
<     position: fixed;
---
> 	height: 100%;
>     width: 56%;
> 	top: 0;
> 	left: 0;
252c29
<     background-position: center bottom;
---
>     background-position: left center;
260d36
<     filter: drop-shadow(0px 0px 2.7vh rgba(0, 0, 0, 0.2));
261a38
> 
271,274c48,51
<     top: 70%;
<     left: 34%;
<     bottom: 10%;
<     right: 10%;
---
>     top: 40%;
>     left: 57%;
>     bottom: 40%;
>     right: 1%;
297c74
<     font-family: "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
---
>     font-family: "Helvetica", "Noto Sans", "Noto Sans JP", "Noto Sans KR", sans-serif;
310a88
> 	color: white;
314,315c92,93
<     height: 7vh;
<     top: 2.5%;
---
>     height: 5vh;
>     top: 0px;
321c99,104
<     top: 36%;
---
>     top: 3vh;
> }
> 
> #line3container {
>     height: 5vh;
>     top: 6vh;
323a107
> 
326c110
<     font-size: 5vh;
---
>     font-size: 2.5vh;
332c116,120
<     font-size: 3.5vh;
---
>     font-size: 2.5vh;
> }
> 
> #line3container span {
>     font-size: 2.5vh;
339c127
<     top: 59%;
---
>     bottom: 2vh;
345c133
<     font-family: "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
---
>     font-family: "Helvetica", "Noto Sans", "Noto Sans JP", "Noto Sans KR", sans-serif;
351a140
> 	color: white;
359c148
<     background-color: rgba(35, 33, 33, 0.3);
---
>     background-color: rgba(33, 33, 33, 1);
360a150
>     bottom: 6vh;
362d151
<     bottom: 1.785vh;
368a158
> 	background-color: gray;
372c162
<     background-color: #232121;
---
>     background-color: white;
382c172
<     bottom: 0.2vh;
---
>     bottom: 6vh;
384c174
<     height: 4vh;
---
>     height: 3vh;
409a200
> 
441,454d231
< <div id="background-albumart">
<     <div class="back"></div>
<     <div class="front"></div>
<     <div id="background-dimming"></div>
< </div>
< <div id="background-artistart">
<     <div class="back"></div>
<     <div class="front"></div>
< </div>
< <div id="background-split">
<     <div style="flex-grow: 1;"></div>
<     <div id="background-gradient" class="visible"></div>
<     <div id="background-footer"></div>
< </div>
456,469c233
< <div id="lyricscontainer">
<     <div id="background-lyrics">
<         <div style="flex-grow: 1;"></div>
<         <div id="lyricscountdown">
<             <span>3</span>
<             <span>2</span>
<             <span>1</span>
<             <div id="lyricscountdownicon" class="lyricsicon"></div>
<         </div>
<         <div style="flex-grow: 1;"></div>
<     </div>
<     <div id="lyricstextcontainer" class="reducedAlphaAvailable reducedAnimationAvailable">
<     </div>
< </div>
---
> 
479,482c243,245
<     <div id="infoicon"></div>
<     <div id="progresstimecontainer" style="display: flex; flex-direction: row;">
<         <p id="progresstime" class="progresstime"></p>
<         <p id="totaltime" class="progresstime"></p>
---
> 	<div class="linecontainer" id="line3container">
>         <span class="back"></span>
>         <span class="front"></span>
492a256,259
> 	<div id="progresstimecontainer" style="display: flex; flex-direction: row;">
>         <p id="progresstime" class="progresstime"></p>
>         <p id="totaltime" class="progresstime"></p>
>     </div>
494c261
< <div id="lyricsicon" class="lyricsicon"></div>
---
> <!-- <div id="lyricsicon" class="lyricsicon"></div> -->

Cheers, Joe.

Is it possible to customise the “now playing” screen at all?

Hi guys, is it possible to have the current bit rate and sample rate also display on the now playing via chromecast or web display?

2 Likes

I would love this as well.

Heeey Joe. The display in the OP was totally rad, good job. Do you mind sharing the full code for it? I should be able to copy paste from the instructions in this tread.

For the noobs in the roon room :slight_smile: Where does one put this file in order to get the updated display page working? I’m using a nucleus if that makes a difference.

Thanks

You don’t, it goes in the client folder. So, it needs to be setup on each individual system. AND will be wiped out the minute there is a Roon update.

Please keep in mind this is not supported and if you mess things up you are on your own to fix.

Thanks, so how can we get this an officially supported option? Shouldn’t be that hard to add the extra meta data since it’s already there and just needs to be displayed.

1 Like

You can add a Feature Request.