Jump to content

Intros Backup Support Thread


Cheesegeezer

Recommended Posts

Cheesegeezer
59 minutes ago, rbjtech said:

Sorry Dave,  @CheesegeezerI have a tendency to steer clear of discussions involving crusher - it's just better for my well being ... 🤪

But to answer your question above (from a few weeks ago - my apologies) - re NFO's

The simple fact of the matter is NFO's are kept with the media on shared storage - so if you created a brand new Emby install (all with new internal ID's) and point to that same storage then the logic would be to either

a) just restore them with your plugin - because they still exist and are present and correct - nothing has changed.  No Provider ID link is required. 

b) when the Core team eventually complete the required basics from the Introskip core feature - they store the Introskip data in the NFO or if this plugin has been used/restored - it's already in there  - the same as they do all the other metadata/custom metadata.   It can then be automatically imported on a new build - again, in exactly the same was as the NFO is read today.  My view is keep things consistent and stop trying to have bespoke solutions for each function ..

I use the NFO version of the Introskip backup/restore - it works great. (so thanks!... as always..) :)

 

Nfo’s work good to a point until TMM is involved with multiple episodes.

there is always a json fallback that can be used. So there is redundancy feature included.

im not sure if you’re saying i need to enhance something or everything is fine. Lol 😂 

Link to comment
Share on other sites

rbjtech
19 minutes ago, Cheesegeezer said:

Nfo’s work good to a point until TMM is involved with multiple episodes.

I don't use TMM - but as there is one NFO per episode - I'm not sure why this would be a problem.

20 minutes ago, Cheesegeezer said:

im not sure if you’re saying i need to enhance something or everything is fine. Lol 😂 

Everything is fine .. 👍

  • Like 1
Link to comment
Share on other sites

Cheesegeezer
3 hours ago, rbjtech said:

I don't use TMM - but as there is one NFO per episode - I'm not sure why this would be a problem.

The multi episodes info are all stacked in the same xml.

but instead of wrapping them in a single root episodes element.  Each episode is a root element! Tut tut  not following w3c xml standards.

from XML Essentials - W3C

Quote

If you are already familiar with HTML, you can see that XML is very similar. However, the syntax rules of XML are strict: XML tools will not process files that contain errors, but instead will give you error messages so that you fix them. This means that almost all XML documents can be processed reliably by computer software.

3 hours ago, rbjtech said:

Everything is fine .. 👍

Lovely Jubleeee

Edited by Cheesegeezer
Link to comment
Share on other sites

rbjtech
27 minutes ago, Cheesegeezer said:

The multi episodes formats are all stacked in the same xml.

but instead of wrapping them in a single root episodes element.  Each episode is a root element! Tut tut  not following w3c xml standards.

from XML Essentials - W3C

 

Still not 100% with you tbh.

If I have 3 versions of the same episode -

sameepisodename - version 1.mkv

sameepisodename - version 2.mkv

sameepisodename - version 3.mkv

 

why would I not have 3 corresponding NFO files ?  

 

sameepisodename - version 1.nfo

sameepisodename - version 2.nfo

sameepisodename - version 3.nfo

 

the Introskip XML data in them is identical - but the other non Introskip entries will/may not be.

On your plugin - you write the Introskip data to all 3 - I've checked, each version of the nfo has the same Introdata - which is correct.

 

So if there is non-standard XML in the NFO (written by TMM) - do you really care - as it only applied to the video file that the nfo is matched to by name  - or is TMM not complying with the 

<episodedetails>

</episodedetails>

structure ?

(and if so, how is emby handling that ?)

Edited by rbjtech
Link to comment
Share on other sites

crusher11

Could not load file or assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.

