Recherche avancée

Médias (1)

Mot : - Tags -/book

Autres articles (81)

  • Ajouter des informations spécifiques aux utilisateurs et autres modifications de comportement liées aux auteurs

    12 avril 2011, par

    La manière la plus simple d’ajouter des informations aux auteurs est d’installer le plugin Inscription3. Il permet également de modifier certains comportements liés aux utilisateurs (référez-vous à sa documentation pour plus d’informations).
    Il est également possible d’ajouter des champs aux auteurs en installant les plugins champs extras 2 et Interface pour champs extras.

  • Problèmes fréquents

    10 mars 2010, par

    PHP et safe_mode activé
    Une des principales sources de problèmes relève de la configuration de PHP et notamment de l’activation du safe_mode
    La solution consiterait à soit désactiver le safe_mode soit placer le script dans un répertoire accessible par apache pour le site

  • MediaSPIP 0.1 Beta version

    25 avril 2011, par

    MediaSPIP 0.1 beta is the first version of MediaSPIP proclaimed as "usable".
    The zip file provided here only contains the sources of MediaSPIP in its standalone version.
    To get a working installation, you must manually install all-software dependencies on the server.
    If you want to use this archive for an installation in "farm mode", you will also need to proceed to other manual (...)

Sur d’autres sites (11374)

  • FFMPEG - Converting any kind of file to Mp4 compatible with IOS and Flash

    5 février 2013, par arashaga

    I am struggling with FFmpeg whithing Drupal Video Module to produce files to MP4 that is compatible with IOS and Flash Player10 and up.
    I have used the following commands so far, please note that the variables starting with " !" are placeholders and will be replaces with the proper items :

    FFmpeg -strict experimental -y -i !videofile -pass 1 -s !widthx!height -b:v 500k -threads 0 -vcodec libx264 -vf "pad=!paddingwidth:!paddingheight:!paddingleft:!paddingtop:000000" -preset slow -an !convertfile

    FFmpeg -strict experimental -y -i !videofile -pass 2 -s !widthx!height -b:v 500k -threads 0 -vcodec libx264 -vf "pad=!paddingwidth:!paddingheight:!paddingleft:!paddingtop:000000" -preset slow -acodec aac -ab 128k !convertfile

    The above command produce an error as :

    error executing command for rendering preset HTML5 MP4, command #1 :

    nice -n 19 /usr/bin/ffmpeg/ffmpeg -y -i '80137db8c3_1334836277_int_tr_19.mp4' -s 176x100 -b:v 500k -threads 0 -vcodec libx264 -preset slow -acodec aac -ab 128k '/converted/80137db8c3_1334836277_int_tr_19.mp4' 2>&1

    Output:

    ffmpeg version git-2013-02-01-5a67e30 Copyright (c) 2000-2013 the FFmpeg developers
     built on Feb  1 2013 14:23:14 with gcc 4.6 (Ubuntu/Linaro 4.6.3-1ubuntu5)
     configuration: --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3
     libavutil      52. 17.100 / 52. 17.100
     libavcodec     54. 91.100 / 54. 91.100
     libavformat    54. 61.104 / 54. 61.104
     libavdevice    54.  3.103 / 54.  3.103
     libavfilter     3. 35.100 /  3. 35.100
     libswscale      2.  2.100 /  2.  2.100
     libswresample   0. 17.102 /  0. 17.102
     libpostproc    52.  2.100 / 52.  2.100
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '80137db8c3_1334836277_int_tr_19.mp4':
     Metadata:
       major_brand     : mp42
       minor_version   : 0
       compatible_brands: isommp42
       creation_time   : 2011-03-28 00:12:26
     Duration: 00:02:01.14, start: 0.000000, bitrate: 703 kb/s
       Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 601 kb/s, 29.96 fps, 29.92 tbr, 1k tbn, 59.83 tbc
       Metadata:
         creation_time   : 1970-01-01 00:00:00
         handler_name    : VideoHandler
       Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 96 kb/s
       Metadata:
         creation_time   : 2011-03-28 00:12:27
         handler_name    : (C) 2007 Google Inc. v08.13.2007.
    [libx264 @ 0x34ec060] using SAR=100/99
    [libx264 @ 0x34ec060] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX
    [libx264 @ 0x34ec060] profile High, level 2.0
    [libx264 @ 0x34ec060] 264 - core 129 r2245 bc13772 - H.264/MPEG-4 AVC codec - Copyleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 ref=5 deblock=1:0:0 analyse=0x3:0x113 me=umh subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=50 rc=abr mbtree=1 bitrate=500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.
    Alternatively use the non experimental encoder 'libfaac'.

    Another command that I used is :

    FFmpeg -i !videofile -an -pass 1 -vcodec libx264 -preset slow -b 500k -threads auto !convertfile

    FFMpeg -y -i !videofile -acodec libfaac -ab 128k -pass 2 -vcodec libx264 -preset slow -b 500k -threads auto !convertfile

    Output for the first pass :

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'comiccon.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: mp41
       creation_time   : 2012-08-15 17:12:37
     Duration: 01:17:15.93, start: 0.000000, bitrate: 706 kb/s
       Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 636 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : VideoHandler
       Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 63 kb/s
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : SoundHandler
    Please use -b:a or -b:v, -b is ambiguous

    using SAR=1/1
    [libx264 @ 0x1c39be0] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX
    [libx264 @ 0x1c39be0] profile Main, level 3.0
    [libx264 @ 0x1c39be0] 264 - core 129 r2245 bc13772 - H.264/MPEG-4 AVC codec - Copyleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x1:0 me=dia subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=50 rc=abr mbtree=1 bitrate=500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'comiccon.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: mp41
       encoder         : Lavf54.61.104
       Stream #0:0(eng): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, pass 1, 500 kb/s, 15360 tbn, 30 tbc
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : VideoHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 -> libx264)
    Press [q] to stop, [?] for help
    frame=139078 fps=279 q=32766.0 Lsize=  286145kB time=01:17:15.86 bitrate= 505.6kbits/s    
    video:284758kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.487000%
    [libx264 @ 0x1c39be0] frame I:656   Avg QP:19.51  size: 21457
    [libx264 @ 0x1c39be0] frame P:76006 Avg QP:22.19  size:  3141
    [libx264 @ 0x1c39be0] frame B:62416 Avg QP:26.38  size:   621
    [libx264 @ 0x1c39be0] consecutive B-frames: 32.3% 17.5% 18.6% 31.6%
    [libx264 @ 0x1c39be0] mb I  I16..4: 24.5%  0.0% 75.5%
    [libx264 @ 0x1c39be0] mb P  I16..4:  7.5%  0.0%  0.0%  P16..4: 40.5%  0.0%  0.0%  0.0%  0.0%    skip:52.1%
    [libx264 @ 0x1c39be0] mb B  I16..4:  1.4%  0.0%  0.0%  B16..8: 12.0%  0.0%  0.0%  direct: 2.9%  skip:83.7%  L0:41.1% L1:41.6% BI:17.3%
    [libx264 @ 0x1c39be0] final ratefactor: 23.45
    [libx264 @ 0x1c39be0] direct mvs  spatial:95.3% temporal:4.7%
    [libx264 @ 0x1c39be0] coded y,uvDC,uvAC intra: 37.6% 42.8% 11.8% inter: 8.9% 8.2% 0.5%
    [libx264 @ 0x1c39be0] i16 v,h,dc,p: 43% 28% 19% 10%
    [libx264 @ 0x1c39be0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 36% 21% 11%  6%  4%  5%  4%  6%  6%
    [libx264 @ 0x1c39be0] i8c dc,h,v,p: 57% 19% 20%  4%
    [libx264 @ 0x1c39be0] Weighted P-Frames: Y:1.4% UV:0.5%
    [libx264 @ 0x1c39be0] kb/s:503.18

    output for the second pass :

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'comiccon.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: mp41
       creation_time   : 2012-08-15 17:12:37
     Duration: 01:17:15.93, start: 0.000000, bitrate: 706 kb/s
       Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 636 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : VideoHandler
       Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 63 kb/s
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : SoundHandler
    Please use -b:a or -b:v, -b is ambiguous
    [libx264 @ 0x3247f80] using SAR=1/1
    [libx264 @ 0x3247f80] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX
    [libx264 @ 0x3247f80] profile High, level 3.0
    [libx264 @ 0x3247f80] 264 - core 129 r2245 bc13772 - H.264/MPEG-4 AVC codec - Copyleft 2003-2013 - http://www.videolan.org/x264.html - options: cabac=1 ref=5 deblock=1:0:0 analyse=0x3:0x113 me=umh subme=8 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=50 rc=2pass mbtree=1 bitrate=500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 cplxblur=20.0 qblur=0.5 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'comiccon.mp4':
     Metadata:
       major_brand     : isom
       minor_version   : 512
       compatible_brands: mp41
       encoder         : Lavf54.61.104
       Stream #0:0(eng): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, pass 2, 500 kb/s, 15360 tbn, 30 tbc
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : VideoHandler
       Stream #0:1(eng): Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo, s16, 128 kb/s
       Metadata:
         creation_time   : 2012-08-15 17:12:37
         handler_name    : SoundHandler
    Stream mapping:
     Stream #0:0 -> #0:0 (h264 -> libx264)
     Stream #0:1 -> #0:1 (aac -> libfaac)
    Press [q] to stop, [?] for help
    frame=139078 fps=206 q=32766.0 Lsize=  357252kB time=01:17:15.93 bitrate= 631.3kbits/s    
    video:282992kB audio:69592kB subtitle:0 global headers:0kB muxing overhead 1.324238%
    [libx264 @ 0x3247f80] frame I:656   Avg QP:19.61  size: 20433
    [libx264 @ 0x3247f80] frame P:76006 Avg QP:23.07  size:  2996
    [libx264 @ 0x3247f80] frame B:62416 Avg QP:26.23  size:   780
    [libx264 @ 0x3247f80] consecutive B-frames: 32.3% 17.5% 18.6% 31.6%
    [libx264 @ 0x3247f80] mb I  I16..4: 17.2% 37.8% 44.9%
    [libx264 @ 0x3247f80] mb P  I16..4:  2.9%  3.7%  1.2%  P16..4: 30.3%  6.1%  3.4%  0.0%  0.0%    skip:52.5%
    [libx264 @ 0x3247f80] mb B  I16..4:  0.5%  0.6%  0.3%  B16..8: 25.9%  2.2%  0.5%  direct: 0.9%  skip:69.3%  L0:51.4% L1:43.0% BI: 5.7%
    [libx264 @ 0x3247f80] 8x8 transform intra:45.9% inter:51.5%
    [libx264 @ 0x3247f80] direct mvs  spatial:85.5% temporal:14.5%
    [libx264 @ 0x3247f80] coded y,uvDC,uvAC intra: 47.3% 49.2% 13.5% inter: 9.0% 9.4% 0.5%
    [libx264 @ 0x3247f80] i16 v,h,dc,p: 38% 27% 13% 22%
    [libx264 @ 0x3247f80] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 16% 14%  5%  5%  7%  7%  8%  9%
    [libx264 @ 0x3247f80] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 15%  9%  6%  7%  8%  7%  8%  8%
    [libx264 @ 0x3247f80] i8c dc,h,v,p: 49% 22% 20%  8%
    [libx264 @ 0x3247f80] Weighted P-Frames: Y:1.4% UV:0.5%
    [libx264 @ 0x3247f80] ref P L0: 79.3% 10.4%  6.8%  1.6%  1.2%  0.7%  0.0%
    [libx264 @ 0x3247f80] ref B L0: 93.6%  4.8%  1.2%  0.3%
    [libx264 @ 0x3247f80] ref B L1: 96.6%  3.4%
    [libx264 @ 0x3247f80] kb/s:500.06

    The above command produces the file correctly however it cannot be played in flash player. One thing that I noticed is this may happen if the input file is mp4 as well. This command is executed for users uploading files, so the input file could be any format.

    Below is the information about my FFmpeg version :

    ffmpeg version git-2013-02-01-5a67e30 Copyright (c) 2000-2013 the
    FFmpeg developers built on Feb 1 2013 14:23:14 with gcc 4.6
    (Ubuntu/Linaro 4.6.3-1ubuntu5) configuration : —enable-gpl
    —enable-libass —enable-libfaac —enable-libfdk-aac —enable-libmp3lame —enable-libopencore-amrnb —enable-libopencore-amrwb —enable-librtmp —enable-libtheora —enable-libvorbis —enable-libvpx —enable-libx264 —enable-nonfree —enable-version3 libavutil 52. 17.100 / 52. 17.100
    libavcodec 54. 91.100 / 54. 91.100
    libavformat 54. 61.104 / 54. 61.104
    libavdevice 54. 3.103 / 54. 3.103
    libavfilter 3. 35.100 / 3. 35.100
    libswscale 2. 2.100 / 2. 2.100
    libswresample 0. 17.102 / 0. 17.102
    libpostproc 52. 2.100 / 52. 2.1

    Thanks,

  • Anomalie #2849 (Nouveau) : table spip_document : date_publication et statut pas à jour

    9 septembre 2012, par Franck Sitbon

    Dans la table spip_document, le champ « date_publication » contient toujours « 1970-01-01 01:00:00 » et le champ « statut » sur « prepa » ou « prop » lorsqu’un contenu est publié avec une date postérieure. Le Jour J, les champs de la BDD ne changent pas, les documents ne sont donc pas (...)

  • Adding A New System To The Game Music Website

    1er août 2012, par Multimedia Mike — General

    At first, I was planning to just make a little website where users could install a Chrome browser extension and play music from old 8-bit NES games. But, like many software projects, the goal sort of ballooned. I created a website where users can easily play old video game music. It doesn’t cover too many systems yet, but I have had individual requests to add just about every system you can think of.

    The craziest part is that I know it’s possible to represent most of the systems. Eventually, it would be great to reach Chipamp parity (a combination plugin for Winamp that packages together plugins for many of these chiptunes). But there is a process to all of this. I have taken to defining a number of phases that are required to get a new system covered.

    Phase 0 informally involves marveling at the obscurity of some of the console systems for which chiptune collections have evolved. WonderSwan ? Sharp X68000 ? PC-88 ? I may be viewing this through a terribly Ameri-centric lens. I’ve at least heard of the ZX Spectrum and the Amstrad CPC even if I’ve never seen either.

    No matter. The goal is to get all their chiptunes cataloged and playable.

    Phase 1 : Finding A Player
    The first step is to find a bit of open source code that can play a particular format. If it’s a library that can handle many formats, like Game Music Emu or Audio Overload SDK, even better (probably). The specific open source license isn’t a big concern for me. I’m almost certain that some of the libraries that SaltyGME currently mixes are somehow incompatible, license-wise. I’ll worry about it when I encounter someone who A) cares, and B) is in a position to do something about it. Historical preservation comes first, and these software libraries aren’t getting any younger (I’m finding some that haven’t been touched in a decade).

    Phase 2 : Test Program
    The next phase is to create a basic test bench program that sends a music file into the library, generates a buffer of audio, and shoves it out to the speakers via PulseAudio’s simple API (people like to rip on PulseAudio, but its simple API really lives up to its name and requires pages less boilerplate code to play a few samples than ALSA).

    Phase 3 : Plug Into Web Player
    After successfully creating the test bench and understanding exactly which source files need to be built, the next phase is to hook it up to the main SaltyGME program via the ad-hoc plugin API I developed. This API requires that a player backend can, at the very least, initialize itself based on a buffer of bytes and generate audio samples into an array of 16-bit numbers. The API also provides functions for managing files with multiple tracks and toggling individual voices/channels if the library supports such a feature. Having the test bench application written beforehand usually smooths out this step.

    But really, I’m just getting started.

    Phase 4 : Collecting A Song Corpus
    Then there is the matter of staging a collection of songs for a given system. It seems like it would just be a matter of finding a large collection of songs for a given format, downloading them in bulk, and mirroring them. Honestly, that’s the easy part. People who are interested in this stuff have been lovingly curating massive collections of these songs for years (see SNESmusic.org for one of the best examples, and they also host a torrent of all their music for really quick and easy hoarding).

    In my drive to make this game music website more useful for normal people, the goal is to extract as much metadata as possible to make searching better, and to package the data so that it’s as convenient as possible for users. Whenever I seek to add a new format to the collection, this is the phase where I invariably find that I have to fundamentally modify some of the assumptions I originally made in the player.

    First, there were the NES Sound Format (NSF) files, the original format I wanted to play. These are files that have any number of songs packed into a single file. Playback libraries expose APIs to jump to individual tracks. So the player was designed around that. Game Boy GBS files also fall into this category but present a different challenge vis-à-vis metadata, addressed in the next phase.

    Then, there were the SPC files. Each SPC file is its own song and multiple SPC files are commonly bundled as RAR files. Not wanting to deal with RAR, or any format where I interacted with a general compression API to pull a few files out, I created a custom resource format (inspired by so many I have studied and documented) and compressed it with a simpler compression API. I also had to modify some of the player’s assumptions to deal with this archive format. Genesis VGMs, bundled either in .zip or .7z, followed the same model as SPC in RAR.

    Then it was suggested that I attempt to bring SaltyGME closer to feature parity with Chipamp, rather than just being a Chrome browser frontend for Game Music Emu. When I studied the Portable Sound Format (PSF), I realized it didn’t fit into the player model I already had. PSF uses a sort of shared library model for code execution and I developed another resource archive format to cope with it. So that covers quite a few formats.

    One more architecture challenge arose when I started to study one of the prevailing metadata formats, explained in the next phase.

    Phase 5 : Metadata
    Finally, for the collections to really be useful, I need to harvest that juicy metadata for search and presentation.

    I have created a series of programs and scripts to scrape metadata out of these music files and store it all in a database that drives the website and search engine. I recognize that it’s no good to have a large corpus of songs with minimal metadata and while importing bulk quantities of music, the scripts harshly reject songs that have too little metadata.

    Again, challenges abound. One of the biggest challenges I’m facing is the peculiar quasi-freeform metadata format that emerged as .m3u that takes a form similar to :

    #################################################################
    #
    # GRADIUS2
    # (c) KONAMI  by Furukawa Motoaki, IKACHAN
    #
    #################################################################
    

    nemesis2.kss::KSS,62,[Nemesis2] (Opening),2:23,,0
    nemesis2.kss::KSS,61,[Nemesis2] (Start),7,,0
    nemesis2.kss::KSS,43,[Nemesis2] (Air Battle),34,0-
    nemesis2.kss::KSS,44,[Nemesis2] (1st. BGM),51,0-
    [...]

    A lot of file formats (including Game Boy GBS mentioned earlier) store their metadata separately using this format. I have some ideas about tools I can use to help me process this data but I’m pretty sure each one will require some manual intervention.

    As alluded to in phase 4, .m3u presents another architectural challenge : Notice the second field in the CSV .m3u data. That’s a track number. A player can’t expect every track in a bundled chiptune file to be valid, nor to be in any particular order. Thus, I needed to alter the architecture once more to take this into account. However, instead of modifying the SaltyGME player, I simply extended the metadata database to include a playback order which, by default, is the same as the track order but can also accommodate this new issue. This also has the bonus of providing a facility to exclude playback of certain tracks. This comes in handy for many PSF archives which tend to include files that only provide support for other files and aren’t meant to be played on their own.

    Bright Side
    The reward for all of this effort is that the data lands in a proper database in the end. None of it goes back into the chiptune files themselves. This makes further modification easier as all of the data that is indexed and presented on the site comes from the database. Somewhere down the road, I should probably create an API for accessing this metadata.