{"id":15007320,"url":"https://github.com/sen-h/vidos","last_synced_at":"2025-10-03T14:31:38.520Z","repository":{"id":123369792,"uuid":"323216369","full_name":"sen-h/VidOS","owner":"sen-h","description":"Complete single purpose linux system that just plays videos","archived":true,"fork":false,"pushed_at":"2024-03-04T04:37:27.000Z","size":3010,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"dev","last_synced_at":"2024-09-29T15:04:34.503Z","etag":null,"topics":["av1","av1-videos","buildroot","dav1d","kernel","linux","linux-distribution","mkv","opus","video","webm"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sen-h.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"contributing.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-21T03:03:32.000Z","updated_at":"2024-03-04T04:40:36.000Z","dependencies_parsed_at":"2024-03-04T05:44:02.684Z","dependency_job_id":null,"html_url":"https://github.com/sen-h/VidOS","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sen-h%2FVidOS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sen-h%2FVidOS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sen-h%2FVidOS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sen-h%2FVidOS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sen-h","download_url":"https://codeload.github.com/sen-h/VidOS/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235146479,"owners_count":18943265,"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":["av1","av1-videos","buildroot","dav1d","kernel","linux","linux-distribution","mkv","opus","video","webm"],"created_at":"2024-09-24T19:08:24.686Z","updated_at":"2025-10-03T14:31:38.083Z","avatar_url":"https://github.com/sen-h.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WARNING: this project is no longer being developed on github, please head on over to codeberg: https://codeberg.org/sen-h/VidOS\n\n# VidOS\n\nComplete single purpose linux system for x86-64 that just plays videos.\nMore precisely it is a bunch of pre-built components and a utility to assemble those components\ninto little linux distros that just boot and play your specified videos.\nNo compiling required!\n\n# Why?\n\nWell, here are some possible use cases:\n\n* Digital Signage(think Video Ads in malls, Airport Terminal displays, menu boards in restaurants etc.)\n* Education (Museum exhibits, art galleries, expo booths)\n\nBut honestly why not?\nPrior startup experience has left me with a bit of an obsession with minimal linux systems and video codecs.\nAlso, it occurs to me that  *perceptually good* FHD AV1 video is approximately the same bit rate as 1x CD speed (1.4 Mb/s).\nOne could (and I have) \"stream\" a 1080P video off of a CD. \n\nAlso, I learned after working on this project for a over a year that this isn't an original idea (go figure): [Movix](http://movix.sourceforge.net/Docs/eMoviX/countries/en/main.html)\n\nMovix/eMovix appears to have been abandoned mid 2006, yet there still exists a plugin for it inside of [k3b](https://apps.kde.org/k3b/).\n\nAn eventual goal is to upstream this project into k3b as an official plugin.\n\n# Theory of operation\n\nA minimal linux system is built with alsa-lib, libdrm, mpv etc..\nThe entire root fileystem is then lz4 compressed and linked into the kernel binary.\nUpon bootup, an init script initializes audio stuff, loads the video(s) \nloads binary blob graphics drivers (if applicable) \nand then runs mpv with the drm option to output directly to a framebuffer. \nAfter the video(s) ends poweroff is called and the device shuts down.\n\n# Supported video formats per Kernel Package\n\nKernel Package\t|Video Container(s)\t\t\t    |Supported video codec(s)|Supported audio codec\t|\n|---\t\t|--\t\t\t\t\t    |---\t\t\t|---\t\t\t|\n|vidos_avc\t|matroska (.mkv) \u003cbr\u003e MPEG-4 part 10 (.mp4) | AVC/H.264\t\t\t| AAC-LC\t\t|\n|vidos_av1\t|matroska (.mkv) \u003cbr\u003e MPEG-4 part 10 (.mp4) \u003cbr\u003e webm (.webm) | AV1\t| opus\t\t\t|\n|vidos_webm\t|matroska (.mkv) \u003cbr\u003e MPEG-4 part 10 (.mp4) \u003cbr\u003e webm (.webm) | vp8/vp9 | opus\t\t\t|\n\n# Getting Started\n\nTo buld a VidOS distro, simply run the VidOS build utility (vobu.sh):\n\n`./vobu.sh -v funnycatvideo.mkv`\n\nwhere `-v` is the path/filename of a video, or a directory/folder full of videos\n\nthis will build an iso you can burn to an optical disk or block device(thumb drive)\n\nyou can use something like [etcher](https://etcher.balena.io/) or dd (if you are careful!)\n\n`dd if=vidos_funnycatvideo_av1_none_ram_20xx-xx-xx.iso of=/dev/sdX bs=4M \u0026\u0026 sync`\n\nor test it out in qemu:\n\n`qemu-system-x86_64 -cpu host --enable-kvm -m 500 -soundhw ac97 -vga cirrus vidos_funnycatvideo_av1_none_ram_20xx-xx-xx.iso`\n\n\nvobu.sh also supports a ton more options outlined below\n``` \nVidOS build utility v1.4.x\nusage: vobu -d [directory] -v [filename/dirname] -b [build style] -g [graphics drivers] -f [format] -r [remove codecs] -l [bootloader/manager]\n-m [mpv options] -p [playback options] -o [output iso name]\noptions:\n-h help -- print this help text\n-d directory -- path to vidos components dir, Default paths: /tmp, /opt, ./\n-v video filename or directory -- path to video file or directory of video files, supported video codecs: [ av1 vp8 vp9 h264 ]\n-b build style -- style of output build, one of: [ disk ram hybrid ] Default: ram\n-g graphics drivers -- binary blob graphics drivers, one or multiple of: [ amdgpu radeon i915 none all ] Default: none\n-f format  -- specific video format to use, if omitted one will be autodetected. one of: [ av1 webm avc ]\n-r remove external codecs -- removes/disables OpenH264 and fdk-aac codecs, OpenH264 Video Codec provided by Cisco Systems, Inc.\n-l bootloader/manager for firmware -- select bootloader depending on machine firmware. one of: [ efi bios both ] Default: bios\n-m mpv options -- extra options to pass to mpv, see: https://mpv.io/manual/stable/#options\n-p playback count -- how many times to play the video or video files: [ -1 to inf ] Default: 1\n-o output iso name -- specify a name for the output iso, Defaults to: 'vidos_$VIDEO_$FORMAT_$GRAPHICS_DRIVERS_$BUILD_STYLE_$BOOTLOADER_YYYY-MM-DD.iso'\n```\n## `-h` *help* -- print this help text\n\nprints help text\n\n## `-d` *directory* -- path to vidos components dir\n\nAn explicit path to the vidos_components directory.\n\nIf unspecified vobu will try to use its working copy in /tmp\nbut if it can't find that, it will look for a copy it can move into /tmp.\n\nFirst it checks /opt, and then it searches the current directory.\n\nIf it still can't find a copy, the path\nto one must be specified with -d \"path/to/vidos_components\"\n\nIt will then copy that into /tmp where it can be used.\n\nBecause of this, subsequent runs of vobu will not need the\nvidos_components dir specified,\nat least until the copy in /tmp gets deleted :P\n\nIt should also be noted that specifiying a path will\nalways install a new copy in /tmp, which will of\ncourse replace the old copy (if one exists).\n\nThis is useful when debugging/developing to ensure you are\nalways working with a fresh copy.\n\n## `-v` *filename* or *directory* -- path to video file or directory of video files\n\nprovide a path to a video file like so:\n\n`./vobu.sh -v myvid.mkv`\n\nor mulitple video files like this:\n\n`./vobu.sh -v myvid.mkv -v catvid.mkv -v dogvid.mkv etc...`\n\nor a directory (and its subdirectories) full of video files like this:\n\n`./vobu.sh -v all_the_cute_animals/`\n\nif -f is not specified, vobu finds the first video with a format it supports,\nand then only finds videos with that same format.\n\nfor example on multi filename arguments:\n\n`./vobu.sh -v h264vid.mp4 -v av1vid.mkv -v differenth264vid.mp4 -v webmvid.webm`\n\nbecause an H.264(AVC) encoded video was found first\n(because it was specified first) the built distro will only contain h264vid.mp4\nand differenth264vid.mp4\n\nif you call -v on a directory like so:\n\n`./vobu.sh -v all_the_cool_vids/`\n\nvobu uses [find](https://linux.die.net/man/1/find) to crawl through all of its sub directories using the same rules\n\nso if all_the_cool_vids/ looked like this:\n```\nall_the_cool_vids/\n├── sweet_skateboarding\n│   └── cool_curbgrinds.mp4\n├── rad_rimshots.webm\n├── sick_kickflips.mkv\n├── dope_dirtbikes.mkv\n```\nvobu will find dope_dirtbikes.mkv first \neven though it comes after cool_curbgrinds.mp4 because it is in the root dir.\nand because dope_dirtbikes.mkv is encoded in av1, vobu next finds\nsick_kickflips.mkv which is also encoded in av1, but ignores rad_rimshots.webm.\n\nto get around this use -f to explicitly set the mandatory format/codec:\n\n`./vobu.sh -v all_the_cool_vids/ -f avc`\n\nvobu will only find cool_curbgrinds.mp4\n\nor:\n\n`./vobu.sh -v all_the_cool_vids/ -f webm`\n\nvobu will only find rad_rimshots.webm\n\n## `-b` *build style* -- where/how the video(s) are stored.\n\nthe style of build vidos will output, different styles mean different\nbehaviours for where the videos are stored in the final image.\nconsequently this affects the time between powering the device on and video playback.\n\n### `ram`\n\nvideos are stored in the initramfs, this means as soon as the kernel \nmounts the initramfs the video is available and playback can start.\nyou are only reading from the disk once at the beginning when isolinux pulls \nthe kernel (bzImage) and the initramfs (rootfs.cpio.lz4) into ram. \n\nthis is a good option for a few short, small videos. \nas more video = bigger initramfs = longer initramfs load time = longer time before playback starts.\n\npast a certain point, mounting and reading from a disk\nafter boot is probably faster (depending on setup) than the time it takes to load \na really big initramfs (rootfs.cpio.lz4) at boot.\n\n### `disk`\n\nVideos are stored in a directory on disk (boot media).\nThis means you can store lots of big video files but you have to wait until the disk is mounted\nbefore you can start playback.\n\n### `hybrid`\n\nThis is sort of a mixture of the previous 2 options, but with a twist.\n\nThe first video in the playlist is split into 10 second chunks, and the\nfirst chunk is stored in the initramfs, but the rest are stored on disk.\n\nThis means that the first video can start playing as soon as the kernel and initramfs is\nloaded, (just like the ram option) but it can be a really big file because the\nrest of it is being read from disk, not ram.\n\nall subsequent videos are stored on disk.\n\nThis is an attempt to be the \"best of both worlds\" approach, but a practical\nspeed difference between this and the ram option is highly dependent on setup\n(boot media, usb host speed, processor speed etc..)\nI came up with this method after learning that USB devices are detected\nasyncronosly and as such don't block the boot process and can appear at any\ntime. This was an attempt to get around that, and yield the fastest power\nbutton to image on glass time.\nThe idea being you start playing the video asap and by the time you have finshed\nthe first chunk the disk has been mounted and the remaining chunks are\navailable.\nYMMV.\n\n## `-g` *firmware* -- graphics drivers\n\nthis selects linux-firmware binary graphics driver directory to package in the initramfs.\n\nyour choice will affect the final size of the initramfs and as such the total boot time.\n\n### `amdgpu` \nfor amd gpus\n\n### `radeon` \nfor radeon or some older amd gpus\n\n### `i915` \nfor some intel gpus\n\n### `none`\ndoesn't install any drivers \n\n### `all`\ninstalls all of them (`amdgpu`, `radeon` and `i915`)\n\n## `-f` *format*\n\nThis selects the video codec and corresponding format so that \nvobu can select a kernel package to build your distro around.\n\nIt's autoselected by vobu by default but can be overridden by calling this option.\n\nthis could come in handy if you had a whole folder full of videos in different formats,\nand you wanted to make sure you grabbed a specific type.\n\n### `avc`\n\nselects videos in AVC format ( H.264/AVC video and AAC audio in an mp4 or matroska container)\n\n### `av1`\n\nselects videos in AV1 format ( AV1 video and Opus audio in an mp4, webm or matroska container)\n\n### `webm`\n\nselects videos in WEBM format (VP8 or VP9 video and Opus audio in an mp4, webm or matroska container)\n\n## `-r` *remove external codecs*\n\nremoves/disables OpenH264 and fdk-aac codecs, this is required for licencing reasons.\n\n## `-l` *bootloader/manager for firmware*\n\nselects bootloader/boot manager the install in the final image, this is dependent on what type of firmware\n(colloqiually referred to as \"The BIOS\") is on the target machine.\n\n### `bios`\n\ninstalls isolinux and kernel package + initramfs on the disk for machines with traditional bios type firmware,\nimages can be burnt to optical media or block devices.\n\n### `efi`\n\ninstalls systemd-boot and kernel package + initramfs in an ESP on the disk for machines with efi compliant firmware,\nimages can be burnt to optical media or block devices.\n\nSecure boot is not supported and MUST be disabled.\n\n### `both`\n\ninstalls isolinux and kernel package + initramfs on the disk and also installs systemd-boot and kernel package + initramfs in an ESP.\n\nbecause the same stuff is duplicated in two places, the resulting final image will be bigger, sometimes by 2X.\n\nfor instance, given an image built with the `ram` style and a 10MB video + 20MB kernel package, the final image will be 60MB.\n\nhowever, for an image built with `disk` style the video is not packed in the initramfs so it's not duplicated.\ntherefore the final image will be 50MB ((20MB kernel package)*2 + 10MB video)\n\nIt should however (theoretically at least) run on any pc regardless of the firmware implementation.\n\n## `-m` *mpv options* -- extra options for mpv\n\npasses additional options to mpv, see the mpv docs for info: https://mpv.io/manual/stable/#options\n\nIt should be noted that all options specfied here are appended to the mpv arguments in the particular S03Video* script\n\nso for something like:\n\n`vobu.sh -v all_the_cool_vids/ -m --shuffle`\n\nthe line in the S03Video script would be:\n\n`mpv -vo=drm --playlist=/path/to/playlist.txt --shuffle`\n\n## `-p` *playback count*\n\nthis is *essentially* a macro for the `-m` option, it appends the `--loop-playlist` option with the passed value, defaulting to `1`\n\nthis is done after what (if any) options were passed with `-m`\n\nSo for something like:\n\n`vobu.sh -v all_the_cool_vids/ -p 1 -m --shuffle`\n\nor\n\n`vobu.sh -v all_the_cool_vids/ -m --shuffle`\n\nthe line in the S03Video script would be:\n\n`mpv -vo=drm --playlist=/path/to/playlist.txt --shuffle --loop-playlist=1`\n\n## `-o` *output iso name*\n\nspecify the output filename/path, the `.iso` suffix is automagically appended\n\n# Bootloader\n\nisolinux is being used for machines with traditional \"bios\" firmware,\nand systemd-boot is used for machines with efi compliant firmware.\n\nwhile the kernel images are built with the efi stub and as such could be executed\ndirectly by the efi firmware without a second stage,\nsystemd-boot is needed in order to load the external initramfs from the ESP.\n\n# Kernel\n\nThe kernel and its linked-in initramfs are built with absolute minimum support for everything required. \n\n# File System \n\nThere is a standard unixy file system in the initramfs that's linked into the kernel.(bzImage)\nThe second initramfs(rootfs.cpio.lz4), which lives on disk, \ncontains a few folders that are overlayed onto the first initramfs. \nWhat's inside of the second initramfs is determined by the `-g`, `-v` and `-b` options\nThe third filesystem is the iso9660 file system(disk) that constitiutes the boot media.\nAlong with containing the kernel package and second initramfs, it may also contain videos depending on the `-b` option.\n\n# building VidOS components from source\n\n `./build.sh` *video format*\n\nThis will download buildroot and do some various setup functions as well as building the \nrelevent kernal packages and a test image.\n\nyou can then run 'build_release.sh' to bundle all of the releases into one directory\n\nafterwords cd into the release dir and run vobu as usual:\n\n`./vobu.sh -v funnycatvideo.mkv`\n\nyou can then dd that to a thumb drive or optical disk:\n\n`dd if=/path/to/buildroot/output/images/output.iso of=/dev/sdX bs=4M \u0026\u0026 sync`\n\nVidOS ships with test videos made with ffmpeg:\n### AV1\n`ffmpeg -f lavfi -i \"testsrc=d=10:s=1920x1080:r=30\" -filter_complex drawtext='fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:fontcolor=white:fontsize=140:text='AV1'' -f lavfi -i sine=f=300:b=2:d=10 -ac 2 -c:a libopus -c:v libsvtav1 -pix_fmt yuv420p av1_video.mkv`\n\n### WEBM\n`ffmpeg -f lavfi -i \"testsrc=d=10:s=1920x1080:r=30\" -filter_complex drawtext='fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:fontcolor=white:fontsize=140:text='WEBM'' -f lavfi -i sine=f=300:b=2:d=10 -ac 2 -c:a libopus -c:v libvpx-vp9 -pix_fmt yuv420p webm_video.webm`\n\n### AVC\n`ffmpeg -f lavfi -i \"testsrc=d=10:s=1920x1080:r=30\" -filter_complex drawtext='fontfile=/usr/share/fonts/truetype/freefont/FreeSans.ttf:fontcolor=white:fontsize=140:text='AVC'' -f lavfi -i sine=f=300:b=2:d=10 -ac 2 -c:a libfdk_aac -c:v libopenh264 -pix_fmt yuv420p avc_video.mp4`\n\nCheers!\n\n# Testing/development\n\n~~Develpment is done on a Wyse Rx0L thin client over its serial port.~~\n~~This negates the need for HID and virtio drivers.~~\nNew _virt kernel config has Cirrus vga support, and works pretty well thru qemu.\nsomething like:\n\n`qemu-system-x86_64 -cpu host --enable-kvm -m 500 -soundhw ac97 -vga cirrus -cdrom path/to/iso.iso`\n\nworks pretty well.\n\nIn general, the approach is to keep things as simple and minimal as possible.\nThis is to avoid an excessive kernel size and prevent it from being used for nefarious purposes.\n\n~~Eventually I will kick myself hard enough to get a proper PXE server running, instead of imaging thumb drives.~~ *got this working a while ago actually*\n\n# Notes\n# To do\n\n~~* make isolinux quieter (or silent)~~ *implemented with optional patch*\n\n~~* figure out efi bootstub stuff~~ *done*\n\n~~* more codec support~~ *supports the 3 major web codecs*\n\n~~* support for a playlist of mulitple videos instead of just one~~ *implemented*\n\n~~* looping video support~~ *done*\n\n* support ARM64/rpi4 *in process*\n\n* more hw platform support\n\n# Licence \n\nThis work is licenced under 0BSD\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsen-h%2Fvidos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsen-h%2Fvidos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsen-h%2Fvidos/lists"}