Jump to content

Using "hls" in the JS inside a plugin.


Recommended Posts

VicMoore
Posted

I am trying to use the hls.min.js library within a plugin, but don't know how to add it.  I tried adding a script tag to load the lib as shown below, but this did not work.

<div is="emby-scroller" class="view flex flex-direction-column scrollFrameY flex-grow" data-mousewheel="true" data-horizontal="false" data-centerfocus="card" data-controller="__plugin/mytvconfigjs" data-title="${HeaderTVSourceSetup}">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet">
    <script type="text/javascript" src="./hls.min.js"></script> 
 

How should I add this library so I can use it within an Emby plugin.

My goal is to stream an Emby video to a node in the DOM using hls.

Vic

 

 

Posted

Hi, you can't. Or at least you shouldn't. You can have a shared js file inside your plugin though. I would check out the auto organize source for an example of that.

Posted
2 hours ago, VicMoore said:

I am trying to use the hls.min.js library within a plugin, but don't know how to add it.  I tried adding a script tag to load the lib as shown below, but this did not work.

<div is="emby-scroller" class="view flex flex-direction-column scrollFrameY flex-grow" data-mousewheel="true" data-horizontal="false" data-centerfocus="card" data-controller="__plugin/mytvconfigjs" data-title="${HeaderTVSourceSetup}">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet">
    <script type="text/javascript" src="./hls.min.js"></script> 
 

How should I add this library so I can use it within an Emby plugin.

My goal is to stream an Emby video to a node in the DOM using hls.

Vic

Hi Vic,

may I ask what exactly you are trying to achieve? 

And is it for users or for server admins?

sw

VicMoore
Posted

Hello @softworkzI am just having fun with JS and the GUI used in myTV.  I am trying to create an interesting GUI effect where when you hover over an image (which represents one video in the Emby DB) then the image is replaced in the DOM with the movie playing. Sort of like you see in YouTube.  I built a client a while back where I did this using HLS.   To do this in the JS and HTML of the myTV plugin, I need to load the HLS library (hls.min.js).  I thought this would be fun to do.

Vic

VicMoore
Posted

@Luke is there another way, rather than using hls, that I can use to play a video on a DOM node? 

Vic

Posted

Ah alright understood.

The problems with HLS playback that I'd see here are:

  • Emby uses hls.js itself - I don't know for sure, but this could cause issues when loaded twice
  • Getting Emby to produce exactly the HLS that you need for arbitrary videos can be quite a task
  • Starting Emby Server transcoding to HLS is a heavy-weight operation with quite some latency involved until it can be played, so you definitely won't be able to react to any hovers as fast as it should be
    • Youtube can do it fast because they have every video pre-rendered in many resolutions, while Emby always does live-transcoding
  • How about using Emby's thumbnail images instead for a nice effect?
    You could display the thumbnail image depending on the mouse position (percentage left-to-right), so when you move the mouse across the image, you can quickly skim through the whole video in a (relatively) light-weight way - and much more responsive than with viddeo..
VicMoore
Posted

@softworkzIs there a way that I could use the hls loaded by Emby?  I like your idea about using thumbnails. I can see the code in my head.

Can I create a thumbnail from any point in a movie?  Do you have a code example?  I will implement this idea.

Vic

VicMoore
Posted (edited)

@Luke I have been studying "auto organize source" and it's wonderful.  I have learned a lot from it.  What I have not figured out is how to share JS code.  I have two JS files defined in the plugin.cs file.

                new PluginPageInfo
                {
                    Name = "mytvconfig",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvconfig.html",
                    IsMainConfigPage = false
                },
                new PluginPageInfo
                {
                    Name = "mytvconfigjs",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvconfig.js"
                },
                new PluginPageInfo
                {
                    Name = "mytvapps",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvapps.html",
                    IsMainConfigPage = false,
                },
                new PluginPageInfo
                {
                    Name = "mytvappsjs",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvapps.js"
                },
 

