faster calibration curve generation
jellyfin intergration
This commit is contained in:
@@ -18,7 +18,16 @@ using json = nlohmann::json;
|
||||
// KPN sink node: accumulates SceneAnnotations and writes the final JSON on EOF.
|
||||
//
|
||||
// Verbosity::minimal — merges per-frame presence into contiguous time windows.
|
||||
// Output: { "movie": "...", "actors": [{ "name", "imdb_id", "scenes": [[t0,t1], ...] }] }
|
||||
// Output: {
|
||||
// "schema_version": 1, "movie": "...", "sample_fps": ..., "anneal_sec": ...,
|
||||
// "actors": [{ "name", "imdb_id", "tmdb_id", "jellyfin_id", "scenes": [[t0,t1], ...] }]
|
||||
// }
|
||||
// This is the spec consumed by the Jellyfin plugin: each actor carries every
|
||||
// identity key the gallery knows (empty string if not resolved). The plugin
|
||||
// should prefer "jellyfin_id" (direct Person item GUID) when non-empty, and
|
||||
// otherwise resolve "imdb_id"/"tmdb_id" against the item's People ProviderIds.
|
||||
// To find who's on screen at timestamp t, scan each actor's "scenes" for a
|
||||
// window where start <= t <= end.
|
||||
//
|
||||
// Verbosity::standard — per-frame detail including bboxes, similarity, unknowns.
|
||||
// Output: { "frames": [{ "t", "identified": [...], "unknowns": [...] }] }
|
||||
@@ -55,6 +64,10 @@ struct ResultSinkFunc {
|
||||
}
|
||||
|
||||
private:
|
||||
// Bump when the minimal/standard output JSON structure changes in a way
|
||||
// the Jellyfin plugin needs to detect.
|
||||
static constexpr int kSchemaVersion = 1;
|
||||
|
||||
static int count_known(const std::vector<IdentifiedActor>& v) {
|
||||
int n = 0;
|
||||
for (const auto& a : v) if (a.actor_idx >= 0) ++n;
|
||||
@@ -73,6 +86,7 @@ private:
|
||||
if (cfg_.verbosity == Verbosity::xray) {
|
||||
root = build_xray();
|
||||
} else {
|
||||
root["schema_version"] = kSchemaVersion;
|
||||
root["movie"] = cfg_.movie_path;
|
||||
root["sample_fps"] = cfg_.sample_fps;
|
||||
root["anneal_sec"] = cfg_.anneal_sec;
|
||||
@@ -91,20 +105,20 @@ private:
|
||||
}
|
||||
|
||||
struct ActorWindow {
|
||||
std::string name, imdb_id;
|
||||
std::string name, imdb_id, tmdb_id, jellyfin_id;
|
||||
std::vector<std::pair<double, double>> scenes; // [start_sec, end_sec]
|
||||
};
|
||||
|
||||
// Core logic: merge per-frame detections into annealed [start, end] windows.
|
||||
std::vector<ActorWindow> build_actor_windows() {
|
||||
struct Info { std::string name, imdb_id; };
|
||||
struct Info { std::string name, imdb_id, tmdb_id, jellyfin_id; };
|
||||
std::map<int, Info> actor_info;
|
||||
std::map<int, std::vector<double>> timestamps;
|
||||
|
||||
for (const auto& frame : frames_) {
|
||||
for (const auto& ia : frame.visible_actors) {
|
||||
if (ia.actor_idx < 0) continue;
|
||||
actor_info[ia.actor_idx] = {ia.name, ia.imdb_id};
|
||||
actor_info[ia.actor_idx] = {ia.name, ia.imdb_id, ia.tmdb_id, ia.jellyfin_id};
|
||||
timestamps[ia.actor_idx].push_back(frame.timestamp_sec);
|
||||
}
|
||||
}
|
||||
@@ -112,8 +126,10 @@ private:
|
||||
std::vector<ActorWindow> result;
|
||||
for (auto& [idx, ts_vec] : timestamps) {
|
||||
ActorWindow aw;
|
||||
aw.name = actor_info[idx].name;
|
||||
aw.imdb_id = actor_info[idx].imdb_id;
|
||||
aw.name = actor_info[idx].name;
|
||||
aw.imdb_id = actor_info[idx].imdb_id;
|
||||
aw.tmdb_id = actor_info[idx].tmdb_id;
|
||||
aw.jellyfin_id = actor_info[idx].jellyfin_id;
|
||||
|
||||
double win_start = ts_vec[0], win_end = ts_vec[0];
|
||||
for (size_t i = 1; i < ts_vec.size(); ++i) {
|
||||
@@ -136,9 +152,11 @@ private:
|
||||
for (const auto& [s, e] : aw.scenes)
|
||||
windows.push_back({s, e});
|
||||
json ja;
|
||||
ja["name"] = aw.name;
|
||||
ja["imdb_id"] = aw.imdb_id;
|
||||
ja["scenes"] = std::move(windows);
|
||||
ja["name"] = aw.name;
|
||||
ja["imdb_id"] = aw.imdb_id;
|
||||
ja["tmdb_id"] = aw.tmdb_id;
|
||||
ja["jellyfin_id"] = aw.jellyfin_id;
|
||||
ja["scenes"] = std::move(windows);
|
||||
actors.push_back(std::move(ja));
|
||||
}
|
||||
return actors;
|
||||
@@ -178,8 +196,10 @@ private:
|
||||
|
||||
if (ia.actor_idx >= 0) {
|
||||
json ja;
|
||||
ja["name"] = ia.name;
|
||||
ja["imdb_id"] = ia.imdb_id;
|
||||
ja["name"] = ia.name;
|
||||
ja["imdb_id"] = ia.imdb_id;
|
||||
ja["tmdb_id"] = ia.tmdb_id;
|
||||
ja["jellyfin_id"] = ia.jellyfin_id;
|
||||
ja["similarity"] = ia.similarity;
|
||||
ja["track_id"] = ia.track_id;
|
||||
ja["bbox"] = jbox;
|
||||
|
||||
Reference in New Issue
Block a user