Jump to content

New Plugin - Custom Scripting | Emby ScripterX


Anthony Musgrove

Recommended Posts

PenkethBoy

Anthony

 

Could we have a comfirmation dialog for when you hit the delete button on an event

 

To prevent the dumbass issue i just had when i clicked it by mistake

 

Ta

  • Like 1
Link to comment
Share on other sites

ginjaninja

The problem for Anthony, as i currently see it, is that how does he "know" what's about to happen and also then decide what's a quiet period, how to group events (i.e. how are they related), know that the providerid look up was for the events just before - becomes a nightmare very quickly for everybody

 

Just had a thought do all the episodes get added in order - i suspect not as they will be in the order emby found them - not checked but something else to verify! :)

 

in relation to  onMediaItemAdded..

 

Dont know from a programming standpoint but from a logical viewpoint, a steady state might be  where there hasn't been any of the event type for X seconds

ie every event of that type puts the counter back to 60 seconds and then it counts down, and when reaches 0 its been a steady state for 60 seconds for that event. "collect up" all onMediatemItemAdded events  since the previous steady state time and now..

 

If scripterX could send such a collection of events to powershell, i reckon i could have a good go at putting some logic into the script to decide which ones to process and how. A crude assessment against path would most likely suffice 99% of time.

 

a steady state timeout would be a good start if not suffice (as long as that timeout doesnt halt all other processing/fetching (like it currently does when wait is implemented in the script) - convoluted fetching checks sound unnecessary.

 

Maybe its possible to engineer a bit more abstraction between the events happening and ScripterX 'firing' for them, and allow emby library maintenance/fetching to continue in the mean time.

Link to comment
Share on other sites

PenkethBoy

The timeout could also be done in a script - as you could "collectup" the events yourself and then decide what to do with them - say have another script periodically read a log file from the main processing script and act on that as an example

 

Yes it might make your life easier but ultimately we have to deal with what emby pumps out via scripterX and in a busy period that could be a lot of events of various different types

 

Also a simple timer would be problematic as a lot goes on in emby and you could have all sorts of timers running - if you had one per event type - as cant see how a single one would work

 

for example if a recording is running it fires off every few seconds so until the recording finishes the timer would be reset - but the downside is that any other update events you might be interested in would never get to your script until an unrelated recording finished - which might mean in an extreme case 2hrs later

 

 Not saying its impossible to do but personally i would like Anthony to finish the events,requests and bugs we have first before adding loads of complexity just to make our life easier. :)

Link to comment
Share on other sites

PenkethBoy

Anthony

 

Just been testing with adding Music Albums and noticed a few minor things which would be good if you could look at when you get time

EventType: ItemAdded Name: Duffy Emby ID: 91409 Emby Item Type: Folder Emby Library: %item.library.name%
EventType: ItemAdded Name: Rockferry Emby ID: 91410 Emby Item Type: MusicAlbum Emby Library: %item.library.name%
EventType: ItemAdded Name: 01 Rockferry Emby ID: 91411 Emby Item Type: Audio Emby Library: %item.library.name%
EventType: ItemAdded Name: 02 Warwick Avenue Emby ID: 91412 Emby Item Type: Audio Emby Library: %item.library.name%
....
EventType: ItemAdded Name: 09 I'm Scared Emby ID: 91419 Emby Item Type: Audio Emby Library: %item.library.name%
EventType: ItemAdded Name: 10 Distant Dreamer Emby ID: 91420 Emby Item Type: Audio Emby Library: %item.library.name%
EventType: ItemUpdated Name: Duffy Emby ID: 91409 Emby Item Type: Folder Emby Library: %item.library.name% Update Reason: None, ImageUpdate
EventType: ItemUpdated Name: Rockferry Emby ID: 91411 Emby Item Type: Audio Emby Library: %item.library.name% Update Reason: None, MetadataImport, ImageUpdate
EventType: ItemUpdated Name: Warwick Avenue Emby ID: 91412 Emby Item Type: Audio Emby Library: %item.library.name% Update Reason: None, MetadataImport, ImageUpdate
....
EventType: ItemUpdated Name: Rockferry Emby ID: 91410 Emby Item Type: MusicAlbum Emby Library: %item.library.name% Update Reason: None, MetadataImport, ImageUpdate, MetadataDownload, MetadataEdit
EventType: ItemUpdated Name: Duffy Emby ID: 91422 Emby Item Type: MusicArtist Emby Library: %item.library.name% Update Reason: None, ImageUpdate, MetadataDownload, MetadataEdit

I added a folder for the artist Duffy which contained the Album Folder Rockferry

 

The folder Duffy and rockferry were picked up fine - along with all the tracks - great

 

Apart from the missing Library.name

 

I noticed that there was no event for a MusicArtist being added - there is one for Duffy being updated though - again not sure if this is Emby or just missed off your list?

 

Thanks

Edited by PenkethBoy
Link to comment
Share on other sites

ginjaninja

as you could "collectup" the events yourself and then decide what to do with them - say have another script periodically read a log file from the main processing script and act on that as an example

 

 

I am going to try this approach as a learning opportunity....

My goals are

  • Avoid Emby library ingestion/fetching getting stalled by scripts called by ScripterX
  • bundle up multiple adds into more meaningful summarys (will concentrate on Episodes, Seasons, Series and Movies initially)
  • Introduce enough of a delay to ensure that an api call against the item id can return additional info.

although by the time i have it working i reckon Anthony will have achieved it more elegantly (crosses fingers) ;-)

 

and i was so close to having a script that might publish "media adds" to a Facebook group via Integromat, 2 steps forward 1 step back,all good learning :-)

 

This is what i had so far, Doesnt work with ScripterX because the ids arent populated with metadata at the time the api is called, but does work standalone if you feed it fetched IDs

NotifyonAddedd.zip

  • Like 1
Link to comment
Share on other sites

Anthony Musgrove

I am absolutely loving all this feedback and suggestions, I really appreciate it. I have some great ideas on how to handle these things more elegantly. Im going to start logging them as issues on github so i make sure I dont miss anything :)

Edited by Anthony.Musgrove
Link to comment
Share on other sites

Anthony Musgrove

Alrighty guys, I've gone through this entire thread and pulled out what I've found to be unaddressed issues or feature requests so far - and I've added them to the GitHub ISSUES list.  Could you check it out and add any more that you see fit :)

 

https://github.com/AnthonyMusgrove/Emby-ScripterX/issues

 

 
Also, I noticed this -
it does an api lookup on the ID to get further information not provided by scripterX posted by @@ginjaninja - this is great feedback.  Could you let me know what extra information you'd like to see ScripterX provide so I can add it where possible.  I'd love to get it to a point where ALL required information for a particular event is provided, so adding to this over time will be awesome.
 
Thank you so much guys, kindest regards,
Anthony
  • Like 1
Link to comment
Share on other sites

PenkethBoy

onScheduledTaskStart - would give you affectively onLibraryScanStart - would just need to filter the event by task.name and/or task.id

  • Like 1
Link to comment
Share on other sites

maegibbons

onScheduledTaskStart - would give you affectively onLibraryScanStart - would just need to filter the event by task.name and/or task.id

That wouldnt apply if a scan had been initiated by user at the library level.

 

Krs

 

Mark

 

A 'like' is always appreciated!

Link to comment
Share on other sites

PenkethBoy

Correct - as currently there is no event in emby for it to give feedback in the UI or logs - but think its down the priority list somewhere to be implemented.... 

 

So library scan at individual library level - disappear into emby

 

also applies to refresh of metadata on an item - gets queued up and happens but little feedback on that as well - but it might be something Anthony can capture even if only the refresh of an item

Link to comment
Share on other sites

PenkethBoy

Oh hang on - might have got the wrong end of the stick - so to try and clear up any confusion

 

Currently we have an event for OnLibraryScanComplete - this is specifically for the scheduled task  "scan media library" - so effectively scan everything

 

If onLibraryScanStart - means - when this scheduled task is started then we already have that as i outlined above

 

However if it means picking up a user running a manual scan on a library then thats a different thing and nothing to do with scheduled tasks - but could be picked up as an event hopefully - picking up when it ends could be more of a challenge

Edited by PenkethBoy
Link to comment
Share on other sites

PenkethBoy

Anthony

 

Need a bit of help as not sure what is actually happening with this

 

It appears the plugin calls my ScripterX script - which then pass the processing of a finish recording to another script - so in theory a separate process

 

First the plugin reports an error (not sure there is one - i will explain below)

 

and somehow picks up the output of a file created by the second script and posts that to the emby log

2020-05-02 13:06:28.255 Error Emby ScripterX: Error executing script '-File "S:\Coding\PowerShell\ScripterX\ScripterX.ps1" -EventType "RecordingEnded" -RecChId "103" -RecStrDate "02/05/2020 12:30:00" -RecEndDate "02/05/2020 13:30:00" -RecName "Ainsley's Mediterranean Cookbook" -RecChName "ITV HD" -RecChType "TV" -RecPath "F:\EmbyTest\Recordings\Series\Ainsley's Mediterranean Cookbook (2020)\Season 1\Ainsley's Mediterranean Cookbook S01E06 Marrakech.ts" -RecEpName "Marrakech" -RecEpNo "6" -RecSnNo "1"':  Comskip 0.82.006, made using ffmpeg
Donator build
 0:00:15 - 398 frames in 1.00 sec(398.00 fps), 1.00 sec(398.00 fps), 10%
 0:00:31 - 776 frames in 1.99 sec(389.95 fps), 1.00 sec(378.00 fps), 20%
 0:00:47 - 1179 frames in 2.99 sec(394.31 fps), 1.00 sec(403.00 fps), 31%
 0:00:01 - 1358 frames in 3.98 sec(341.21 fps), 1.00 sec(179.00 fps), 0%
 0:00:18 - 1800 frames in 4.98 sec(361.45 fps), 1.00 sec(442.00 fps), 12%
 0:00:35 - 2216 frames in 5.97 sec(371.19 fps), 1.00 sec(416.00 fps), 23%
 0:00:52 - 2649 frames in 6.97 sec(380.06 fps), 1.00 sec(433.00 fps), 34%
 0:01:11 - 3104 frames in 7.96 sec(389.95 fps), 1.00 sec(455.00 fps), 46%
 0:01:29 - 3564 frames in 8.96 sec(397.77 fps), 1.00 sec(460.00 fps), 58%
 0:01:46 - 3988 frames in 9.95 sec(400.80 fps), 1.00 sec(424.00 fps), 70%
 0:02:05 - 4462 frames in 10.94 sec(407.86 fps), 1.00 sec(474.00 fps), 82%
 0:02:22 - 4890 frames in 11.94 sec(409.55 fps), 1.00 sec(428.00 fps), 93%

5105 frames decoded in 12.42 seconds (411.03 fps)

this happens to be a comskip output file - no idea why it is doing that

 

the next line in the emby log has the same time stamp as above

2020-05-02 13:06:28.255 Info Emby ScripterX: Output from script '-File "S:\Coding\PowerShell\ScripterX\ScripterX.ps1" -EventType "RecordingEnded" -RecChId "103" -RecStrDate "02/05/2020 12:30:00" -RecEndDate "02/05/2020 13:30:00" -RecName "Ainsley's Mediterranean Cookbook" -RecChName "ITV HD" -RecChType "TV" -RecPath "F:\EmbyTest\Recordings\Series\Ainsley's Mediterranean Cookbook (2020)\Season 1\Ainsley's Mediterranean Cookbook S01E06 Marrakech.ts" -RecEpName "Marrakech" -RecEpNo "6" -RecSnNo "1"': [STREAM]
index=0
codec_name=hevc
codec_long_name=H.265 / HEVC (High Efficiency Video Coding)
profile=Main
codec_type=video
codec_time_base=1/25
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
width=1920
height=1080
coded_width=1920
coded_height=1088
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=120
color_range=tv
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
id=N/A
r_frame_rate=25/1
avg_frame_rate=25/1
time_base=1/1000
start_pts=1541
start_time=1.541000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:ENCODER=Lavc58.75.100 hevc_nvenc
TAG:DURATION=00:02:33.101000000
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/1000
start_pts=0
start_time=0.000000
duration_ts=N/A
duration=N/A
bit_rate=N/A
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=N/A
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:language=eng
TAG:ENCODER=Lavc58.75.100 aac
TAG:DURATION=00:02:31.935000000
[/STREAM]

