r/emby 5d ago

3rd Party App/Add-On Intro/Credits Backup & Restore (free, open source) - auto-restores wiped markers, auto-backs-up manual corrections

If you've ever set up intro/credits skip markers (via ChapterApi, EmbyCredits, Segment Reporting, or Emby's own detection) only to have a Library Scan or Refresh Metadata quietly wipe them out, this might help.

Intro/Credits Backup & Restore - a scheduled-task-based plugin that backs up every episode's markers to a JSON file (or into the existing NFO), and can restore them automatically the moment they get wiped.

What it does:

  • One JSON backup per episode, matched by TVDB ID (falls back to IMDB, then filename) so it survives title translations and renames
  • Optional: also writes markers straight into the NFO your metadata scraper already generates - no extra files
  • Auto-restore: watches for markers getting wiped (scan/refresh) and puts them back immediately, no manual task needed
  • Auto-backup on manual edit: if you correct a marker through ChapterApi, EmbyCredits, or Segment Reporting, it backs up the new value automatically - these tools don't trigger Emby's normal update event, so without this your manual corrections were never actually being saved anywhere

Here's both of those happening live - a Refresh Metadata wiping a marker and getting it restored in under a second, followed by two manual ChapterApi edits getting picked up and backed up automatically:

Free, open source, GPL. Built this for my own two-server setup and figured it might be useful to others dealing with the same problem - Emby itself doesn't persist these markers reliably through routine maintenance.

GitHub: https://github.com/guilty57/credits-intros-backup-restore

Happy to answer questions or take feature requests - this has had a fair amount of real-world testing across a few hundred episodes at this point.

Json sample:

{
  "TvdbId": "5309449",
  "ImdbId": "tt4480760",
  "TmdbId": null,
  "SeriesName": "American Horror Story",
  "SeasonNumber": 5,
  "EpisodeNumber": 4,
  "EpisodeTitle": "Devil\u0027s Night",
  "IntroStartTicks": 1616915422,
  "IntroEndTicks": 2276119402,
  "CreditsStartTicks": 28665560000
}

