Jump to content
View in the app

A better way to browse. Learn more.

PreShow Experience

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

All Activity

This stream auto-updates

  1. Past hour
  2. Great work on this. I have a lot of new functionality that I've worked on with PreShow that is on a similar path to this. I may add an action or similar functionality to make it easier to do stuff like this without the need to modify PreShow.
  3. Today
  4. I've been working on a system that generates movie-specific content on the fly every time you launch a PreShow sequence. Instead of static slides, PSE now dynamically creates a "Tonight's Feature" title card and (optionally) 30 custom trivia slides tailored to whatever film you're about to watch. I wanted to share the approach in case others want to build on it. Here's what it looks like in practice: you press Start PreShow on "Fargo," and a few seconds later your sequence opens with a custom title card reading "FARGO" on a theater marquee background, followed by 30 slides of trivia, behind-the-scenes facts, and Q&A specific to that film — all generated fresh every time. The ProblemPSE's slideshow module is great for static trivia packs, but I wanted content that adapts to whatever movie I'm watching. The challenge is that PSE caches slideshow content when it builds the sequence, so you can't just generate images asynchronously and hope they show up in time. I tried a lot of approaches that didn't work before finding one that does: Action module with Python script — PSE runs Python actions inside Kodi's embedded Python, which doesn't have libraries like Pillow installed. Also runs asynchronously — PSE moves to the next module before the script finishes. Generating images and hoping the slideshow picks them up — PSE caches the slide directory contents at sequence build time. If your images aren't there yet, they won't appear. Overwriting existing placeholder images — PSE caches the actual image data, not the file reference. Overwriting the file after caching has no effect. Skin button interception — Tried adding a RunScript call before PSE launches from the skin's context menu. Unreliable timing. The Solution: Hooking into experience.pyThe key insight is that PSE resolves the feature film's metadata (title, genre, year, cast, etc.) before it builds and caches the sequence. There's a window between "PSE knows what movie you picked" and "PSE scans the slideshow directories" where we can inject code. The hook goes into PSE's experience.py, specifically in the method that resolves the feature film from Kodi's library. After PSE appends the feature to its internal list, we write the metadata to temp files and call external Python scripts that generate our content: # In experience.py, after self.features.append(feature) # and before "if not self.features: return False" if self.features and self.features[-1].title: import subprocess import json as _json _feat = self.features[-1] # Write title for the compositing script with open("/tmp/pse_feature_title.txt", "w") as _f: _f.write(_feat.title) # Write full metadata as JSON for other scripts _meta = { "title": _feat.title, "year": getattr(_feat, "year", 0), "genres": getattr(_feat, "genres", []), "directors": getattr(_feat, "directors", []), "cast": getattr(_feat, "cast", [])[:10], "rating": str(getattr(_feat, "rating", "")), "runtime": getattr(_feat, "runtime", 0), } with open("/tmp/pse_feature_metadata.json", "w") as _f: _json.dump(_meta, _f) # Run content generation scripts (synchronous — PSE waits) subprocess.call(["/usr/bin/python3", "/path/to/your/script.py"]) The critical detail is subprocess.call — this blocks PSE until the script finishes. PSE doesn't proceed to sequence building until our content is generated and sitting in the slideshow directory. Important: We call /usr/bin/python3 (system Python) rather than running inside Kodi's Python. This gives us access to any pip-installed library — Pillow for image compositing, requests for API calls, whatever you need. Kodi's embedded Python is limited to its bundled packages. Finding the Right SpotTo find where to inject, look for this pattern in experience.py: feature = self.featureFromId(movieid, episodeid) if feature: self.features.append(feature) # >>> YOUR HOOK GOES HERE <<< if not self.features: return False return True Search for self.features.append(feature) near featureFromId — there's one instance in the method that handles the "Start PreShow" button press. On my install it's around line 1060. After editing, you must delete the bytecode cache or Kodi will keep running the old version: rm ~/.kodi/addons/script.preshowexperience/resources/lib/__pycache__/experience.cpython-*.pyc Then restart Kodi. What You Can Build With ThisOnce you have the hook in place, the feature metadata is available to any external script. Here's what's in the self.features[-1] object: title — Movie title year — Release year genres — List of genres (Action, Horror, Drama, etc.) directors — Director names cast — Cast list with names and roles rating — MPAA rating runtime — Runtime in seconds studios — Studio names tags — Kodi library tags With this data you could: Generate a custom "Tonight's Feature" title card with the movie name Create genre-themed trivia (horror trivia for horror films, sci-fi for sci-fi) Select decade-appropriate trailers by dynamically populating a trailer directory Generate MPAA-style rating cards Pick studio-specific intro bumpers Call an AI API to generate movie-specific trivia and Q&A slides Create "on this day in cinema history" slides based on the current date and film era Example 1: Dynamic Title CardMy first use case was a "Tonight's Feature" title card — a theater marquee background with the movie title composited in a vintage font. The script reads the title from the temp file, uses Pillow to render text onto a template image, and saves it to a slideshow directory. The core of the compositing script: from PIL import Image, ImageDraw, ImageFont def generate_title_card(title): # Load background template img = Image.open("/tmp/template.png") draw = ImageDraw.Draw(img) font = ImageFont.truetype("/tmp/myfont.ttf", 80) # Center the title bbox = draw.textbbox((0, 0), title.upper(), font=font) text_w = bbox[2] - bbox[0] x = (1920 - text_w) // 2 draw.text((x, 450), title.upper(), font=font, fill=(0, 0, 0)) img.save("/path/to/pse/Slideshow/Tonight/tonight.png") The real script has auto-sizing logic (shrinks the font for long titles), word wrapping, and handles the CIFS font loading issue (Pillow can't load fonts from network shares — copy to /tmp/ first). But the concept is this simple. In the PSE sequence, a Slideshow module points at the Tonight directory and displays whatever image is in there. Runtime: About 1.4 seconds on a Vero 5. Barely noticeable in the PSE launch flow. Example 2: AI-Generated Trivia SlidesThe more ambitious extension calls the Claude API with the movie's metadata and asks it to generate trivia facts and Q&A pairs. The response is parsed and rendered into 30 slides — 10 trivia facts plus 10 question/answer pairs (20 slides). The flow: import json import urllib.request def generate_trivia(metadata): api_key = open("/home/user/.config/pse/api.key").read().strip() prompt = f"""Generate trivia about "{metadata['title']}" ({metadata['year']}). Director: {', '.join(metadata['directors'])} Cast: {', '.join(metadata['cast'][:5])} Return JSON with: - 10 trivia facts (behind the scenes, connections, legacy, etc.) - 10 Q&A pairs (movie trivia questions with answers) """ payload = json.dumps({ "model": "claude-sonnet-4-20250514", "max_tokens": 6000, "messages": [{"role": "user", "content": prompt}] }).encode() req = urllib.request.Request("https://api.anthropic.com/v1/messages", data=payload) req.add_header("Content-Type", "application/json") req.add_header("x-api-key", api_key) req.add_header("anthropic-version", "2023-06-01") resp = urllib.request.urlopen(req, timeout=30) data = json.loads(resp.read()) trivia = json.loads(data['content'][0]['text']) # Render each item as a slide image with Pillow for i, item in enumerate(trivia): render_slide(item, i, metadata['title']) Each slide gets rendered with a vintage cinema aesthetic — dark background, golden category headers, cream body text, decorative borders. Question slides use blue headers, answer slides use green. The trivia generation is opt-in — I have a toggle script that creates/removes a flag file (/tmp/pse_trivia_enabled). The generation script checks for this file and skips if it's not there. A Kodi notification confirms the toggle state. Runtime: About 8-10 seconds for the API call plus slide rendering. A progress notification shows during generation so you know it's working. Tips for ImplementationCIFS/Network Share Gotcha: If your PSE content lives on a network share, Pillow's FreeType library cannot load fonts from CIFS mounts. Always copy fonts and templates to /tmp/ before opening them with Pillow. Bytecode Cache: Kodi caches compiled Python as .pyc files. Every time you edit experience.py, delete the cache and restart Kodi or your changes won't take effect. PSE Updates: When PSE updates, experience.py gets overwritten. Keep a backup of your modified version and re-apply the hook after updates. The hook is small enough that re-applying takes 30 seconds. Testing: You can test your generation scripts independently from the command line: echo "Alien" > /tmp/pse_feature_title.txt echo '{"title":"Alien","year":1979,"genres":["Horror","Sci-Fi"],"directors":["Ridley Scott"]}' > /tmp/pse_feature_metadata.json python3 /path/to/your/script.py Then check the output directory for your generated slides. Keep Scripts Fast: Since subprocess.call blocks PSE initialization, your scripts need to finish in a reasonable time. The title card takes ~1.4 seconds, the AI trivia takes ~8-10 seconds. Much longer than that and the delay before the sequence starts becomes noticeable. Sequence SetupMy PSE sequence order: Slideshow — Tonight directory (dynamic title card, 30-60 second duration) Slideshow — Trivia directory (AI trivia slides, 10 second per slide) Trailer modules Audio Format Bumper Action — Enable refresh rate switching Feature The two slideshow modules point at directories that get populated fresh every time by the hook scripts. Everything else in the sequence is standard PSE configuration. What's NextI'm exploring a few more ideas with this system: dynamically selecting trailer folders based on the feature's genre/decade, generating "cinema history" slides that tie the film to its cultural moment, and creating custom intermission cards for double features. The hook pattern is flexible enough that any script with access to the movie metadata can feed content into the sequence. If anyone builds on this or has questions about the implementation, happy to help. The hardest part was figuring out the right injection point — once that's solved, the rest is just Python scripting.
  5. Yesterday
  6. We work with a variety of intro templates that can be found on various stock sites, like Envato. They typically require apps like Adobe After Effects to render custom content into the template, but it's quite effective. You can search for a variety of known studio intros or work with logo reveals that are completely different from those found at the head of major motion pictures. There are also some people who you can pay to have intros built in the style of known studio intros. We couldn't find a Marvel style template for a student film festival, but found someone who had the ability to make one for us for about $50. It was incredibly similar to the comic book style Marvel intro - the kids were confused at first as this Marvel style intro began and then they lost their minds when they realize it was the title of the festival. They are out there. Just need to Google ;-)
  7. SVS started following Preshow theater intros
  8. That's a good catch. I don't think there is a volume control for slideshows. All of the volume controls are in playbook in module volumes. I'll add slideshow controls there. Thanks for letting me know about this.
  9. @Matt - Regarding slideshows, we can't seem to figure out what commands the volume of the module. There isn't a volume setting in the module itself and there isn't a volume setting in the Playback section of the app settings. Thought maybe it was tied to Trivia, but it's not. Seems to come through at about 50% volume or something lower than 100%. If this isn't directly settable in the app, is this something we can manually "tweak" in the app folder outside of Kodi?
  10. msilas joined the community
  11. Last week
  12. potsy joined the community
  13. Hello, We’ve run into a portability issue when creating sequences in PreShow Experience on a desktop or non-media-server player. Currently, PreShow stores all media references as absolute file paths tied to the original machine. This means that if we move a PreShow project folder to another server or workstation, the sequence breaks because the media paths still point to the original device location. This creates unnecessary extra steps when deploying sequences for: Short films Theatre intros Touring productions Multi-server installations Instead of simply moving the PreShow project folder and relinking a single base directory, we have to manually update or recreate paths due to the absolute references. Requested FeatureIt would be extremely helpful if PreShow could support relative file paths for media content. For example: When setting a content directory in PreShow, the software would treat that folder as the base path. All media within the sequence would then be referenced relative to that base folder, rather than to an absolute system location. When moving the project to a new machine, we would only need to update the base content directory once. BenefitsImproved portability between systems Easier deployment to media servers Cleaner project structure Reduced setup time for touring or distributed environments Fewer broken media links This enhancement would significantly streamline workflow and reduce errors when moving projects between machines. Thank you for considering this request.
  14. Shaolin23 joined the community
  15. I am a bit lost on how to do even basic surround in Davinci Resolve. i was able to doa faux oen by duplicating the fronts to the back but if there is an AI tool out there i might do that. When i get to that point though, i may review some youtube videos on resolve. There has to be an easy way to sort of program sound.
  16. Those are Called MPAA ratings. The classic ratings version can be found here https://preshowexperience.com/files/file/94-mpaa-classic/ There's different styles you can download to fit your taste.
  17. Earlier
  18. galley0554 joined the community
  19. I was working on a customized Intro with Davinci Resolve. The mixing of the atmos sound was quite time consuming, why I lost motivation at some point. But I will give it another try and add a voice and test, if it still sounds super cheap. If not, I will maybe be motivated to continue on it
  20. David Diaz - Evercast joined the community
  21. Yea but just the simple stuff Warner Brothers and other studios intros changed to my theater name , simpler stuff like that
  22. In my first test, the system worked the way I initially intended: it grouped trivia by decade, rating, and genre, and selected content based on those matches. That part was fine and worked as expected for testing. However, once I started adding more detailed movie-specific trivia, it quickly became clear that this approach was pretty boring in practice. The system always chose the “best” match first, and because many movies have large trivia packs, it would end up playing all the trivia for a single movie before moving on to the next best match, and then the next, and so on. To fix that, I changed the behavior. In the current version, the system plays a slide from the best-matching folder, then skips that folder for a random number of slides (3–6). It then does the same with the second-best folder, and continues down the list. This creates the feel of randomness, while still giving higher priority to more relevant content. I had forgotten that I made this change until I went back and reviewed the code, which is why the behavior didn’t line up with how I described it, and wasn't what you were expecting.
  23. Currently working out a series of videos for theater intros. Using Unreal Engine. Slow going but I hope to make one for every genre. At least I have one. I customized the Regal Cinemas 1990's roller coaster to my theater. Used some AI to change some wording in the narration and Davinci resolve to edit the text on the marque scroller. Gruelling work as unreal Engine is hard to learn. Nothing is straight forward. Everything is a task. But I hope in the end it looks great. Doing an old West town for westerns. A spooky gothic castle on a hill for horror. I plan to do a parody or homage to the Disney Castle for family movies. But I really like watching the playlists on YouTube that feature simple CGI that reminds me of bowling alley animations. That is probably more easily done now with Unreal. I will probably sparingly use AI but for home theater intros it seems tempting. But AI programs seem expensive. Anyone else have customized intros?
  24. gner joined the community
  25. Wozman joined the community
  26. lynnman joined the community
  27. Owl joined the community
  28. rob_is_bored joined the community
  29. After testing more i found out that only one works at a time if it has no rating the year will work if no ratings or year the genre will work 🤔
  30. Ok after heavy testing, rating slides work flawlessly every time , But genre and year never do just random slides even tho the log shows them scoreing correctly.
  31. Subjective, yes. But here's a few "scary movies": The Conjuring 1 and 2 The Ring Insidious Presence The Exorcist Poltergeist
  32. All my movies with Atmos or DTS:X audio have "atmos" and "dtsx" in the filename respectively. PSE has always been able to pick the correct audio bumper accordingly. That's the easiest way to do it currently.
  33. omaroby replied to sea dog's topic in Support
    I setup folders by genre so basically horror themed trailers, action themed, superhero themed, etc. Then I just create sequences based off genre. At some point I hope we can add nfo files to local trailers for metadata such as genres, aspect ratio and others. That would help lower the amount of sequences I have to make.
  34. ffmpeg had the functionality, but Kodi didn't update to a version with it. I don't think it was a simple replace to update it, so it took them a while. I wouldn't change the names of your movies. I'm not going to remove the functionality for the file names, so having them named that way will guarantee that they load the appropriate bumper. There's no need for you to risk kodi losing any info for your movies by changing the name. I don't think Auro 3d will be included, just Atmos and DTS:X. I've been slowly working on new stuff for PreShow, and hope to make some huge improvements this year.
  35. Jungle with Daniel Radcliff Maybe wouldnt say it is scary but very disturbing
  36. I thought that ffmpeg used to recognize Atmos tracks one or two years ago. However, I allready wondered why my atmos bumbers are not played anymore. (Maybe I also had a few files with an atmos flag in the name). I would love it to automatically detect atmos, auro3d and dtsx tracks. Is there any news about when Kodi 22 will release? Otherwise it would be a pain to rename all my movies and I am scared that Kodi would detect them as a new file, since it is another filename than before. So I am not sure if I will update the names, but the auto-detection for audio bumpers is one of the biggest reasons why I started using PSE! (Great to hear that you are still working on PSE btw :) )
  37. marius started following Audio Format Bumpers
  38. It looks like Kodi 22 recognizes Atmos and DTS:X. I'll see what I can update when it is official.
  39. Just had a thought though. Ffmpeg may not be good at finding Atmos. Could MediaInfo be packaged in preshow and used to scan the feature to then determine which audio format it is in?
  40. So this sounds more like an issue with Kodi. I suppose the important thing is if you decided to add a tool to search for a list of movies that may be in Atmos, the problem would be in if the user re-encoded with handbrake and changed or compressed the audio tracks(s). I suppose it would be nice if the movies show the appropriate audio bumper, but how would it know how to tell the difference? It seems just using the truehd folder is a surefire way, but I would be glad to make changes (except I don't know if I want to change the filenames manually)
  41. Atmos is a subset of TrueHD. When FFMPEG analyzes the audio, it can only report TrueHD. There are 3 audio formats that can't be recognized. They are Dolby Atmos, DTS-X & Auro-3D. Right now, if you want PreShow to recognize them, you need to add atmos, dtsx, or auro3d to the filename to get them to display properly.
  42. The Haunting (1963) It probably isn't scary for everyone. Scary is subjective as you say. But the Haunting truly sets the mood, practically invented the jump scare, and the director was brilliant at creative use of shots. No blood, no monsters. Because it is the imagination that builds the scariest of all monsters. Fight me

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.