This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Latest commit

History

636 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Important

This repository is outdated and archived!

You can find up-to-date client libraries in the new Emby.ApiClient Repository


Emby.ApiClient

This portable class library makes it very easy to harness the power of the Embyr API. This is available as a Nuget package:

Emby.ApiClient

Single Server Example

This is an example of connecting to a single server using a fixed, predictable address, from an app that has user-specific features.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();varclient=newApiClient(logger,"http://localhost:8096","My client name",device,cryptoProvider);varauthResult=awaitAuthenticateUserAsync("username",passwordHash);// Report capabilities after authenticationawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the user was logged out remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{UserId=client.UserId,SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});awaitclient.Logout();

Service Apps

If your app is some kind of service or utility (e.g. Sickbeard), you should construct ApiClient with your api key.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();varclient=newApiClient(logger,"http://localhost:8096","0123456789",capabilities,cryptoProvider);// Report capabilitiesawaitApiClient.ReportCapabilities(capabilities);// RemoteLoggedOut indicates the access token was revoked remotely by the serverApiClient.RemoteLoggedOut+=ApiClient_RemoteLoggedOut;// Get the ten most recently added items for the current uservaritems=awaitclient.GetItemsAsync(newItemQuery{SortBy=new[]{ItemSortBy.DateCreated},SortOrder=SortOrder.Descending,// Get media only, don't return folder itemsFilters=new[]{ItemFilter.IsNotFolder},Limit=10,// Search recursively through the user's libraryRecursive=true});

Web Socket

Once you have an ApiClient instance, you can easily connect to the server's web socket using:

ApiClient.OpenWebSocket();

This will open a connection in a background thread, and periodically check to ensure it's still connected. The web socket provides various events that can be used to receive notifications from the server:

ApiClient.UserUpdated+=webSocket_UserUpdated;

Multi-Server Usage

The above examples are designed for cases when your app always connects to a single server, and you always know the address. An example is an app that will always run within a local network and only connect to one server at a time. If your app is designed to support multiple networks and/or multiple servers, then IConnectionManager should be used in place of the above example.

// Developers are encouraged to create their own ILogger implementationvarlogger=newNullLogger();// This describes the device capabilitiesvarcapabilities=newClientCapabilities();// If using the portable class library you'll need to supply your own IDevice implementation.vardevice=newDevice{DeviceName="My Device Name",DeviceId="My Device Id"};// Developers will have to implement ICredentialProvider to provide storage for saving server informationvarcredentialProvider=newCredentialProvider();// If using the portable class library you'll need to supply your own INetworkConnection implementation.varnetworkConnection=newNetworkConnection(logger);// If using the portable class library you'll need to supply your own ICryptographyProvider implementation.varcryptoProvider=newCryptographyProvider();// If using the portable class library you'll need to supply your own IServerLocator implementation.varserverLocator=newServerLocator(logger);varconnectionManager=newConnectionManager(logger,credentialProvider,networkConnection,serverLocator,"My App Name",// Application version"1.0.0.0",device,capabilities,cryptoProvider,ClientWebSocketFactory.CreateWebSocket);

Multi-Server Startup Workflow

After you've created your instance of IConnectionManager, simply call the Connect method. It will return a result object with three properties:

  • State
  • Servers
  • ApiClient

ServerInfo and ApiClient will be null if State == Unavailable. If State==SignedIn or State==ServerSignIn, the Servers list will always have one single entry. Let's look at an example.

varresult=awaitconnectionManager.Connect(cancellationToken);switch(result.State){caseConnectionState.ConnectSignIn:// Connect sign in screen should be presented// Authenticate using LoginToConnect, then call Connect again to start overcaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.ServerSelection:// Multiple servers available// Display a selection screen using result.Servers// When a server is chosen, call the Connect overload that accept either a ServerInfo object or a String url.caseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

If the user wishes to connect to a new server, simply use the Connect overload that accepts an address.

varaddress="http://localhost:8096";varresult=awaitconnectionManager.Connect(address,cancellationToken);switch(result.State){caseConnectionState.Unavailable:// Server unreachablecaseConnectionState.ServerSignIn:// A server was found and the user needs to login.// Display a login screen and authenticate with the server using result.ApiClientcaseConnectionState.SignedIn:// A server was found and the user has been signed in using previously saved credentials.// Ready to browse using result.ApiClient}

Similarly, if the user selects a server from the selection screen, use the overload that accepts a ServerInfo instance. When the user wishes to logout, use connectionManager.Logout instead of the individual apiClient.Logout.

If at anytime the RemoteLoggedOut event is fired, simply start the workflow all over again by calling connectionManager.Connect(cancellationToken).

ConnectionManager will handle opening and closing web socket connections at the appropriate times. All your app needs to do is use an ApiClient instance to subscribe to individual events.

ApiClient.UserUpdated+=webSocket_UserUpdated;

With multi-server connectivity it is not recommended to keep a global ApiClient instance, or pass an ApiClient around the application. Instead keep a factory that will resolve the appropiate ApiClient instance depending on context. In order to help with this, ConnectionManager has a GetApiClient method that accepts a BaseItemDto and returns an ApiClient from the server it belongs to.

About

ApiClient allows .NET apps to easily access the Emby API

Resources

Stars

78 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages