ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} 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
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } 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
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
ViLiMan edited this page Sep 24, 2015 · 63 revisions

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

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

Welcome to the rameplayer wiki!

The foremost purpose of this wiki is to define the interactions between different services and GUI.

Services: omx_server
lcd_server
media_indexer (reads the metadata)
downloader (downloader manager for online media)

REST calls

edit

REST API

##Some Fundemental Decissions:

  • RESTfull API

Tries to follow general guidelines at least what comes to retrieving metadata, but because it uses only JSON and have some RPC commands it is not 100% pure. It uses HTTP status codes to signify success or failure of some sort. http://www.restapitutorial.com/httpstatuscodes.html

  • There is NO authentication

Any client able to access the rameplayer will be able to get information provided by the API. Later we can add authentication if needed or limit request to come only on LAN.

  • In rameplayer context REST client and servers are as follows:
  • client is Web GUI
  • server is the rest_service
  • No Case sensitivity

use of "_" when have to make separation between words

  • JSON only

in HTTP request "Accept: application/json" in HTTP response "Content-Type: application/json"

  • Time information delivery using ISO 8601

https://en.wikipedia.org/wiki/ISO_8601

  • supports milliseconds.

E.g. to be used in time defined playback

  • It uses URI to specify id's instead of query parameters

e.g. GET /api/media/albums/1 instead of

GET /api/media/albums?id=1

Because in REST query is used like it names says query of items not as singular way to refer them.

  • Use of plurals when items can be many (albums, tracks) when only one is possible using singular (player)

##REST API CALLS:

GET /api/media/albums/1

Returns Album id number 1 from media library

USE: GUI can populate the view for playback selection.

PARAMS: fields string (OPTIONAL)

JSON:

{ "album_id": 1, "album": "Album Name", "artist": "Album Artist", "tracks": [{ "tracks": 1, "title": "Song title", "filename": "file_001.mp3", "duration": "142.031756" },
// Another track
] }

RETURNS:

200 OK

404 Not Found

COMMENTS:

1.1 not repeating the artist and album info in track-array (since with jw-media there are always the same usually something like this for all tracks: "artist": "Artist NAme", "album": "MUSIC—Piano") 1.2 I did selectively copy the ffprope metada (not returning all the info). You have to dig the originals to see what i didn't include.. 1.3 I copied the ffprope produced format section as it's own object inside track object. 1.4 To speed up the initial GUI population you can give the tag names you want to includ: Since including all the existing metadata (like chapter data) would lead into large json not needed in all cases. This will ensure maximum flexibility and speed when constructing GUI e.g. in the case of AV book view. Reference: https://developers.google.com/+/web/api/rest/#partial-response

e.g. track&title


GET /api/media/albums/2/tracks/1

Returns the track info for specified album 2 and track 1

USE: GUI can selectively get more info (e.g. chapters) from specific track

JSON:
{
"medialib_track_no": 1, "title": "Song's title""format": {
medialib_filepath: "file_001.mp3","duration": "142.031756",
},
"chapters": [{
"id": 0,
"time_base": "1/2997",
"start": 0,
"start_time": "0.000000",
"end": 6100,
"end_time": "2.035369",
"tags": {
"title": "Start"
}
},
{
"id": 1,
"time_base": "1/2997",
"start": 6100,
"start_time": "2.035369",
"end": 33200,
"end_time": "11.077744",
"tags": {
"title": "Chapter 1"
}
}]
}

RETURNS:

200 OK

404 Not Found


POST /api/player/play?filepath="/media/002.m4v"

OR POST /api/player/play?album=1&track=2

USE:
Commanding the player to start playing media optionally specified to start delay time or some absolute time.

PARAMS:
filepath string OR album number track number absolute_time string ISO 8601(optional) delay_time_ms number time in ms (optional)

JSON: nothing

RETURNS: 200 OK 404 Not Found 500 Internal Server Error

COMMENTS:

3.1 omx_player talks only with the files. So either GUI keeps tracks on the filepath or RESTAPIi goes trough the metadata and calls the right filename with right path. Raising the abstraction little bit.

Or do we want to support both approaches? So depending the GUI it can either send filename or album/track pair (not so difficult to implement in REST side). We can for example start with the filename approach..

3.2 Using POST here because calling the same method again will not have same results (due changed server state). We are here invoking server to do (process) something not returning data (this is to follow REST principles)

3.3 I ended up using following verb syntax in the URI i.e. having a command play there (which is not according to REST principles that do not work together with RPC needs - I studied quite a bit..) but I preferred that over query action=play syntax.


POST /api/player/stop

USE: Commanding the player to stop current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/pause

USE: Commanding the player to pause current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/resume

USE: Commanding the player to resume (play) current playback

PARAMS: nothing

JSON: nothing

RETURNS: 200 OK 500 Internal Server Error


POST /api/player/prepare?filepath="/media/002.m4v"

USE:

Commanding the player to prepare (read the file in advance to buffer)?

PARAMS:

filepath string

JSON:

nothing

RETURNS:

200 OK

404 Not Found

500 Internal Server Error

COMMENTS:

?!?

Things to consider:

  • REST API only answer 192.168.. or 10...* calls?
  • Disable the download possibility of py and wsgi files?