Now its not reporting an error (so cant be an error in the config of the command line in the plugin)

and adding a ffprobe output file to the emby log

the output from the second script is just to files - nothing is written to the console - the second script is however called by -noNewWindow which may be the issue - i will test

 

1. So why is the plugin following the process to the second script - any ideas

2. why is it saying theres as error - then there isnt?

3. don't want to pollute my emby log with output files

4. genuine errors are fine obviously

Edited by PenkethBoy
Link to comment
Share on other sites

PenkethBoy

Anthony

 

Fixed it -NoNewWindow was the issue - need to check but it appears that runs in the same process as the ScripterX script

 

Changing to -WindowsStyle Hidden has fixed it

 

[edit]

 

from MS docs for start-process

 

"-NoNewWindow

Start the new process in the current console window. By default PowerShell opens a new window."

 

 

So uses same process - hence why ScripterX was doing some funky stuff! :)

Edited by PenkethBoy
  • Like 1
Link to comment
Share on other sites

PenkethBoy

Anthony

 

I want to copy my EmbyScripterX.xml file to another machine to save having to type in the script parameters again

 

But noticed the ActionId would be different - does this matter or will it cause issues?

 

Going to give it a go anyway :) But thought i would ask

 

Suggestion - low priority - but if the actionId's matter then maybe an import option to make the xml more portable?

 

[edit] - appears to have worked fine

 

I shut down emby first - then replaced the xml file and started emby - all worked fine

 

Ace!

Edited by PenkethBoy
  • Like 1
Link to comment
Share on other sites

Anthony Musgrove

Anthony

 

I want to copy my EmbyScripterX.xml file to another machine to save having to type in the script parameters again

 

But noticed the ActionId would be different - does this matter or will it cause issues?

 

Going to give it a go anyway :) But thought i would ask

 

Suggestion - low priority - but if the actionId's matter then maybe an import option to make the xml more portable?

 

[edit] - appears to have worked fine

 

I shut down emby first - then replaced the xml file and started emby - all worked fine

 

Ace!

 

Hey mate :) It should work perfectly!  hehe, yeah those action ids are simply randomly generated GUIDs to ensure no duplication of ids, but they're just a way that Scripter-X can differentiate between each one of them :)

Link to comment
Share on other sites

Anthony Musgrove

Tonight I had a query regarding Node.JS and Scripter-X integration.   It wasn't working for him, so I did some investigating and it works flawlessly.  He had the interpreter incorrectly set to /bin/bash when it should have been set to 'node'.  So now that I know it works flawlessly, Node.JS is on the compatibility list for scripting engines - which is awesome - because there are so many awesome bots and scripts eg discord/webhooks/etc that people would love to use to update their users on events etc.

 

I wrote this up with a sample script and a sample action setup at:

 

https://github.com/AnthonyMusgrove/Emby-ScripterX/tree/master/ExampleScripts/NodeJS

 

So so so exciting!

  • Like 1
Link to comment
Share on other sites

ginjaninja

I am going to try this approach as a learning opportunity....

My goals are

  • Avoid Emby library ingestion/fetching getting stalled by scripts called by ScripterX
  • bundle up multiple adds into more meaningful summarys (will concentrate on Episodes, Seasons, Series and Movies initially)
  • Introduce enough of a delay to ensure that an api call against the item id can return additional info.
although by the time i have it working i reckon Anthony will have achieved it more elegantly (crosses fingers) ;-)

 

and i was so close to having a script that might publish "media adds" to a Facebook group via Integromat, 2 steps forward 1 step back,all good learning :-)

 

This is what i had so far, Doesnt work with ScripterX because the ids arent populated with metadata at the time the api is called, but does work standalone if you feed it fetched IDs

attachicon.gifNotifyonAddedd.zip

be gentle its a proof of concept..

But i think the logic is working to crudely summarise child objects into parent objects based on path (tested on episodes,seasons,series so far)

I have tried to use a mutex to stop LogMediaAdds and ProcessAdded writing to queue at the same time

 

LogMediaAdds.PS1 is called by ScripterX to create the queue (LogMediaAdds.CSV)