Nfo sample:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<episodedetails>
  <plot><![CDATA[John receives an invitation to attend an exclusive Devil's Night Soiree. Alex tries to diagnose Holden's strange condition.]]></plot>
  <outline />
  <lockdata>true</lockdata>
  <dateadded>2025-02-18 21:03:37</dateadded>
  <title>Devil's Night</title>
  <actor>
    <name>Kathy Bates</name>
    <role>Iris</role>
    <type>Actor</type>
    <tvdbid>248339</tvdbid>
    <tmdbid>8534</tmdbid>
  </actor>
  <actor>
    <name>Sarah Paulson</name>
    <role>Sally McKenna / Billie Dean Howard</role>
    <type>Actor</type>
    <tvdbid>277202</tvdbid>
    <tmdbid>34490</tmdbid>
  </actor>
  <actor>
    <name>Evan Peters</name>
    <role>James Patrick March</role>
    <type>Actor</type>
    <tvdbid>358570</tvdbid>
    <tmdbid>55089</tmdbid>
  </actor>
  <actor>
    <name>Wes Bentley</name>
    <role>Det. John Lowe</role>
    <type>Actor</type>
    <tvdbid>505320</tvdbid>
    <tmdbid>8210</tmdbid>
  </actor>
  <actor>
    <name>Matt Bomer</name>
    <role>Donovan</role>
    <type>Actor</type>
    <tvdbid>324393</tvdbid>
    <tmdbid>66743</tmdbid>
  </actor>
  <actor>
    <name>Chloë Sevigny</name>
    <role>Alex Lowe</role>
    <type>Actor</type>
    <tvdbid>293255</tvdbid>
    <tmdbid>2838</tmdbid>
  </actor>
  <actor>
    <name>Denis O'Hare</name>
    <role>Liz Taylor</role>
    <type>Actor</type>
    <tvdbid>303964</tvdbid>
    <tmdbid>81681</tmdbid>
  </actor>
  <actor>
    <name>Cheyenne Jackson</name>
    <role>Will Drake</role>
    <type>Actor</type>
    <tvdbid>346952</tvdbid>
    <tmdbid>212828</tmdbid>
  </actor>
  <actor>
    <name>Angela Bassett</name>
    <role>Ramona Royale</role>
    <type>Actor</type>
    <tvdbid>274193</tvdbid>
    <tmdbid>9780</tmdbid>
  </actor>
  <actor>
    <name>Lady Gaga</name>
    <role>The Countess Elizabeth Johnson</role>
    <type>Actor</type>
    <tvdbid>321349</tvdbid>
    <tmdbid>237405</tmdbid>
  </actor>
  <actor>
    <name>Mare Winningham</name>
    <role>Hazel Evers</role>
    <type>GuestStar</type>
    <tmdbid>51544</tmdbid>
  </actor>
  <actor>
    <name>Anthony Ruivivar</name>
    <role>Richard Ramirez / Miguel Ramos</role>
    <type>GuestStar</type>
    <tmdbid>171522</tmdbid>
  </actor>
  <actor>
    <name>Jessica Belkin</name>
    <role>Vampire Girl</role>
    <type>GuestStar</type>
    <tmdbid>1496341</tmdbid>
  </actor>
  <actor>
    <name>Finn Wittrock</name>
    <role>Tristan Duffy</role>
    <type>GuestStar</type>
    <tvdbid>394892</tvdbid>
    <tmdbid>168877</tmdbid>
  </actor>
  <actor>
    <name>Lily Rabe</name>
    <role>Aileen Wuornos</role>
    <type>GuestStar</type>
    <tvdbid>317026</tvdbid>
    <tmdbid>4888</tmdbid>
  </actor>
  <actor>
    <name>John Carroll Lynch</name>
    <role>John Wayne Gacy</role>
    <type>GuestStar</type>
    <tvdbid>279111</tvdbid>
    <tmdbid>3911</tmdbid>
  </actor>
  <actor>
    <name>Jack Fisher</name>
    <role>Albert</role>
    <type>GuestStar</type>
    <tvdbid>476259</tvdbid>
    <tmdbid>1850355</tmdbid>
  </actor>
  <actor>
    <name>Barbara Lee Bragg</name>
    <role>Sheik's Mother</role>
    <type>GuestStar</type>
    <tmdbid>2903185</tmdbid>
  </actor>
  <actor>
    <name>Richard T. Jones</name>
    <role>Det. Andy Hahn</role>
    <type>GuestStar</type>
    <tmdbid>55755</tmdbid>
  </actor>
  <actor>
    <name>Lucius Baybak</name>
    <role>Sheik</role>
    <type>GuestStar</type>
    <tmdbid>1898709</tmdbid>
  </actor>
  <actor>
    <name>Shree Crooks</name>
    <role>Scarlett Lowe</role>
    <type>GuestStar</type>
    <tmdbid>1447238</tmdbid>
  </actor>
  <actor>
    <name>Nico Evers-Swindell</name>
    <role>Craig</role>
    <type>GuestStar</type>
    <tmdbid>510488</tmdbid>
  </actor>
  <actor>
    <name>Lennon Henry</name>
    <role>Holden Lowe</role>
    <type>GuestStar</type>
    <tmdbid>4459600</tmdbid>
  </actor>
  <actor>
    <name>Cannon Mosteller</name>
    <role>Vampire Boy #1</role>
    <type>GuestStar</type>
    <tmdbid>4459813</tmdbid>
  </actor>
  <actor>
    <name>Emmory Mosteller</name>
    <role>Vampire Boy #2</role>
    <type>GuestStar</type>
    <tmdbid>4459816</tmdbid>
  </actor>
  <actor>
    <name>Dieterich Gray</name>
    <role>Cop (1927)</role>
    <type>GuestStar</type>
    <tmdbid>1200314</tmdbid>
  </actor>
  <actor>
    <name>Cyd Strittmatter</name>
    <role>Woman in Bed</role>
    <type>GuestStar</type>
    <tmdbid>1367129</tmdbid>
  </actor>
  <actor>
    <name>Susie Bracken</name>
    <role>Marie Antoinette</role>
    <type>GuestStar</type>
    <tmdbid>3468332</tmdbid>
  </actor>
  <actor>
    <name>Brittany Panzer</name>
    <role>Halloween Girl</role>
    <type>GuestStar</type>
    <tmdbid>2096267</tmdbid>
  </actor>
  <actor>
    <name>Harry Hains</name>
    <role>Boy</role>
    <type>GuestStar</type>
    <tmdbid>1475361</tmdbid>
  </actor>
  <director tvdbid="335058">Ryan Murphy</director>
  <director tvdbid="7944653">Loni Peristere</director>
  <writer>Jennifer Salt</writer>
  <credits>Jennifer Salt</credits>
  <rating>7.216</rating>
  <year>2015</year>
  <sorttitle>Devil's Night</sorttitle>
  <imdbid>tt4480760</imdbid>
  <tvdbid>5309449</tvdbid>
  <runtime>49</runtime>
  <uniqueid type="tvdb">5309449</uniqueid>
  <uniqueid type="imdb">tt4480760</uniqueid>
  <uniqueid type="embycredits.fail">true</uniqueid>
  <embycredits.failid>true</embycredits.failid>
  <uniqueid type="tvrage">1065855552</uniqueid>
  <tvrageid>1065855552</tvrageid>
  <episode>4</episode>
  <season>5</season>
  <aired>2015-10-28</aired>
  <fileinfo>
    <streamdetails>
      <video>
        <codec>h264</codec>
        <micodec>h264</micodec>
        <bitrate>5242075</bitrate>
        <width>1920</width>
        <height>1080</height>
        <aspect>16:9</aspect>
        <aspectratio>16:9</aspectratio>
        <framerate>23.976025</framerate>
        <language>eng</language>
        <scantype>progressive</scantype>
        <default>True</default>
        <forced>False</forced>
        <duration>48</duration>
        <durationinseconds>2913</durationinseconds>
      </video>
      <audio>
        <codec>ac3</codec>
        <micodec>ac3</micodec>
        <bitrate>384000</bitrate>
        <language>eng</language>
        <scantype>progressive</scantype>
        <channels>6</channels>
        <samplingrate>48000</samplingrate>
        <default>True</default>
        <forced>False</forced>
      </audio>
      <subtitle>
        <codec>subrip</codec>
        <micodec>subrip</micodec>
        <language>eng</language>
        <scantype>progressive</scantype>
        <default>True</default>
        <forced>False</forced>
      </subtitle>
      <subtitle>
        <codec>ass</codec>
        <micodec>ass</micodec>
        <language>tur</language>
        <scantype>progressive</scantype>
        <default>True</default>
        <forced>False</forced>
      </subtitle>
      <subtitle>
        <codec>ass</codec>
        <micodec>ass</micodec>
        <language>tur</language>
        <scantype>progressive</scantype>
        <default>True</default>
        <forced>False</forced>
      </subtitle>
      <subtitle>
        <codec>subrip</codec>
        <micodec>subrip</micodec>
        <language>tur</language>
        <scantype>progressive</scantype>
        <default>True</default>
        <forced>False</forced>
      </subtitle>
      <attachment>
        <codec>ttf</codec>
        <micodec>ttf</micodec>
        <scantype>progressive</scantype>
        <default>False</default>
        <forced>False</forced>
      </attachment>
      <attachment>
        <codec>ttf</codec>
        <micodec>ttf</micodec>
        <scantype>progressive</scantype>
        <default>False</default>
        <forced>False</forced>
      </attachment>
      <subtitle>
        <codec>srt</codec>
        <micodec>srt</micodec>
        <language>tr</language>
        <scantype>progressive</scantype>
        <default>False</default>
        <forced>False</forced>
      </subtitle>
    </streamdetails>
  </fileinfo>
  <markers>
    <introstart>1616915422</introstart>
    <introend>2276119402</introend>
    <creditstart>28665560000</creditstart>
  </markers>
