Jump to content

Help getting started using API


dmclennan

Recommended Posts

dmclennan

Hi,

I've been experimenting with Swagger and think I have an idea how the API works.  I want to create a simple web page that plays a single playlist.  Through Swagger, I am able to play the playlist using Sessions.  Yet, when I try this trough a browser I get 'Unable to find the specified file'. 

I would appreciate it if anyone could post the minimal javascript code to login/authenticate (using API key), initiate session and play the playlist to a specific deviceid.

Thanks!

Don

 

Link to comment
Share on other sites

dmclennan

Hi Luke,

Thanks for the reply -- yes I have looked at the API wiki.  I'm missing something with the authentication and session information.  That's why I was asking for the minimal example.

Don

Link to comment
Share on other sites

4 hours ago, dmclennan said:

 

I would appreciate it if anyone could post the minimal javascript code to login/authenticate (using API key)

 

 

Our javascript api libraries have this:

https://github.com/MediaBrowser/Emby.ApiClient.Javascript

Again also mentioned in the developer wiki. You could use it directly or just take a look at it for sample code.

Link to comment
Share on other sites

dmclennan

I appreciate everyone's input and trying to help.  I can't find sample code or make sense the code snippets (mostly java). Before I give up, again, all I'm looking for is a simple html page that invokes the javascript apiclient, authenticates (either by authkey or user/password) and plays one music song.  Anyone with a simple example?

Thanks, Don

Link to comment
Share on other sites

bakes82

Are you a developer by trade. If you’re  just a copy paste hack coder then just give up. It’s not going to be a simple process to auth. Then get the library you want. Then call to get the file to stream to you.  Especially to just play a song. Like just use the app or webpage.

Link to comment
Share on other sites

PenkethBoy

@dmclennanAuth is simple to achieve as is finding libraries/files etc - its finding out the details to do it that is the challenge

to try and give you a start - as the documentation is woful and non existent for any person not familiar with code/coding on a daily basis and/or looking for a start to get them going with using the emby api - despite what Luke thinks

Below is a powershell example to login using user details and get the access token that you then use for each api call to authenticate

# Script version information
$Version = "v0.1.0"
# Script Global Variables for this example - could come from a config file or credential store etc etc
$embyClientName = "PS-EmbyBase"
$embyDeviceName = "PowerShell"
$embyDeviceId = "1000000"
$embyApplicationVersion = " - " +$Version
$embyServerUrl = "http://192.168.1.80:8096" # can be localhost or IP address e.g. "http://192.168.1.100:8096" include the quotes.

# for this example i have them here - but should be stored in a more secure location for porduction scripts
$Username = "dmclennan" # include the quotes.
$Pwd = '' # If you do not have a pwd then leave as ''


