AMenard 2 Posted June 5, 2020 Share Posted June 5, 2020 Hi, Is there some material on how to develop plugins/channel for emby? Or some exemple code that someone can study and/or adapt? An API function list/call? Maybe I'm not looking at the right place... For exemple, I've found a link to the wiki but the plugin and channel entry is more about how to install them than how to create them. Link to comment Share on other sites More sharing options...
Solution Luke 37098 Posted June 5, 2020 Solution Share Posted June 5, 2020 Hi there, yes we do have a wiki on this: https://github.com/MediaBrowser/Emby/wiki/How-to-build-a-Server-Plugin Please let us know if this helps. Thanks. 1 Link to comment Share on other sites More sharing options...
AMenard 2 Posted June 5, 2020 Author Share Posted June 5, 2020 Hi there, yes we do have a wiki on this: https://github.com/MediaBrowser/Emby/wiki/How-to-build-a-Server-Plugin Please let us know if this helps. Thanks. Thanks! Exactly what I was looking for. Link to comment Share on other sites More sharing options...
Anthony Musgrove 195 Posted June 6, 2020 Share Posted June 6, 2020 Im in the process of writing a book on it Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 3, 2020 Share Posted October 3, 2020 On 6/6/2020 at 4:38 AM, Anthony Musgrove said: Im in the process of writing a book on it @Anthony Musgrove it done yet? Link to comment Share on other sites More sharing options...
Luke 37098 Posted October 3, 2020 Share Posted October 3, 2020 @chef may have some tips. Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 3, 2020 Share Posted October 3, 2020 @Luke This is way I prefer a nice api instead lol less issues about how to do things. As long and I can interface the api I can use whatever front end I want . When you guys moving to blazor Link to comment Share on other sites More sharing options...
chef 3746 Posted October 7, 2020 Share Posted October 7, 2020 On 10/2/2020 at 8:29 PM, bakes82 said: @Luke This is way I prefer a nice api instead lol less issues about how to do things. As long and I can interface the api I can use whatever front end I want . When you guys moving to blazor I have some plugin examples for channels on my github. https://github.com/chefbennyj1/Emby.NewReleasesChannel Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 7, 2020 Share Posted October 7, 2020 6 hours ago, chef said: I have some plugin examples for channels on my github. https://github.com/chefbennyj1/Emby.NewReleasesChannel You got a screen shot of what that does? Does it show New movies/tv shows for that week/month I assume? Idk what a channel is lol. Why are these not in the global plugin place, or a way to add repos so we dont need to download and add to plugins folder. Link to comment Share on other sites More sharing options...
chef 3746 Posted October 7, 2020 Share Posted October 7, 2020 (edited) 3 hours ago, bakes82 said: You got a screen shot of what that does? Does it show New movies/tv shows for that week/month I assume? Idk what a channel is lol. Why are these not in the global plugin place, or a way to add repos so we dont need to download and add to plugins folder. Some of those plugins (in the repo) are in the catalog, but some others would... 'over-extended'... the criteria to be put in there (if you know what I mean, ex. u#orren# plugin doesn't really have a place in the catalog). They are just some personal ones I made for my setup to fulfill a need. When you mentioned plugin/channels, I thought you meant: how do you build a channel plugin. I really enjoy writing code for emby plugins, so if you have any questions I can help with, lemme know Edited October 7, 2020 by chef Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 7, 2020 Share Posted October 7, 2020 44 minutes ago, chef said: Some of those plugins (in the repo) are in the catalog, but some others would... 'over-extended'... the criteria to be put in there (if you know what I mean, ex. u#orren# plugin doesn't really have a place in the catalog). They are just some personal ones I made for my setup to fulfill a need. When you mentioned plugin/channels, I thought you meant: how do you build a channel plugin. I really enjoy writing code for emby plugins, so if you have any questions I can help with, lemme know Well you want to just write this My stuff is all remote hosted so its a PITA to put dlls on to docker, especially if I cant test via a console app or something first. Its pretty simple I think, I did it in plex but as blazor app. You just need 1 object to store a Collection Name, a list of trakt URLs, library to create collection in. You parse the URLS. Then you just send those to the trak.net api and you can get back the IMDB/TMDB/TVDB to check if its in the Emby library.https://github.com/henrikfroehling/Trakt.NET In trakt you setup your own API client/secret public static class TraktHelpers { public static TraktListFields TraktListUriParse(string uri) { uri = uri.ToLower(); if (uri.Contains("/users/") && uri.Contains("/lists/")) { var questionMarkIndex = uri.IndexOf('?'); if (questionMarkIndex > 0) { uri = uri.Remove(questionMarkIndex); } var splitString = uri.Split("/users/")[1].Split("/lists/"); var userName = splitString[0]; var listName = splitString[1]; return new TraktListFields{Username = userName, ListName = listName}; } return null; } } public class TraktListFields { public string Username { get; set; } public string ListName { get; set; } } if (urls != null) foreach (var url in urls) { var userLists = TraktHelpers.TraktListUriParse(url); if (userLists == null || userLists.Username.IsNullOrEmpty() || userLists.ListName.IsNullOrEmpty()) { MoviesListCompare = new List<MovieDto>(); await _toastObj.Show(new ToastModel { Title = "Error!", Content = $"Can not parse user name or list from uri {url}", CssClass = "e-toast-danger", Icon = "e-danger toast-icons", TimeOut = 15000 }); } if (userLists != null) traktListFields.Add(new TraktListFields {Username = userLists.Username, ListName = userLists.ListName}); } var clientId = Configuration["Trakt:ClientId"]; var clientSecret = Configuration["Trakt:ClientSecret"]; var traktClient = new TraktClient(clientId, clientSecret) { Authorization = TraktAuthorization.CreateWith(TraktKey) }; var items = new List<TraktPagedResponse<ITraktListItem>>(); foreach (var list in traktListFields) { items.AddRange(await traktClient.Users.GetCustomListItemsAsync(list.Username, list.ListName)); } MoviesListCompare = new List<MovieDto>(); var plexMovies = PlexLibraryInfo.MediaContainer.Metadata; foreach (var traktPagedResponse in items) { foreach (var traktListItem in traktPagedResponse.Value) { if (traktListItem.Type == TraktListItemType.Movie) { var plexHas = PlexHelpers.PlexHasItem(plexMovies, traktListItem.Movie.Title, traktListItem.Movie.Ids.Imdb, traktListItem.Movie.Year ?? 0); var plexWatched = PlexHelpers.PlexWatchedItem(plexMovies, traktListItem.Movie.Title, traktListItem.Movie.Ids.Imdb, traktListItem.Movie.Year ?? 0); MoviesListCompare.Add(new MovieDto { Title = traktListItem.Movie.Title, Description = plexHas != null ? plexHas.Summary : traktListItem.Movie.Overview, TraktHas = true, Year = traktListItem.Movie.Year, IMDB = traktListItem.Movie.Ids.Imdb, PlexHas = plexHas != null, PlexWatched = plexWatched != null, Duration = plexHas != null ? (plexHas.Duration / 1000).ToString() : (traktListItem.Movie.Runtime ?? 0 * 60).ToString(), Rating = plexHas != null ? plexHas.ContentRating : traktListItem.Movie.Certification, PlexRatingKey = plexHas != null ? plexHas.RatingKey : string.Empty, Art = plexHas != null ? ServerUrl + plexHas.Thumb + "?X-Plex-Token=" + PlexKey : string.Empty }); } } } Trakt Login var clientId = Configuration["Trakt:ClientId"]; var traktRedirectUrl = NavigationManager.BaseUri + "TraktReturn"; var redirectUrl = $"https://trakt.tv/oauth/authorize?client_id={clientId}&redirect_uri={traktRedirectUrl}&response_type=code"; NavigationManager.NavigateTo(redirectUrl); Return From trakt var clientId = Configuration["Trakt:ClientId"]; var clientSecret = Configuration["Trakt:ClientSecret"]; var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri); var code = string.Empty; if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("code", out var codeOut)) { code = codeOut; } if (code.IsNotNullOrEmpty()) { var traktClient = new TraktClient(clientId, clientSecret); traktClient.Authentication.RedirectUri = NavigationManager.BaseUri + "TraktReturn"; var authResp = await traktClient.Authentication.GetAuthorizationAsync(code); await ProtectedLocalStore.SetAsync("TraktKey", authResp.Value.AccessToken); TraktLoginState.LoggedIn = true; NavigationManager.NavigateTo("/trakt"); } Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 8, 2020 Share Posted October 8, 2020 @chefI just got your NewReleases installed, if you could do the exact same things put using a trakt list I think thats exactly what most people want Link to comment Share on other sites More sharing options...
chef 3746 Posted October 8, 2020 Share Posted October 8, 2020 Just now, bakes82 said: @chefI just got your NewReleases installed, if you could do the exact same things put using a trakt list I think thats exactly what most people want This is interesting You'll have to forgive me, I'm not a trakt user (yet...), I have couple questions, so I can get an idea of the scope of the project. The trakt plugin that emby already has, will sync watched states between trakt and emby, but this plugin is different. The idea is to create a "Trakt" library collection option (appearing on the emby home screen), which will show media items from Trakt (that are not already in the Emby database). What happens when we view the item details page (the Hero page of the Movie/Episode) and we press the play button? Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 8, 2020 Share Posted October 8, 2020 @chef No this plugin is the reverse of what you are saying, It will SHOW what movies or tv shows MATCH on the list. (If you want to show the "missing" things also would be wonderful but I think thats not priority) So many people like to have a collection that shows you know the top 250 Imdb movies, or all the James Bond Movies. I usually say "Collections" but I like this library format also, less clicking. But I guess you could make that a toggle. So there are many automated trakt lists or people can make their own, then the plugin will get that list every night and if emby has it, put it in that collection/libary whatever we are calling them . Heres some ref: https://trakt.tv/users/nielsz/lists/active-imdb-top-250?sort=rank,asc https://trakt.tv/users/giladg/lists/top-10-movies-of-the-week?sort=added,asc Just FYI this is a highly requested item in Plex and Emby 1 Link to comment Share on other sites More sharing options...
bakes82 90 Posted October 8, 2020 Share Posted October 8, 2020 So UI: Name of Library to make URL1 URL2 URLN Create Library (Like NewReleases Does) or Create Collection If Collection -> What Libraries do you want the collections in Backend: Make sure to removed items no longer on list when comparing. Link to comment Share on other sites More sharing options...
smernt 9 Posted November 20, 2021 Share Posted November 20, 2021 On 08/10/2020 at 02:11, chef said: This is interesting You'll have to forgive me, I'm not a trakt user (yet...), I have couple questions, so I can get an idea of the scope of the project. The trakt plugin that emby already has, will sync watched states between trakt and emby, but this plugin is different. The idea is to create a "Trakt" library collection option (appearing on the emby home screen), which will show media items from Trakt (that are not already in the Emby database). What happens when we view the item details page (the Hero page of the Movie/Episode) and we press the play button? Hey @chef did you ever get anywhere with making a plugin to use trakt lists as 'collections' inside of Emby? Link to comment Share on other sites More sharing options...
chef 3746 Posted November 20, 2021 Share Posted November 20, 2021 1 hour ago, smernt said: Hey @chef did you ever get anywhere with making a plugin to use trakt lists as 'collections' inside of Emby? @bakes82 made an awesome one. Link to comment Share on other sites More sharing options...
smernt 9 Posted November 20, 2021 Share Posted November 20, 2021 43 minutes ago, chef said: @bakes82 made an awesome one. Thanks, I've just tried it but couldn't get it to work, it created a 'channel' but didn't pull anything into it, even though I did the trakt pin & have apple tv content on my server etc. Also, how do I now remove the 'AppleTV' channel that it created? there's no delete button & I can't see it referenced as a library or collection... Link to comment Share on other sites More sharing options...
Luke 37098 Posted November 20, 2021 Share Posted November 20, 2021 You'd have to just uninstall the plugin. 1 Link to comment Share on other sites More sharing options...
bakes82 90 Posted November 20, 2021 Share Posted November 20, 2021 I don't use emby, wasnt worth the effort. I also dont think this dude is a dev and wants one pre built which doesnt exist. Code is here youll need to update the server api Im sure. I recall there being some random issues but maybe they been fixed in the past year but doubtful ;) https://github.com/bakes82/TraktLists 1 Link to comment Share on other sites More sharing options...
smernt 9 Posted November 20, 2021 Share Posted November 20, 2021 Just now, Luke said: You'd have to just uninstall the plugin. Thanks, I did that but forgot to re-start the server so it could pick it up! Link to comment Share on other sites More sharing options...
bakes82 90 Posted April 4, 2022 Share Posted April 4, 2022 @chef Whats this doing in your "NewReleases" channel code? I have a channel but if I update something in the config it doesnt seem to take until server restart its like channels only load the config 1x? Does this get around that? private Task<ChannelItemResult> GetChannelItemsInternal() { Plugin.Instance.UpdateConfiguration(Plugin.Instance.Configuration); var config = Plugin.Instance.Configuration; Link to comment Share on other sites More sharing options...
chef 3746 Posted April 4, 2022 Share Posted April 4, 2022 32 minutes ago, bakes82 said: @chef Whats this doing in your "NewReleases" channel code? I have a channel but if I update something in the config it doesnt seem to take until server restart its like channels only load the config 1x? Does this get around that? private Task<ChannelItemResult> GetChannelItemsInternal() { Plugin.Instance.UpdateConfiguration(Plugin.Instance.Configuration); var config = Plugin.Instance.Configuration; Hmm... Might have been early code that didn't make sense. However, on first run of a plugin, if the plugin configuration class doesn't have a constructor, calling update will create the config, and the xml with default values, or null. I think it is proper to have a constructor in the plugin configuration class. That is a cheesy hack to force the plugin configuration to initialize the first time the plugin runs in the server. Link to comment Share on other sites More sharing options...
Luke 37098 Posted April 4, 2022 Share Posted April 4, 2022 To get your channel content to change immediately, have the channel implement the interface IHasChangeEvent, and then fire the ContentChanged event. To do that from some other class such as your plugin, you could do: public override void UpdateConfiguration(BasePluginConfiguration configuration) { base.UpdateConfiguration(configuration); _channelManager.GetChannel<Channel>().OnContentChanged(); } Link to comment Share on other sites More sharing options...
DragonSkills99 3 Posted April 27, 2022 Share Posted April 27, 2022 @Luke How can I debug my plugin? I'm quite confused with the "https://github.com/MediaBrowser/Emby" Repo, as it has many projects and I don't know what to start and where to put/include the plugin. Alternatively is there any lightweight example for adding a TV Provider (more the where to put and how to save data in the normal nfo files than how to request/parse remote data, as I've already completed writing the API/Website-Wrapper) But even with that example I would like it very much to be able to debug my Plugin... Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now