In the apps.js file I added:

    ApiClient.appsTest = function (id) {

        var url = this.getUrl(`/Items/${id}/ThumbnailSet`);

        console.log("=== thumbnails url = ", url);

        return this.ajax({
            type: "GET",
            url: url
        });
    };

 

I understood that this adds a new method "appsTest" to the ApiClient.  So, I assumed that this new method would be available in the other JS file (mytvconfig.js). When I try to use this function in myconfig.js I get a "ApiClient.appsTest is not a function"  error.  

Am I going down the right track?  Did I miss what you were trying to tell me?  If so, then how do I share methods between JS files?

I greatly appreciate the help that you and @softworkzgenerously give me.

Vic

 

Edited by VicMoore
VicMoore
Posted (edited)

@softworkz I can now get the Thumbnail tag array for a movie.  I am not sure what image url to use to display each image. Would it be:

let image_url =  "/Items/" + id + "/Images/Thumb?tag=" + Tag ;

where "id" is the corresponding image Id and "Tag" is the respective Tag from the thumbnail array. This does not look right.

Is this url correct? Or, should I be using another url?

Vic

Edited by VicMoore
Posted
8 hours ago, VicMoore said:

@Luke I have been studying "auto organize source" and it's wonderful.  I have learned a lot from it.  What I have not figured out is how to share JS code.  I have two JS files defined in the plugin.cs file.

                new PluginPageInfo
                {
                    Name = "mytvconfig",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvconfig.html",
                    IsMainConfigPage = false
                },
                new PluginPageInfo
                {
                    Name = "mytvconfigjs",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvconfig.js"
                },
                new PluginPageInfo
                {
                    Name = "mytvapps",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvapps.html",
                    IsMainConfigPage = false,
                },
                new PluginPageInfo
                {
                    Name = "mytvappsjs",
                    EmbeddedResourcePath = this.GetType().Namespace + ".config.mytvapps.js"
                },
 

In the apps.js file I added:

    ApiClient.appsTest = function (id) {

        var url = this.getUrl(`/Items/${id}/ThumbnailSet`);

        console.log("=== thumbnails url = ", url);

        return this.ajax({
            type: "GET",
            url: url
        });
    };

 

I understood that this adds a new method "appsTest" to the ApiClient.  So, I assumed that this new method would be available in the other JS file (mytvconfig.js). When I try to use this function in myconfig.js I get a "ApiClient.appsTest is not a function"  error.  

Am I going down the right track?  Did I miss what you were trying to tell me?  If so, then how do I share methods between JS files?

I greatly appreciate the help that you and @softworkzgenerously give me.

Vic

 

See FileOrganizerJs and how the rest of the plugin loads it.

VicMoore
Posted

@LukeThanks for the clue. I am off and running with it.

@softworkzI have your idea up and running.  I now need to make the Thumbnails change as I move the cursor.  Thanks so much.

Vic

  • Like 1
  • Thanks 1
VicMoore
Posted

@LukeI followed your advice.

First, what I know is this:

1) Web pages are identified in Plugin.cs.  Each page is assigned a name and a path to the corresponding HTML, followed by another path to the page's javascript.

2) The first <div> in the HTML for each page has a data-controller property that gives the name for the web page in Plugin.cs to which the HTML belongs.

3) The exception to these rules is the FileOrganizerJS  web page in Plugin.cs. The HTML for this page does not define a data-controller to use.

4) I have not been able to discover how the plugin loads the FileOrganizer.JS

 

Am I getting warm?  Where does FileOrganizer get loaded?

vic

Posted

Did you search the repo for FileOrganizerJs?

VicMoore
Posted

@LukeWhat is the repo ?

Vic

VicMoore
Posted

@LukeAh, I understand now. Thanks for the help.

Vic

  • Thanks 1
Posted

What you probably really want is this:

 

image.png

 

The yellow is the name you specify in C# in the PluginPageInfo definition.

The green is the name under which you can access it in JS - it's free to your choosing.

 

It's really obscure - impossible to figure out oneself...I had to dig it up myself.

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