at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.WriteInfoToJson(BaseItem item, String seriesName, Nullable`1 seasonNumber, Nullable`1 episodeNumber, Nullable`1 episodeNumEnd, String tvdbId, String imdbId, String tmdbId, Int64 introStartTime, Int64 introEndTime, Int64 creditStartTime)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine&amp; stateMachine)
at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.WriteInfoToJson(BaseItem item, String seriesName, Nullable`1 seasonNumber, Nullable`1 episodeNumber, Nullable`1 episodeNumEnd, String tvdbId, String imdbId, String tmdbId, Int64 introStartTime, Int64 introEndTime, Int64 creditStartTime)
at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.Execute(CancellationToken cancellationToken, IProgress`1 progress)
at Emby.Server.Implementations.ScheduledTasks.ScheduledTaskWorker.ExecuteInternal(TaskOptions options)

Link to comment
Share on other sites

Cheesegeezer
9 minutes ago, rbjtech said:

Still not 100% with you tbh.

If I have 3 versions of the same episode -

sameepisodename - version 1.mkv

sameepisodename - version 2.mkv

sameepisodename - version 3.mkv

 

why would I not have 3 corresponding NFO files ?  

 

sameepisodename - version 1.nfo

sameepisodename - version 2.nfo

sameepisodename - version 3.nfo

 

the Introskip XML data in them is identical - but the other non Introskip entries will/may not be.

On your plugin - you write the Introskip data to all 3 - I've checked, each version of the nfo has the same Introdata - which is correct.

 

So if there is non-standard XML in the NFO (written by TMM) - do you really care - as it only applied to the video file that the nfo is matched to by name  - or is TMM not complying with the 

<episodedetails>

</episodedetails>

structure ?

(and if so, how is emby handling that ?)

Rich, this is multi episodes not multi versions (geez lol you are really into your multiversions at the moment hahahahaha)

So Episode 1,2 are contained in one video container.  Such as House S02E01S02E02.mkv

And the TMM doesn't have a SINGLE  Root Element it has 2 root elements that fail when using any XML reader/writer.

in the example below from TMM multiepisode nfo there are 2 root <episodedetails>

What they should have done is wrap it in a singe root element named <Episodes> <episodedetails /> <episodedetails /> </Episodes

Spoiler

<episodedetails>
  <title>Space Chicken</title>
  <season>2</season>
  <episode>1</episode>
  <aired>2018-06-18</aired>
  <plot>To impress his new neighbors, Cricket attempts to launch a chicken into space.</plot>
  <uniqueid type="tvdb" default="true">6719828</uniqueid>
  <uniqueid type="sonarr">94838</uniqueid>
  <thumb>https://artworks.thetvdb.com/banners/episodes/342059/6719828.jpg</thumb>
  <watched>false</watched>
  <fileinfo>
    <streamdetails>
      <video>
        <aspect>1.7777778</aspect>
        <bitrate>0</bitrate>
        <codec>h264</codec>
        <framerate>23.976023976023976023976023976</framerate>
        <height>1080</height>
        <scantype>Progressive</scantype>
        <width>1920</width>
        <duration>22.027733333333334</duration>
        <durationinseconds>1322</durationinseconds>
      </video>
      <audio>
        <bitrate>224000</bitrate>
        <channels>2</channels>
        <codec>EAC3</codec>
        <language>eng</language>
      </audio>
      <subtitle>
        <language>engeng</language>
      </subtitle>
    </streamdetails>
  </fileinfo>
</episodedetails>
<episodedetails>
  <title>Steak Night</title>
  <season>2</season>
  <episode>2</episode>
  <aired>2018-06-18</aired>
  <plot>The Greens are excited to continue their traditional monthly steak dinner, but Cricket accidentally loses the steaks on the subway.</plot>
  <uniqueid type="tvdb" default="true">6719831</uniqueid>
  <uniqueid type="sonarr">94839</uniqueid>
  <thumb>https://artworks.thetvdb.com/banners/episodes/342059/6719831.jpg</thumb>
  <watched>false</watched>
  <fileinfo>
    <streamdetails>
      <video>
        <aspect>1.7777778</aspect>
        <bitrate>0</bitrate>
        <codec>h264</codec>
        <framerate>23.976023976023976023976023976</framerate>
        <height>1080</height>
        <scantype>Progressive</scantype>
        <width>1920</width>
        <duration>22.027733333333334</duration>
        <durationinseconds>1322</durationinseconds>
      </video>
      <audio>
        <bitrate>224000</bitrate>
        <channels>2</channels>
        <codec>EAC3</codec>
        <language>eng</language>
      </audio>
      <subtitle>
        <language>engeng</language>
      </subtitle>
    </streamdetails>
  </fileinfo>
</episodedetails>

 

  • Thanks 1
Link to comment
Share on other sites

rbjtech
8 minutes ago, Cheesegeezer said:

Rich, this is multi episodes not multi versions (geez lol you are really into your multiversions at the moment hahahahaha)

So Episode 1,2 are contained in one video container.  Such as House S02E01S02E02.mkv

And the TMM doesn't have a SINGLE  Root Element it has 2 root elements that fail when using any XML reader/writer.

in the example below from TMM multiepisode nfo there are 2 root <episodedetails>

What they should have done is wrap it in a singe root element named <Episodes> <episodedetails /> <episodedetails /> </Episodes

  Hide contents

<episodedetails>
  <title>Space Chicken</title>
  <season>2</season>
  <episode>1</episode>
  <aired>2018-06-18</aired>
  <plot>To impress his new neighbors, Cricket attempts to launch a chicken into space.</plot>
  <uniqueid type="tvdb" default="true">6719828</uniqueid>
  <uniqueid type="sonarr">94838</uniqueid>
  <thumb>https://artworks.thetvdb.com/banners/episodes/342059/6719828.jpg</thumb>
  <watched>false</watched>
  <fileinfo>
    <streamdetails>
      <video>
        <aspect>1.7777778</aspect>
        <bitrate>0</bitrate>
        <codec>h264</codec>
        <framerate>23.976023976023976023976023976</framerate>
        <height>1080</height>
        <scantype>Progressive</scantype>
        <width>1920</width>
        <duration>22.027733333333334</duration>
        <durationinseconds>1322</durationinseconds>
      </video>
      <audio>
        <bitrate>224000</bitrate>
        <channels>2</channels>
        <codec>EAC3</codec>
        <language>eng</language>
      </audio>
      <subtitle>
        <language>engeng</language>
      </subtitle>
    </streamdetails>
  </fileinfo>
</episodedetails>
<episodedetails>
  <title>Steak Night</title>
  <season>2</season>
  <episode>2</episode>
  <aired>2018-06-18</aired>
  <plot>The Greens are excited to continue their traditional monthly steak dinner, but Cricket accidentally loses the steaks on the subway.</plot>
  <uniqueid type="tvdb" default="true">6719831</uniqueid>
  <uniqueid type="sonarr">94839</uniqueid>
  <thumb>https://artworks.thetvdb.com/banners/episodes/342059/6719831.jpg</thumb>
  <watched>false</watched>
  <fileinfo>
    <streamdetails>
      <video>
        <aspect>1.7777778</aspect>
        <bitrate>0</bitrate>
        <codec>h264</codec>
        <framerate>23.976023976023976023976023976</framerate>
        <height>1080</height>
        <scantype>Progressive</scantype>
        <width>1920</width>
        <duration>22.027733333333334</duration>
        <durationinseconds>1322</durationinseconds>
      </video>
      <audio>
        <bitrate>224000</bitrate>
        <channels>2</channels>
        <codec>EAC3</codec>
        <language>eng</language>
      </audio>
      <subtitle>
        <language>engeng</language>
      </subtitle>
    </streamdetails>
  </fileinfo>
</episodedetails>

 

With you now ! Sorry Dave - yea, I have multi-version on the brain .. 🤣

  • Haha 1
Link to comment
Share on other sites

crusher11
On 12/8/2022 at 12:01 AM, crusher11 said:

Could not load file or assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.

at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.WriteInfoToJson(BaseItem item, String seriesName, Nullable`1 seasonNumber, Nullable`1 episodeNumber, Nullable`1 episodeNumEnd, String tvdbId, String imdbId, String tmdbId, Int64 introStartTime, Int64 introEndTime, Int64 creditStartTime)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine&amp; stateMachine)
at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.WriteInfoToJson(BaseItem item, String seriesName, Nullable`1 seasonNumber, Nullable`1 episodeNumber, Nullable`1 episodeNumEnd, String tvdbId, String imdbId, String tmdbId, Int64 introStartTime, Int64 introEndTime, Int64 creditStartTime)
at Intros.Backup.ScheduledTasks.IntrosBackupScheduledTask.Execute(CancellationToken cancellationToken, IProgress`1 progress)
at Emby.Server.Implementations.ScheduledTasks.ScheduledTaskWorker.ExecuteInternal(TaskOptions options)

I'm getting this error at midnight every night. Do you need a log? 

Link to comment
Share on other sites

Cheesegeezer
2 hours ago, crusher11 said:

I'm getting this error at midnight every night. Do you need a log? 

I know what the issue is

  • Like 1
Link to comment
Share on other sites

Cheesegeezer
43 minutes ago, TeamB said:

you should be able to at least read the xml, i have had to do this in the past when reading an xml logging stream, this sort of system is not used much now but 10 years or so ago it was more common. see an example here

https://stackoverflow.com/questions/5042902/xml-error-there-are-multiple-root-elements

Yeah and this was when xml was less strict. No chance now. Apart from converting to text and wrapping into a single root processing and writing back to original format… its a lot of crap to deal with when they should update their format to be inline with current standards of xml format. Geez this was all implemented back in the late 90’s lol 😂 when the original xbmc was launched, i had it running on my chipped xbox… it was awesome 

 

Edited by Cheesegeezer
Link to comment
Share on other sites

Cheesegeezer

Here ya go @TeamB

straight  from  your link

BE7C3CE0-8CC1-410D-B065-0E340E864285.thumb.jpeg.21c727634a8d0428b806b4d4402e1de2.jpeg
and to add to this I’ve tried all the relaxation methods. They don’t work anymore 

Edited by Cheesegeezer
Link to comment
Share on other sites

TeamB

I am not saying it is a correct xml document, all I am saying is I have delt with this in the past, there are two approaches in the link, the relaxed DTD approach I have used in the past to parse a stream of log data. The other one where you load the "xml" into a string and wrap it in a new root element is also usable if you are working with static documents.

Link to comment
Share on other sites

Cheesegeezer
1 minute ago, TeamB said:

I am not saying it is a correct xml document, all I am saying is I have delt with this in the past, there are two approaches in the link, the relaxed DTD approach I have used in the past to parse a stream of log data. The other one where you load the "xml" into a string and wrap it in a new root element is also usable if you are working with static documents.

Exactly and thats what I’m saying dtd is invalid now, string wrapping is a chore, with validation extensions. I didn’t even know tmm existed before i launched this plugin lol 😂 so it targets the emby ecosystem and there is redundancy if nfo fails, my json backup option can pick this up no probs. 

Link to comment
Share on other sites

TeamB

valid or not people do it and sometimes you need to deal, code can parse multiple root level elements, using the standard xml reader

using System.Text;
using System.Xml;

namespace XmpParse
{
    internal class Program
    {
        static void Main(string[] args)
        {

            //string doc = @"<xml><string>hello</string></xml>";
            string doc = @"<item><comment>hello</comment></item><item><comment>world</comment></item>";
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(doc));

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            using (XmlReader reader = XmlReader.Create(ms, settings))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            Console.WriteLine(reader.Name);
                            break;
                        case XmlNodeType.Text:
                            Console.WriteLine(reader.Value);
                            break;
                        case XmlNodeType.XmlDeclaration:
                        case XmlNodeType.ProcessingInstruction:
                            Console.WriteLine(reader.Name + " : " + reader.Value);
                            break;
                        case XmlNodeType.Comment:
                            Console.WriteLine("Comment : " + reader.Value);
                            break;
                        case XmlNodeType.EndElement:
                            Console.WriteLine("END");
                            break;
                    }
                }
            }
            Console.WriteLine("Done");
        }
    }
}

output

item
comment
hello
END
END
item
comment
world
END
END
Done

is it a pain in the ass, yes, do you actually want to have to go to all this trouble, probably not, but it can be done.

 

 

 

  • Agree 1
Link to comment
Share on other sites

Cheesegeezer
3 minutes ago, TeamB said:

valid or not people do it and sometimes you need to deal, code can parse multiple root level elements, using the standard xml reader

using System.Text;
using System.Xml;

namespace XmpParse
{
    internal class Program
    {
        static void Main(string[] args)
        {

            //string doc = @"<xml><string>hello</string></xml>";
            string doc = @"<item><comment>hello</comment></item><item><comment>world</comment></item>";
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(doc));

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            using (XmlReader reader = XmlReader.Create(ms, settings))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            Console.WriteLine(reader.Name);
                            break;
                        case XmlNodeType.Text:
                            Console.WriteLine(reader.Value);
                            break;
                        case XmlNodeType.XmlDeclaration:
                        case XmlNodeType.ProcessingInstruction:
                            Console.WriteLine(reader.Name + " : " + reader.Value);
                            break;
                        case XmlNodeType.Comment:
                            Console.WriteLine("Comment : " + reader.Value);
                            break;
                        case XmlNodeType.EndElement:
                            Console.WriteLine("END");
                            break;
                    }
                }
            }
            Console.WriteLine("Done");
        }
    }
}

output

item
comment
hello
END
END
item
comment
world
END
END
Done

is it a pain in the ass, yes, do you actually want to have to go to all this trouble, probably not, but it can be done.

 

 

 

I’ll revisit it for sure, but i spent a couple of days trying to handle it and couldn’t. Can i test your code in the plugin? 
 

Cheers matey 👍

Link to comment
Share on other sites

TeamB

that example code it from the stackoverflow post above, it just an example of how to parse weird xml using a call back approach.

using this approach you need to parse the doc using call backs for each of the nodes, you are in effect building a DTD parser from scratch so you can have your xml parser have whatever rules you want. just be warned it is a pain in the ass to fully parse a document like this. The way I have done it in the past is parse the document into a known class I define, filling in the fields of your class as they are encountered in the document. Then once parsed use your class to do your actions. this keeps the parsing and usage of the data separate.

Link to comment
Share on other sites

Cheesegeezer

If i can get it to work, i will create a helper class and post on git. So we all dont have to go theu the issues.

Link to comment
Share on other sites

Cheesegeezer
2 minutes ago, TeamB said:

that example code it from the stackoverflow post above, it just an example of how to parse weird xml using a call back approach.

using this approach you need to parse the doc using call backs for each of the nodes, you are in effect building a DTD parser from scratch so you can have your xml parser have whatever rules you want. just be warned it is a pain in the ass to fully parse a document like this. The way I have done it in the past is parse the document into a known class I define, filling in the fields of your class as they are encountered in the document. Then once parsed use your class to do your actions. this keeps the parsing and usage of the data separate.

Yup this is the approach I initially took and everything was chucking exceptions at me, i figured a way to check the document and if it had more than one root i would catch the exception and continue.

but like i said, the nfo isn’t even required for backup restore, you can still export to json and store this on a flash, external, remote location and import it on a completely brand new emby server install and after all your libraries are dealt with, you can backup from json and boom everything is written to the database for chapters and markers

Link to comment
Share on other sites

Cheesegeezer

Nfo is a way of future proofing but the core would need to adopt the import intros tags from the nfo and flag the episode as processed.

Edited by Cheesegeezer
Link to comment
Share on other sites

  • 4 weeks later...
TheDelo187

@Cheesegeezer Sooooo I just finally finished all the intro detection and now that I want to write the backups to both json and nfo and I have been greeted with this error which doesn't make much sense as I have had a Premium Lifetime Sub for years and this worked atleast when I was backing up to just json on Tuesday 1/3/2023

Status

You have a Lifetime Emby Premiere plan and your device usage is well within your limit.

2023-01-05 16:08:35.428 Info Intros Backup-Backup: Either you are not a valid Emby Premium Subscriber or your Trial Period has expired, Please consider supporting plugin and the Emby Project by purchasing a Premium Subscription.
Link to comment
Share on other sites

Cheesegeezer
1 hour ago, TheDelo187 said:

@Cheesegeezer Sooooo I just finally finished all the intro detection and now that I want to write the backups to both json and nfo and I have been greeted with this error which doesn't make much sense as I have had a Premium Lifetime Sub for years and this worked atleast when I was backing up to just json on Tuesday 1/3/2023

Status

You have a Lifetime Emby Premiere plan and your device usage is well within your limit.

2023-01-05 16:08:35.428 Info Intros Backup-Backup: Either you are not a valid Emby Premium Subscriber or your Trial Period has expired, Please consider supporting plugin and the Emby Project by purchasing a Premium Subscription.

Did you purchase the plugin? 
i will amend the wording on next release for that error

Link to comment
Share on other sites

TheDelo187
13 hours ago, Cheesegeezer said:

Did you purchase the plugin? 
i will amend the wording on next release for that error

Welp therein lies the confusion I guess I missed the paid feature part. New problem, my paypal email and my emby email differ and I tried doing a one time debit card payment so I can specify the proper one (I do not want to make another account with Paypal) after I put in my card info the site just refreshes for no reason and throughs a "generic error" url at me with a blank page. Is there anyway I can send you my key and both my email for emby and my paypal email so I can give you some money and get this thing registered?

Link to comment
Share on other sites

Cheesegeezer
1 minute ago, TheDelo187 said:

Welp therein lies the confusion I guess I missed the paid feature part. New problem, my paypal email and my emby email differ and I tried doing a one time debit card payment so I can specify the proper one (I do not want to make another account with Paypal) after I put in my card info the site just refreshes for no reason and throughs a "generic error" url at me with a blank page. Is there anyway I can send you my key and both my email for emby and my paypal email so I can give you some money and get this thing registered?

I did this recently with another user.  but i will need to get @ebr involved who can link the two.

I will send a PM to you and Eric and once he surfaces (i'm UK, he's US, so 6ish hours difference)

Standby and thanks

Link to comment
Share on other sites

TheDelo187
5 minutes ago, Cheesegeezer said:

I did this recently with another user.  but i will need to get @ebr involved who can link the two.

I will send a PM to you and Eric and once he surfaces (i'm UK, he's US, so 6ish hours difference)

Standby and thanks

You're a treasure! Thanks

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