ecourty / kodi-nfo-parser
A PHP library to parse and serialize Kodi NFO files (Movie, TvShow, Episode, Artist, Album, MusicVideo, MovieSet).
Requires
- php: >=8.3
- ext-libxml: *
- ext-simplexml: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.71
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.0
README
A framework-agnostic PHP library for parsing and serializing Kodi NFO files — the XML metadata files that Kodi stores alongside your media.
Table of Contents
Installation
composer require ecourty/kodi-nfo-parser
Requirements: PHP >= 8.3
Extensions: ext-simplexml
Quick Start
Parsing a file
use Ecourty\KodiNfoParser\NfoParser; use Ecourty\KodiNfoParser\Model\MovieNfo; $parser = new NfoParser(); $nfo = $parser->parseFile('/path/to/movie.nfo'); if ($nfo instanceof MovieNfo) { echo $nfo->title; // "Inception" echo $nfo->year; // 2010 echo $nfo->plot; // "A thief who steals..." }
Parsing a string
$nfo = $parser->parseString(file_get_contents('tvshow.nfo'));
Supported NFO Types
All 7 Kodi NFO types are supported. Each is parsed into a typed readonly model.
| NFO Type | Model | Root XML tag |
|---|---|---|
| Movie | MovieNfo |
<movie> |
| TV Show | TvShowNfo |
<tvshow> |
| Episode | EpisodeNfo |
<episodedetails> |
| Artist | ArtistNfo |
<artist> |
| Album | AlbumNfo |
<album> |
| Music Video | MusicVideoNfo |
<musicvideo> |
| Movie Set | MovieSetNfo |
<set> |
Multi-episode files
When an .nfo file contains multiple <episodedetails> blocks, the parser returns a single EpisodeNfo with all episodes accessible via $nfo->episodes:
use Ecourty\KodiNfoParser\Model\EpisodeNfo; $nfo = $parser->parseFile('s01e01e02.nfo'); if ($nfo instanceof EpisodeNfo) { foreach ($nfo->episodes as $episode) { echo $episode->title; // each episode's title echo $episode->season; // season number echo $episode->episode; // episode number } }
NFO Variants
The parser automatically detects the variant of each NFO file — no configuration needed.
| Variant | Content | Description |
|---|---|---|
| Metadata | XML only | Standard NFO with full media metadata |
| Parsing | URL only | Single-line scraper URL; Kodi fetches metadata remotely |
| Combination | XML + trailing URL | Metadata NFO with an additional scraper URL appended |
For Parsing NFOs, you can also build a model directly:
$nfo = $parser->parseParsingNfo('https://www.imdb.com/title/tt1375666/');
On Combination NFOs, the scraper URL is available on the model:
echo $nfo->scraperUrl; // "https://www.imdb.com/title/tt1375666/"
Serialization
Any model can be serialized back to a valid NFO XML string using NfoSerializer:
use Ecourty\KodiNfoParser\NfoSerializer; use Ecourty\KodiNfoParser\Model\MovieNfo; $serializer = new NfoSerializer(); $movie = new MovieNfo( title: 'Inception', year: 2010, plot: 'A thief who steals corporate secrets...', ); $xml = $serializer->serialize($movie); file_put_contents('movie.nfo', $xml);
Error Handling
All exceptions extend Ecourty\KodiNfoParser\Exception\NfoException.
| Exception | When thrown |
|---|---|
NfoFileNotFoundException |
The file does not exist or is not readable |
NfoFileReadException |
The file could not be read |
InvalidNfoException |
The content is not valid NFO XML |
UnknownNfoTypeException |
The root XML tag is not a known Kodi NFO type |
use Ecourty\KodiNfoParser\Exception\NfoException; use Ecourty\KodiNfoParser\Exception\NfoFileNotFoundException; try { $nfo = $parser->parseFile('/path/to/file.nfo'); } catch (NfoFileNotFoundException $e) { // file missing } catch (NfoException $e) { // any other NFO-related error }
Development
# Install dependencies composer install # Run tests composer test # Run PHPStan (level max) composer phpstan # Run CS fixer composer cs-fix