# Get Access Token for supplied User Details
function Get-EmbyAccessToken ($Username, $Pwd)
{
    $AuthUrl = $embyServerUrl + "/Users/AuthenticateByName?format=json"
    $Body = @{Username="$username";pw=$Pwd} | ConvertTo-Json
    $Header = @{"Authorization"="Emby Client=`"$embyClientName`", Device=`"$embyDeviceName`", DeviceId=`"$embyDeviceId`", Version=`"$embyApplicationVersion`""}
    # Check we can login with UserName and Pwd
    try
    {
        $LoginResult = Invoke-WebRequest -ErrorAction SilentlyContinue -Uri $AuthUrl -Method POST -Body $Body -ContentType "application/json" -Headers $Header
    }
    Catch
    {
        # error code goes here for failures e.g. server is not reachable/its off etc
    }
    # 200 is a successful login - check swagger for other possible codes
    If ($LoginResult.StatusCode -eq 200)
    {
        Return $LoginResult
    }
    else
    {
        # put your abort code here for dealing with a failed login
    }
}

An example of how to use the above

<#-----------------------------------------------------------------------------
Check User has supplied valid login details
-----------------------------------------------------------------------------#>
# User Authorisation - Try and login
$authResult = Get-EmbyAccessToken -Username $UserName -Pwd $Pwd
$user = $authResult.Content | ConvertFrom-Json

# Using the access token and user id to get all the libraries the user has access to
$MediaUrl = $embyServerUrl + "/emby/users/" + $User.User.Id + "/views" + "?api_key=" + $User.AccessToken
$LibraryResult = Invoke-WebRequest -Uri $MediaUrl -Method Get
$LibraryResult = $LibraryResult.Content | ConvertFrom-Json
# No of libraries = $LibraryResult.TotalRecordCount or $LibraryResult.items.count
# Sort JSON Library "Items" by CollectionType and Name
$LibraryResult = $LibraryResult.Items | Sort-Object -Property CollectionType, Name
<#-----------------------------------------------------------------------------
Cycle through User Library List and Extract Items by CollectionType
-----------------------------------------------------------------------------#>

for ($i = 0; $i -lt $LibraryResult.Length; $i++)
{
	# filter down to a sub set of library types (collectiontype)
    If (($LibraryResult.Item($i).CollectionType -eq "movies") -or ($LibraryResult.Item($i).CollectionType -eq "tvshows") -or ($LibraryResult.Item($i).CollectionType -eq "boxsets"))
    {
    	Write-Host Library - $LibraryResult.Item($i).Name of Type: $LibraryResult.Item($i).CollectionType
    }
}

 

The above is a simplified version of what i use in my scripts when i need to "talk" to emby - and should be easy enough to convert to your prefered language

ive shown you how to get a list of libraries - the LibraryResult variable has other properties of each library

you can use other requests to get an existing playlist from emby or create one etc - and get emby to play a song or the playlist or send it to another app etc etc - worlds your shell fish of choice

None of this is difficult or complex once you have an understanding of how the API works and emby is structured - but can seem a black box initially but a bit of patience and study is worth the effort.

Have Fun

PS - if you have other queries etc - i would open separate threads for them to keep the discussion focussed on the one issue

 

Link to comment
Share on other sites

  • 2 weeks later...
dmclennan
On 11/19/2020 at 8:48 PM, PenkethBoy said:

@dmclennanAuth is simple to achieve as is finding libraries/files etc - its finding out the details to do it that is the challenge

to try and give you a start - as the documentation is woful and non existent for any person not familiar with code/coding on a daily basis and/or looking for a start to get them going with using the emby api - despite what Luke thinks

Below is a powershell example to login using user details and get the access token that you then use for each api call to authenticate


# Script version information
$Version = "v0.1.0"
# Script Global Variables for this example - could come from a config file or credential store etc etc
$embyClientName = "PS-EmbyBase"
$embyDeviceName = "PowerShell"
$embyDeviceId = "1000000"
$embyApplicationVersion = " - " +$Version
$embyServerUrl = "http://192.168.1.80:8096" # can be localhost or IP address e.g. "http://192.168.1.100:8096" include the quotes.

# for this example i have them here - but should be stored in a more secure location for porduction scripts
$Username = "dmclennan" # include the quotes.
$Pwd = '' # If you do not have a pwd then leave as ''


# Get Access Token for supplied User Details
function Get-EmbyAccessToken ($Username, $Pwd)
{
    $AuthUrl = $embyServerUrl + "/Users/AuthenticateByName?format=json"
    $Body = @{Username="$username";pw=$Pwd} | ConvertTo-Json
    $Header = @{"Authorization"="Emby Client=`"$embyClientName`", Device=`"$embyDeviceName`", DeviceId=`"$embyDeviceId`", Version=`"$embyApplicationVersion`""}
    # Check we can login with UserName and Pwd
    try
    {
        $LoginResult = Invoke-WebRequest -ErrorAction SilentlyContinue -Uri $AuthUrl -Method POST -Body $Body -ContentType "application/json" -Headers $Header
    }
    Catch
    {
        # error code goes here for failures e.g. server is not reachable/its off etc
    }
    # 200 is a successful login - check swagger for other possible codes
    If ($LoginResult.StatusCode -eq 200)
    {
        Return $LoginResult
    }
    else
    {
        # put your abort code here for dealing with a failed login
    }
}

An example of how to use the above


<#-----------------------------------------------------------------------------
Check User has supplied valid login details
-----------------------------------------------------------------------------#>
# User Authorisation - Try and login
$authResult = Get-EmbyAccessToken -Username $UserName -Pwd $Pwd
$user = $authResult.Content | ConvertFrom-Json

# Using the access token and user id to get all the libraries the user has access to
$MediaUrl = $embyServerUrl + "/emby/users/" + $User.User.Id + "/views" + "?api_key=" + $User.AccessToken
$LibraryResult = Invoke-WebRequest -Uri $MediaUrl -Method Get
$LibraryResult = $LibraryResult.Content | ConvertFrom-Json
# No of libraries = $LibraryResult.TotalRecordCount or $LibraryResult.items.count
# Sort JSON Library "Items" by CollectionType and Name
$LibraryResult = $LibraryResult.Items | Sort-Object -Property CollectionType, Name
<#-----------------------------------------------------------------------------
Cycle through User Library List and Extract Items by CollectionType
-----------------------------------------------------------------------------#>

for ($i = 0; $i -lt $LibraryResult.Length; $i++)
{
	# filter down to a sub set of library types (collectiontype)
    If (($LibraryResult.Item($i).CollectionType -eq "movies") -or ($LibraryResult.Item($i).CollectionType -eq "tvshows") -or ($LibraryResult.Item($i).CollectionType -eq "boxsets"))
    {
    	Write-Host Library - $LibraryResult.Item($i).Name of Type: $LibraryResult.Item($i).CollectionType
    }
}

 

The above is a simplified version of what i use in my scripts when i need to "talk" to emby - and should be easy enough to convert to your prefered language

ive shown you how to get a list of libraries - the LibraryResult variable has other properties of each library

you can use other requests to get an existing playlist from emby or create one etc - and get emby to play a song or the playlist or send it to another app etc etc - worlds your shell fish of choice

None of this is difficult or complex once you have an understanding of how the API works and emby is structured - but can seem a black box initially but a bit of patience and study is worth the effort.

Have Fun

PS - if you have other queries etc - i would open separate threads for them to keep the discussion focussed on the one issue

 

Thank you -- I will give this a try.  

Link to comment
Share on other sites

yaksplat
On 12/4/2020 at 12:14 PM, dmclennan said:

Thank you -- I will give this a try.  

Keep in mind that although you are seeing http links in swagger, what's actually occurring is an http POST, GET or DELETE.  That's not going to occur when just pasting a link into a browser.

Are you familiar with Postman?  If so, just try the following:

generate an api key in the dashboard

Create a GET in postman

 http://<server>:8096/emby/System/Info?api_key=<keyFromAbove>

when you send that, you get some response with system info.  That confirms your API key

From the emby dashboard, click on devices and then a device that you want to play to.  In the address bar you'll see this

http://<server>:8096/web/index.html#!/devices/device.html?id=<deviceID>

The string at the end is the deviceID

if emby is open on that device, you can then get a sessionID

Create another GET in postman and run this with the above information

http://<server>:8096/emby/Sessions?DeviceId=<deviceID>&api_key=<apiKey>

That gives you  the session on that device.

Now, you need to find an item to play

Create another GET

http://<server>:8096/emby/Items?Recursive=true&IncludeItemTypes=Audio&NameStartsWith=<searchTerm>&api_key=<apiKey>

That will return a list of matching audio items.  Pick an item id that you want to play.

Now to play that item on the specific device, create a POST

http://<server>:8096/emby/Sessions/<sessionID>/Playing?ItemIds=<itemID>&PlayCommand=PlayNow&api_key=<apiKey>

At that point you should have your song being played on your device.

Now as far as programming something to do all of that, you're going to have to just throw it into the language of your choice.  They've made it extremely easy to do a task like this.

Link to comment
Share on other sites

dmclennan

Following the above suggestions, whether Postman or Powershell, I decided to give this a try using python.  

6 hours ago, yaksplat said:

...

Create a GET in postman


 http://<server>:8096/emby/System/Info?api_key=<keyFromAbove>

when you send that, you get some response with system info.  That confirms your API key

 

 

Using the API key from the dashboard, making an http GET request returns 'Access token is invalid or expired".

Simple python code,

import requests

url="http://10.10.0.4:8096/emby/System/Info?ai_key=xxx324ccf324bd4993ef6a50b1032eb"
response=requests.request("GET",url)
print(response.text)

Link to comment
Share on other sites

35 minutes ago, dmclennan said:

Following the above suggestions, whether Postman or Powershell, I decided to give this a try using python.  

 

Using the API key from the dashboard, making an http GET request returns 'Access token is invalid or expired".

Simple python code,

import requests

url="http://10.10.0.4:8096/emby/System/Info?ai_key=xxx324ccf324bd4993ef6a50b1032eb"
response=requests.request("GET",url)
print(response.text)

Yep don't forget the "p" in "api".

Link to comment
Share on other sites

dmclennan

Sorry, thank you for finding the obvious (trying to cut/paste between documentation and above examples).

I'm finally able to talk to Emby through the API - this is progress!!!  I think I now have a handle on using the API.

Thanks again for all your help.

Link to comment
Share on other sites

dmclennan

Yaksplat's roadmap is what I needed to begin working with the API.  A couple points that might help other folks not familiar with the Emby REST / API  model,

1. This is server-side code.  Until I thought about it more, I originally thought client-side browser could simply invoke the javascript API and this would all happen client-side with ajax calls.

2.  Any server-side programming language should be fine, as long as it supports HTTP GET and POST syntax.  I used python (already installed on my linux server).

3.  To play a song, requires several GET and POST commands.  I'm sure this is described somewhere, but I couldn't find.  As outlined above, the sequence is:

  1. GET System/Info using api_key to connect and authenticate
  2. GET Devices using api_key to list devices (optional)
  3. With DeviceId, GET Session; this returns an json object, with SessionID stored in PlayState Id
  4. With SessionId, start/stop playback, POST Sessions/<SessionId>/Playing?ItemIds=....

Observations,

  1. Sessions Playing will play songs, starting with the specified ItemId and will playnext or shuffle until told to stop playing.  
  2. Logging out POST Sessions/Logout deletes the Emby Api Key.  I'm not sure if this is correct behaviour -- I wanted to disconnect/logout of the session 

Here's my first-pass python code, following Yaksplat's sequence,

import requests
import json
import time

# Setup
emby_url="http://10.10.0.4:8096/emby/"
api_key = "xxx1324ccf324bd4993ef6a50b1032eb"
device_id = "861765ab-84ed-4f13-937d-1fadc09ae2e9"
song_id =  "11367"

# Authenticate
url = emby_url + "System/Info?api_key=" + api_key
response = requests.request("GET",url)

# Get all devices (optional)
url = emby_url + "Devices?api_key=" + api_key
response = requests.request("GET",url)

# Get session with DeviceId
url = emby_url + "Sessions?DeviceId=" + device_id + "&api_key=" + api_key
response = requests.request("GET",url)
session_dictionary = json.loads(response.text)
session_id = session_dictionary[0]["Id"]

# Play song
url= emby_url + "Sessions/" + session_id + "/Playing?ItemIds=" + song_id + "&PlayCommand=PlayShuffle&api_key=" + api_key
response = requests.request("POST",url)

# Wait a bit
time.sleep(20)

# Stop playing song
url = emby_url + "Sessions/" + session_id + "/Playing/Stop?api_key=" + api_key
response = requests.request("POST",url)

I hope this helps others get started with the API.  The API is pretty easy to work with.  Thanks again for all your help.

  • Like 1
Link to comment
Share on other sites

"1. This is server-side code.  Until I thought about it more, I originally thought client-side browser could simply invoke the javascript API and this would all happen client-side with ajax calls."

 

There's nothing stopping you from implementing this in client side javascript that utilizes Emby's Javascript API wrapper.

Link to comment
Share on other sites

yaksplat
6 hours ago, dmclennan said:

Yaksplat's roadmap is what I needed to begin working with the API.  A couple points that might help other folks not familiar with the Emby REST / API  model,

1. This is server-side code.  Until I thought about it more, I originally thought client-side browser could simply invoke the javascript API and this would all happen client-side with ajax calls.

2.  Any server-side programming language should be fine, as long as it supports HTTP GET and POST syntax.  I used python (already installed on my linux server).

3.  To play a song, requires several GET and POST commands.  I'm sure this is described somewhere, but I couldn't find.  As outlined above, the sequence is:

  1. GET System/Info using api_key to connect and authenticate
  2. GET Devices using api_key to list devices (optional)
  3. With DeviceId, GET Session; this returns an json object, with SessionID stored in PlayState Id
  4. With SessionId, start/stop playback, POST Sessions/<SessionId>/Playing?ItemIds=....

Observations,

  1. Sessions Playing will play songs, starting with the specified ItemId and will playnext or shuffle until told to stop playing.  
  2. Logging out POST Sessions/Logout deletes the Emby Api Key.  I'm not sure if this is correct behaviour -- I wanted to disconnect/logout of the session 

Here's my first-pass python code, following Yaksplat's sequence,


import requests
import json
import time

# Setup
emby_url="http://10.10.0.4:8096/emby/"
api_key = "xxx1324ccf324bd4993ef6a50b1032eb"
device_id = "861765ab-84ed-4f13-937d-1fadc09ae2e9"
song_id =  "11367"

# Authenticate
url = emby_url + "System/Info?api_key=" + api_key
response = requests.request("GET",url)

# Get all devices (optional)
url = emby_url + "Devices?api_key=" + api_key
response = requests.request("GET",url)

# Get session with DeviceId
url = emby_url + "Sessions?DeviceId=" + device_id + "&api_key=" + api_key
response = requests.request("GET",url)
session_dictionary = json.loads(response.text)
session_id = session_dictionary[0]["Id"]

# Play song
url= emby_url + "Sessions/" + session_id + "/Playing?ItemIds=" + song_id + "&PlayCommand=PlayShuffle&api_key=" + api_key
response = requests.request("POST",url)

# Wait a bit
time.sleep(20)

# Stop playing song
url = emby_url + "Sessions/" + session_id + "/Playing/Stop?api_key=" + api_key
response = requests.request("POST",url)

I hope this helps others get started with the API.  The API is pretty easy to work with.  Thanks again for all your help.

Glad my process helped out.  Always check your status after a request.  Make sure that you have a 200 or 204 before continuing.  In your code, the auth check could fail with a 404, but your code would continue. 

Link to comment
Share on other sites

dmclennan
2 hours ago, roaku said:

"1. This is server-side code.  Until I thought about it more, I originally thought client-side browser could simply invoke the javascript API and this would all happen client-side with ajax calls."

 

There's nothing stopping you from implementing this in client side javascript that utilizes Emby's Javascript API wrapper.

Now that I have a better handle on how the API works, I may try client-side javascript.

 

Link to comment
Share on other sites

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