Initial music playback!

This commit is contained in:
RandyTheSilly committed 2026-10-11 16:37:30 -04:00
1 parent 1e9375f5e9
commit 9798dcb08e
2 files changed
+65 -22

No files matched your search

+19 -1
View File
@@ -124,6 +124,24 @@ static void inbox_received_handler(DictionaryIterator *iter, void *context) {
} }
} }
static void to_pkjs_play_from_track(uint16_t seqId) {
if (!s_pkjs_ready) {
return;
}
DictionaryIterator *out;
AppMessageResult result = app_message_outbox_begin(&out);
if (result != APP_MSG_OK) {
return;
}
dict_write_uint16(out, MESSAGE_KEY_OUT_PLAY_SEQ_ID, seqId);
result = app_message_outbox_send();
if (result != APP_MSG_OK) {
return;
}
}
static void to_pkjs_move_deeper(NavScope scope, uint16_t *subscope_index) { static void to_pkjs_move_deeper(NavScope scope, uint16_t *subscope_index) {
if (!s_pkjs_ready) { if (!s_pkjs_ready) {
return; return;
@@ -236,7 +254,7 @@ static void menu_select_click(struct MenuLayer *menu_layer, MenuIndex *clicked_i
to_pkjs_move_deeper(s_current_menu_scope + 1, &clicked_index->row); to_pkjs_move_deeper(s_current_menu_scope + 1, &clicked_index->row);
break; break;
case NAV_SCOPE_ALBUM_TRACKS: case NAV_SCOPE_ALBUM_TRACKS:
// TODO tell PKJS to play track (and queue sequential tracks) to_pkjs_play_from_track(s_current_menu_seq_ids[clicked_index->row]);
break; break;
} }
} }
+46 -21
View File
@@ -14,6 +14,10 @@ var NavScope = Object.freeze({
var cfg = JSON.parse(localStorage.getItem('clay-settings')); var cfg = JSON.parse(localStorage.getItem('clay-settings'));
var currentArtist = null; var currentArtist = null;
////////////////////// GENERAL API VARS //////////////////////
var USER_ID_CACHE_KEY = 'user-id';
var jfSessionId;
////////////////////// LIBRARY CACHE ////////////////////// ////////////////////// LIBRARY CACHE //////////////////////
var LIBRARY_CACHE_KEY = 'library-cache'; var LIBRARY_CACHE_KEY = 'library-cache';
@@ -77,9 +81,33 @@ function loadLibraryCache() {
////////////////////// SYNC ////////////////////// ////////////////////// SYNC //////////////////////
function toggleReadyState(ready) { function toggleReadyState(ready) {
let bestSessionInfo = {
sessionId: "",
lastActiveTime: new Date("1970-01-01T00:00:00.0000000Z")
};
// get sessionId from Jellyfin
callAPI("GET", cfg.PRIV_BASE_URL + "/Sessions", function (sessionIdResp) {
if (sessionIdResp === null) { return; }
const sessionIdObj = JSON.parse(sessionIdResp);
let lastActiveTime;
for (const session of sessionIdObj) {
if (session.UserName == cfg.PRIV_USERNAME) {
lastActiveTime = new Date(session.LastActivityDate);
if (lastActiveTime > bestSessionInfo.lastActiveTime) {
bestSessionInfo = {
sessionId: session.Id,
lastActiveTime: lastActiveTime
};
}
}
}
jfSessionId = bestSessionInfo.sessionId;
const readyDict = {}; const readyDict = {};
readyDict[keys.PKJS_READY] = ready; readyDict[keys.PKJS_READY] = ready;
Pebble.sendAppMessage(readyDict); Pebble.sendAppMessage(readyDict);
});
} }
function syncLibrary() { function syncLibrary() {
@@ -87,8 +115,8 @@ function syncLibrary() {
// store cache of library info from Jellyfin // store cache of library info from Jellyfin
if (cfg.PRIV_BASE_URL && cfg.PRIV_API_KEY && cfg.PRIV_USERNAME) { if (cfg.PRIV_BASE_URL && cfg.PRIV_API_KEY && cfg.PRIV_USERNAME) {
// get userId from Jellyfin
callAPI("GET", cfg.PRIV_BASE_URL + "/Users", function (userIdResp) { callAPI("GET", cfg.PRIV_BASE_URL + "/Users", function (userIdResp) {
// get userId from Jellyfin
if (userIdResp === null) { return; } if (userIdResp === null) { return; }
const userIdObj = JSON.parse(userIdResp); const userIdObj = JSON.parse(userIdResp);
let userId; let userId;
@@ -200,6 +228,16 @@ Pebble.addEventListener("appmessage", function (dict) {
const scope = payloadGet(dict.payload, "BIDIR_MENU_NAV_SCOPE"); const scope = payloadGet(dict.payload, "BIDIR_MENU_NAV_SCOPE");
const subscope = payloadGet(dict.payload, "OUT_MENU_NAV_SUBSCOPE"); const subscope = payloadGet(dict.payload, "OUT_MENU_NAV_SUBSCOPE");
const seqId = payloadGet(dict.payload, "OUT_PLAY_SEQ_ID");
if (seqId) {
console.log("SEQ ID RECEIVED");
console.log("sessionId: " + jfSessionId);
console.log("seqId: " + seqId);
console.log("jfId: " + allJfIds[seqId]);
console.log("SEQ ID RECEIVED");
callAPI("POST", cfg.PRIV_BASE_URL + "/Sessions/" + jfSessionId + "/Playing?playCommand=PlayNow&itemIds=" + allJfIds[seqId], null);
}
if (scope) { if (scope) {
let vanityList; let vanityList;
@@ -250,8 +288,8 @@ Pebble.addEventListener("appmessage", function (dict) {
////////////////////// JELLYFIN API ////////////////////// ////////////////////// JELLYFIN API //////////////////////
function reportAPIFailure() { function reportAPIFailure(statusCode, statusText) {
console.log("API FAILURE"); console.log("[" + statusCode+"] API FAILURE: " + statusText);
} }
function callAPI(method, endpoint, callback) { function callAPI(method, endpoint, callback) {
@@ -260,17 +298,19 @@ function callAPI(method, endpoint, callback) {
xhr.onload = function () { xhr.onload = function () {
switch (xhr.status) { switch (xhr.status) {
case 200: case 200:
if (callback) {
callback(this.responseText); callback(this.responseText);
}
return; return;
default: default:
reportAPIFailure(); reportAPIFailure(xhr.status, xhr.statusText);
} }
}; };
xhr.onerror = function () { xhr.onerror = function () {
reportAPIFailure(); reportAPIFailure(xhr.status, xhr.statusText);
}; };
xhr.ontimeout = function () { xhr.ontimeout = function () {
reportAPIFailure(); reportAPIFailure(xhr.status, xhr.statusText);
}; };
xhr.open(method, endpoint, true); xhr.open(method, endpoint, true);
@@ -279,18 +319,3 @@ function callAPI(method, endpoint, callback) {
xhr.setRequestHeader("Authorization", 'MediaBrowser Token="' + cfg.PRIV_API_KEY + '"'); xhr.setRequestHeader("Authorization", 'MediaBrowser Token="' + cfg.PRIV_API_KEY + '"');
xhr.send(); xhr.send();
} }
// On Every Startup
//// Get Session ID
//curl -H "Authorization: MediaBrowser Token=\"TOKEN\"" -X GET 'BASEURL/Sessions'
// Filter by:
// UserId
// Sort by:
// LastActivityDate
// Controls
//// Select Track (pass through a queue)
//curl - H "Authorization: MediaBrowser Token=\"TOKEN\"" - X POST 'BASEURL/Sessions/SESSIONID/Playing?playCommand=PlayNow&itemIds=XXX,YYY'