{"id":22242746,"url":"https://github.com/tiben/m3uragen","last_synced_at":"2025-06-11T16:33:28.599Z","repository":{"id":57438931,"uuid":"294406948","full_name":"TiBeN/m3uragen","owner":"TiBeN","description":"Generate RetroArch M3U playlists from multi images software romsets","archived":false,"fork":false,"pushed_at":"2021-11-13T15:10:37.000Z","size":60,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-02T18:11:16.328Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TiBeN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-10T12:44:40.000Z","updated_at":"2023-07-25T00:34:05.000Z","dependencies_parsed_at":"2022-09-11T14:11:22.349Z","dependency_job_id":null,"html_url":"https://github.com/TiBeN/m3uragen","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/TiBeN/m3uragen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TiBeN%2Fm3uragen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TiBeN%2Fm3uragen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TiBeN%2Fm3uragen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TiBeN%2Fm3uragen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TiBeN","download_url":"https://codeload.github.com/TiBeN/m3uragen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TiBeN%2Fm3uragen/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259297922,"owners_count":22836435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-03T04:16:56.893Z","updated_at":"2025-06-11T16:33:28.543Z","avatar_url":"https://github.com/TiBeN.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"m3uragen\n========\n\nm3uragen generates M3U playlists from multi images software romsets for use\nwith RetroArch.\n\nOverview\n--------\n\nThe RetroArch emulators frontend supports multi images software (discs,\nfloppies etc.) using [M3U playlist\nfiles](http://docs.retroachievements.org/Multi-Disc-Games-Tutorial/).  M3U\nfiles have to be created manually, which can be a tedious and boring task with big\nimage romsets (TOSEC, no-intro etc.). This tool scans your romset directories and\ncreate theses files automatically into a directory of your choice. \n\nIt supports two kinds of romsets:\n\n-   Zipped romsets\n\n    In theses sets, each software has its own zip archive containing the images\n    of the software. Because M3U files must contains path to unzipped images,\n    m3uragen processes theses romsets in two steps: first it unzip the archives\n    into a directory of your choice, then it creates M3U files containing paths pointing \n    to the unzipped images.\n\n-   Unzipped romsets\n\n    In theses sets, images files are stored as is in the directory (or into\n    subdirectories). m3uragen processes theses romsets by scanning the \n    directory (optionnally recursively) and gathering image sets of the same software\n    then creates a M3U file for each set having more than one image. In order to proceed, \n    m3uragen must be provided with a [regular expression](https://en.wikipedia.org/wiki/Regular_expression) \n    which determines the \"media flag\" part of the image file name. \n    Common rom collections (TOSEC, no-intro) \n    use [standard naming schemes](https://www.tosecdev.org/tosec-naming-convention) to\n    name the images files, which contain \"media flags\" for multi images\n    softwares among other things. For example TOSEC use something like: \n\n    'Some Game **(Disk 1 of 2)**.img'.\n\nInstallation\n------------\n\n### Using pip\n\nTo install using pip type:\n\n    $ pip install m3uragen\n\n### From the repo\n\nClone this repository, 'cd' into then launch using:\n\n    $ ./bin/m3uragen \u003cargs\u003e\n\nUsage\n-----\n\n    $ m3uragen [-h] [-v] [-d] [-r] [-s SUFFIX] (-m MEDIA_FLAG_PATTERN | -z UNZIP_IMAGES) [-e IMAGE_EXTENSIONS] [-S MOVE_SINGLE] [-M MOVE_MULTI]\n               [-f FILTER_PATTERN]\n               romset_dir m3u_dir\n\n    positional arguments:\n      romset_dir            Romset directory\n      m3u_dir               M3U output directory\n    \n    optional arguments:\n      -h, --help            show this help message and exit\n      -v, --verbose         increase output verbosity\n      -d, --dry-run         execute in dry mode (don't write anything)\n      -r, --recursive       scan romset dir recursivelly\n      -s SUFFIX, --suffix SUFFIX\n                            Add a suffix to M3U file names\n      -m MEDIA_FLAG_PATTERN, --media-flag-pattern MEDIA_FLAG_PATTERN\n                            regex used to extract media flags from image file name\n      -z UNZIP_IMAGES, --unzip-images UNZIP_IMAGES\n                            output directory where archives are unzipped\n      -e IMAGE_EXTENSIONS, --image-extensions IMAGE_EXTENSIONS\n                            filter images by extension (available only with -m)\n      -S MOVE_SINGLE, --move-single MOVE_SINGLE\n                            move software single images to this dir\n      -M MOVE_MULTI, --move-multi MOVE_MULTI\n                            move software multi images to this dir\n      -f FILTER_PATTERN, --filter-pattern FILTER_PATTERN\n                            filter out images that matches this regex (available only with -m)\n\nExamples\n--------\n\n### Handle a zipped collection\n\nSuppose you have a romset of zipped C64 floppy games.\n\nThe romset is organised like this into the dir '/c64-set'\n\n    $ ls /c64-set\n\n    [..]\n    'Zeppelin Rescue (USA, Europe) (v1.3).zip'\n    'Zeppelin (USA, Europe).zip'\n    'Zig Zag (USA, Europe).zip'\n    'Zoids (USA, Europe).zip'\n    'Zone Ranger (USA, Europe).zip'\n    'Zoom! (USA).zip'\n    'Zork II - The Wizard of Frobozz (USA, Europe) (R22).zip'\n    'Zork I - The Great Underground Empire (USA, Europe) (R52) (C128).zip'\n    'Zorro (USA, Europe).zip'\n    'Z-Pilot (Europe).zip'\n    'Z-Pilot (USA).zip'\n    'Zyron (Europe).zip'\n    [..]\n\nBecause the images are zipped into archives, theses archives have to be unzipped before.\nWe want unzipped images to go to '/c64-dsk' and generated m3u files to '/c64-m3u'.\nThis is done by executing:\n\n    $ m3uragen -v /c64-set /c64-m3u -z /c64-dsk\n\nM3U files are named after the name of the zip archives:\n\n    $ ls /c64-m3u\n\n    [..]\n    'World'\\''s Greatest Football Game (USA, Europe).m3u'\n    'World Tour Golf (USA, Europe).m3u'\n    'WWF WrestleMania (Europe).m3u'\n    'X-Men - Madness in Murderworld (USA, Europe) (Alt 1).m3u'\n    'X-Men - Madness in Murderworld (USA, Europe).m3u'\n    'X-Out (Europe) (Alt 1).m3u'\n    'X-Out (Europe).m3u'\n    'Zak McKracken and the Alien Mindbenders (Germany).m3u'\n    'Zork I - The Great Underground Empire (USA, Europe) (R52) (C128).m3u'\n    [..]\n\nPaths to the images files inside M3U files are relatives to the M3U files.\n\n### Handle an unzipped collection\n\nSuppose you have some Atari ST floppy images named after the TOSEC naming conventions:\n\n    $ ls /st-flop\n\n    [..]\n    Battleships (1987)(Elite)[!].stx\n    Berlin 1948 (1989)(Time Warp)(Disk 1 of 2).stx\n    Berlin 1948 (1989)(Time Warp)(Disk 2 of 2).stx\n    Bermuda Project (1987)(Mirrorsoft)(Disk 1 of 2).stx\n    Bermuda Project (1987)(Mirrorsoft)(Disk 2 of 2).stx\n    Better Dead Than Alien! (1987)(Electra).stx\n    Beverly Hills Cop (1990)(Paramount Pictures)(Disk 1 of 2).stx\n    Beverly Hills Cop (1990)(Paramount Pictures)(Disk 2 of 2).stx\n    [..]\n\nFor multi-images software, the image files names contain a media flag that follows\nthis pattern: '(Disk n of n)'. This pattern can be expressed with the following\nregular expression: `\\(Disk \\d+ of \\d+\\)`.\nM3U files of this collection can be generated into '/st-m3u' using:\n\n    $ m3uragen -v /st-flop /st-m3u -m '\\(Disk \\d+ of \\d+\\)'\n\nM3U files are named after the images filenames minus the media flag part:\n\n    $ ls /st-m3u\n\n    [..]\n    Berlin 1948 (1989)(Time Warp).m3u\n    Bermuda Project (1987)(Mirrorsoft).m3u\n    Beverly Hills Cop (1990)(Paramount Pictures).m3u\n    [..]\n\nThe regular expression can be tested again the romset without writing anything by \ncombining verbose mode and dry run mode:\n\n    $ m3uragen -v -d /st-flop /st-m3u -m '\\(Disk \\d+ of \\d+\\)'\n\nThis will output M3U files that would be generated without really create them.\n\nIf the romset directory is organised into subdirs e.g.:\n\n    ├── Berlin 1948 (1989)(Time Warp)(Disk 1 of 2)\n    │   └── Berlin 1948 (1989)(Time Warp)(Disk 1 of 2).stx\n    ├── Berlin 1948 (1989)(Time Warp)(Disk 2 of 2)\n    │   └── Berlin 1948 (1989)(Time Warp)(Disk 2 of 2).stx\n    ├── Bermuda Project (1987)(Mirrorsoft)(Disk 1 of 2)\n    │   └── Bermuda Project (1987)(Mirrorsoft)(Disk 1 of 2).stx\n    ├── Bermuda Project (1987)(Mirrorsoft)(Disk 2 of 2)\n    │   └── Bermuda Project (1987)(Mirrorsoft)(Disk 2 of 2).stx\n    ├── Better Dead Than Alien! (1987)(Electra)\n    │   └── Better Dead Than Alien! (1987)(Electra).stx\n    ├── Beverly Hills Cop (1990)(Paramount)(Disk 1 of 2)\n    │   └── Beverly Hills Cop (1990)(Paramount)(Disk 1 of 2).stx\n    ├── Beverly Hills Cop (1990)(Paramount)(Disk 2 of 2)\n    │   └── Beverly Hills Cop (1990)(Paramount)(Disk 2 of 2).stx\n\nSimply tell m3uragen to scan the directory recursively using '-r':\n\n    $ m3uragen -v -r /st-flop /st-m3u -m '\\(Disk \\d+ of \\d+\\)'\n\n### A more complex example: gamebasecpc romset\n\nThis Amstrad CPC romset is more challenging as it mixes many images formats\n(cdt and dsk), presents a more complex media flag naming scheme and is\norganized into subdirs:\n\n    \n    ├── A\n    │   ├── Academy - Tau Ceti II (E) - Side A.cdt\n    │   ├── Academy - Tau Ceti II (E) - Side A - EACH SIDE A IS DUPLICATED ON SIDE B.cdt\n    │   ├── Academy - Tau Ceti II (E) - Side B.cdt\n    │   ├── Academy - Tau Ceti II (E) - Side B - EACH SIDE A IS DUPLICATED ON SIDE B.cdt\n    │   ├── Academy - Tau Ceti II (F).dsk\n        [..]\n    │   ├── Aventuriers (F), Les - Disk 1A.cdt\n    │   ├── Aventuriers (F), Les - Disk 1A.dsk\n    │   ├── Aventuriers (F), Les - Disk 1B.cdt\n    │   ├── Aventuriers (F), Les - Disk 1B.dsk\n    │   ├── Aventuriers (F), Les - Disk 2A.cdt\n    │   ├── Aventuriers (F), Les - Disk 2A.dsk\n    │   ├── Aventuriers (F), Les - Disk 2B.cdt\n    │   ├── Aventuriers (F), Les - Disk 2B.dsk\n    │   ├── Aventuriers (F), Les - Side 1A.cdt\n    │   ├── Aventuriers (F), Les - Side 1B.cdt\n    │   ├── Aventuriers (F), Les - Side 2A.cdt\n    │   ├── Aventuriers (F), Les - Side 2B.cdt\n        [..]\n    ├── B\n    │   ├── Baba's Palace (E).cdt\n    │   ├── Baba's Palace (E).dsk\n    │   ├── Baby Jo (E) - Disk 1A.dsk\n    │   ├── Baby Jo (E) - Disk 1B.dsk\n    │   ├── Backgammon (E).cdt\n        [..]\n\nGenerating M3U files for this collection can be handled in two passes, one per image format.\nThe media flag pattern is the following: ` - (Disk|Side) [A-Z0-9]+[^.]*`.\nEach pass is filtered by file extension using `-i \u003cextension\u003e`. In order to prevent clash\nin M3U filenames between formats, a flag containing the image format will be added at \nthe end of the M3U filename, using `-s \u003csuffix\u003e`: \n\n    $ m3uragen -v /romset /romset-m3u -m ' - (Disk|Side) [A-Z0-9]+[^.]*' -r -s ' (cdt)' -e cdt\n    $ m3uragen -v /romset /romset-m3u -m ' - (Disk|Side) [A-Z0-9]+[^.]*' -r -s ' (dsk)' -e dsk\n    \n    $ ls /romset-m3u\n\n    [..]\n    Academy - Tau Ceti II (E) (cdt).m3u\n    Aventuriers (F), Les (cdt).m3u\n    Aventuriers (F), Les (dsk).m3u\n    Baby Jo (E) (dsk).m3u\n    [..]\n \n### Reorganize images\n\nTwo options are available to move image files from the romset directory to others\ndirectories:\n\n-   `-S \u003cdir\u003e`: Move single image software files to this dir\n-   `-M \u003cdir\u003e`: Move multi images software files to this dir\n\nThis allows to make importing images into RetroArch playlists easier by\nimporting single image software files dir and m3u dir per emulated machine for\nexample.\n\n### Filter out images files\n\nImages files can be filtered out by providing regular expression to the filter option:\n\n    -f \u003cregex\u003e\n\nThis can be useful to exclude images flagged as `alternate` or `bad dump` in a\nTOSEC collection for example. The following pattern excludes all images flagged\n'a, b, cr, m, o, u, p, h and t):\n\n    -f '\\[(a|b|cr|m|o|u|p|h|t)[0-9]{,2}( [^]]+)?\\]'\n\nThe -f option can be used many times in a command.\n\n### Handling TOSEC romsets\n\nThe Atari ST TOSEC romset example given above is deliberately simple for\ntutorial purposes but does handle exhaustively TOSEC romsets. The following\npattern is more complex but handle almost all cases:\n\n    -m '\\((Disc|Disk|File|Part|Side|Tape) [^()]+\\)(\\(.+\\))?(\\[.+\\])?' \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiben%2Fm3uragen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftiben%2Fm3uragen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiben%2Fm3uragen/lists"}