ProcessAdded.PS1 is a scheduled script which for each 1st unprocessed object in queue

  • get related objects in queue
  • Which is the parent object?
  • Sends the parent object to PostAdded.PS1 (to kick off a facebook notification via Integromat in this case)
  • Marks related objects processed
  • Repeats until no objects in the queue but will pause for a minute (releasing the mutex) if queue items are still being added

https://emby.media/community/index.php?/topic/85620-additional-webhook-triggers/?p=880340

 

edit: added support for music albums, protection from special characters in path, and non functional types.

Edited by ginjaninja
Link to comment
Share on other sites

PenkethBoy

For LogMediaAdds - i dont think you need the mutex - i have a much more complex script that logs all the ScripterX events i have enabled (12 out of 16) as well as sending Toasts/Notifications to windows and setting other scripts running

 

The point is the log file can be written to in very quick succession without missing anything - i have tested mine with adding- in one go - 25 albums containing 313 songs and all were recorded in my log file

 

Reason is the your logmediaadds script is opened in a separate process for each scriptex call and the delay in between the scripterx calls is enough to ensure the log is not going to be open in another script - while the log file remains within reasonable bounds - if thats what you are trying to achieve

Link to comment
Share on other sites

Anthony Musgrove

Hey guys :)

 

I have just released version 2.2.8.0 (skip 2.2.7, there was an issue) - changes include:

 

- Global Tokens (Server, ScripterX) - see 'Global Tokens' section of the Actions page

- Renamed onScheduledTask to onScripterXScheduledTask

- Added various new tokens to Items - check out any Event that supports items

 

NOTE - provider ids are now available for item, season, series, etc.   These tokens are dynamic.

 

For example -   %item.meta.imdb% = imdb id for the item

%series.meta.imdb% = imdb for the series

%season.meta.imdb% = imdb for the season

 

But this is dynamic in the way that it matches for example %item.meta.anything% - anything being any provider that is available on your installation, for example %item.meta.tmdb = tmdb ID, and so forth.

 

Enjoy guys :) 

  • Like 1
Link to comment
Share on other sites

PenkethBoy

Anthony 

 

cool

 

just so i am certain i understand

 

item.meta.xxxx - where xxxx can be any valid emby data item or is it just limited to provider id's

Link to comment
Share on other sites

PenkethBoy

For LogMediaAdds - i dont think you need the mutex - i have a much more complex script that logs all the ScripterX events i have enabled (12 out of 16) as well as sending Toasts/Notifications to windows and setting other scripts running

 

The point is the log file can be written to in very quick succession without missing anything - i have tested mine with adding- in one go - 25 albums containing 313 songs and all were recorded in my log file

 

Reason is the your logmediaadds script is opened in a separate process for each scriptex call and the delay in between the scripterx calls is enough to ensure the log is not going to be open in another script - while the log file remains within reasonable bounds - if thats what you are trying to achieve

Actually on closer inspection i am seeing the need for a mutex - for events that happen with less than approx 20 milliseconds between them - hmm

Link to comment
Share on other sites

ginjaninja

Actually on closer inspection i am seeing the need for a mutex - for events that happen with less than approx 20 milliseconds between them - hmm

and also when the script creating the queue tries to write at the same time as script proessing the queue?

Link to comment
Share on other sites

PenkethBoy

for me it happens with a single script writing to its own log - each instance of the script writes to the same log file - so if i have two events within a very short interval ~20ms - then that appears to be too short a window for script instance one to finish writing before instance two trys to do the same

 

i was comparing the emby log entries for ScripterX with my log and noticed that a couple got missed

 

this was specifically with a load of scheduled tasks all firing at once after starting my test server that had been off for a while so emby does a catch up on these and fires them off almost at the same time

 

I wonder if Anthony could add a delay and queue up the events to overcome this? @@Anthony.Musgrove

As the time an event fires - is not time critical for me at least - so a short (ms) added delay would not impact what the scripts are going to do.

 

So say create a queue of events that fire off with a delay of say 50/100 ms between them or something similar - just to give the scripts a chance to do their stuff etc.....

 

However in your case where you are reading the same logfile/csv as being written to then a mutex is probably the best way to go - until i have another idea or thought :)

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