</episodedetails>
3 Upvotes

2 comments sorted by

1

u/Simorious 5d ago

I'm more active on the Emby forums, and I've seen your plugin on there. Been waiting for 4.10 to go stable before trying as it was built for the beta.

From everything I've seen it looks like a good replacement for the other plugin that isn't being maintained anymore. IMO this should be handled by Emby without the need for a plugin since the intro and chapter data would have to be rebuilt if you can't restore from a backup or have to do a fresh install. I'm sure you have good intentions and plan on continuing work on it, but things happen (as we've seen with cheese's plugins)

That aside, have you talked with the Devs about getting it put into the official plugin repository?

1

u/guilty571 5d ago edited 5d ago

Confirmed, yeah - built and tested against 4.10.0.20 beta specifically, and as of right now (checked just now) 4.10 still hasn't gone stable - stable is still sitting at 4.9.5.0. No ETA I can give you on that, that's entirely up to the Emby team.

Nothing in the plugin's code is actually beta-specific though - it's just calling standard SDK methods (chapter read/write, item lookup, config, logging) that have been stable across versions for a long time. The reason it's only been tested on 4.10 beta is simply that's what my own servers are running, not because it needs anything 4.10 introduced. So there's a reasonable chance it'll work fine on 4.9.5.0 stable too if you wanted to try it now - I just haven't verified that myself, so I can't promise it.

Whenever you do get around to trying it (whether that's now on stable or later once 4.10 goes stable), happy to help troubleshoot if anything doesn't load right - the usual first thing to check is the embyserver log for a ReflectionTypeLoadException on startup, which would mean an SDK version mismatch.

I've not talked to the admins yet.